123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- import { isBigint, isDate, isInfinite, isMap, isNaNValue, isRegExp, isSet, isUndefined, isSymbol, isArray, isError, isTypedArray, isURL, } from './is.js';
- import { findArr } from './util.js';
- function simpleTransformation(isApplicable, annotation, transform, untransform) {
- return {
- isApplicable,
- annotation,
- transform,
- untransform,
- };
- }
- const simpleRules = [
- simpleTransformation(isUndefined, 'undefined', () => null, () => undefined),
- simpleTransformation(isBigint, 'bigint', v => v.toString(), v => {
- if (typeof BigInt !== 'undefined') {
- return BigInt(v);
- }
- console.error('Please add a BigInt polyfill.');
- return v;
- }),
- simpleTransformation(isDate, 'Date', v => v.toISOString(), v => new Date(v)),
- simpleTransformation(isError, 'Error', (v, superJson) => {
- const baseError = {
- name: v.name,
- message: v.message,
- };
- superJson.allowedErrorProps.forEach(prop => {
- baseError[prop] = v[prop];
- });
- return baseError;
- }, (v, superJson) => {
- const e = new Error(v.message);
- e.name = v.name;
- e.stack = v.stack;
- superJson.allowedErrorProps.forEach(prop => {
- e[prop] = v[prop];
- });
- return e;
- }),
- simpleTransformation(isRegExp, 'regexp', v => '' + v, regex => {
- const body = regex.slice(1, regex.lastIndexOf('/'));
- const flags = regex.slice(regex.lastIndexOf('/') + 1);
- return new RegExp(body, flags);
- }),
- simpleTransformation(isSet, 'set',
- // (sets only exist in es6+)
- // eslint-disable-next-line es5/no-es6-methods
- v => [...v.values()], v => new Set(v)),
- simpleTransformation(isMap, 'map', v => [...v.entries()], v => new Map(v)),
- simpleTransformation((v) => isNaNValue(v) || isInfinite(v), 'number', v => {
- if (isNaNValue(v)) {
- return 'NaN';
- }
- if (v > 0) {
- return 'Infinity';
- }
- else {
- return '-Infinity';
- }
- }, Number),
- simpleTransformation((v) => v === 0 && 1 / v === -Infinity, 'number', () => {
- return '-0';
- }, Number),
- simpleTransformation(isURL, 'URL', v => v.toString(), v => new URL(v)),
- ];
- function compositeTransformation(isApplicable, annotation, transform, untransform) {
- return {
- isApplicable,
- annotation,
- transform,
- untransform,
- };
- }
- const symbolRule = compositeTransformation((s, superJson) => {
- if (isSymbol(s)) {
- const isRegistered = !!superJson.symbolRegistry.getIdentifier(s);
- return isRegistered;
- }
- return false;
- }, (s, superJson) => {
- const identifier = superJson.symbolRegistry.getIdentifier(s);
- return ['symbol', identifier];
- }, v => v.description, (_, a, superJson) => {
- const value = superJson.symbolRegistry.getValue(a[1]);
- if (!value) {
- throw new Error('Trying to deserialize unknown symbol');
- }
- return value;
- });
- const constructorToName = [
- Int8Array,
- Uint8Array,
- Int16Array,
- Uint16Array,
- Int32Array,
- Uint32Array,
- Float32Array,
- Float64Array,
- Uint8ClampedArray,
- ].reduce((obj, ctor) => {
- obj[ctor.name] = ctor;
- return obj;
- }, {});
- const typedArrayRule = compositeTransformation(isTypedArray, v => ['typed-array', v.constructor.name], v => [...v], (v, a) => {
- const ctor = constructorToName[a[1]];
- if (!ctor) {
- throw new Error('Trying to deserialize unknown typed array');
- }
- return new ctor(v);
- });
- export function isInstanceOfRegisteredClass(potentialClass, superJson) {
- if (potentialClass?.constructor) {
- const isRegistered = !!superJson.classRegistry.getIdentifier(potentialClass.constructor);
- return isRegistered;
- }
- return false;
- }
- const classRule = compositeTransformation(isInstanceOfRegisteredClass, (clazz, superJson) => {
- const identifier = superJson.classRegistry.getIdentifier(clazz.constructor);
- return ['class', identifier];
- }, (clazz, superJson) => {
- const allowedProps = superJson.classRegistry.getAllowedProps(clazz.constructor);
- if (!allowedProps) {
- return { ...clazz };
- }
- const result = {};
- allowedProps.forEach(prop => {
- result[prop] = clazz[prop];
- });
- return result;
- }, (v, a, superJson) => {
- const clazz = superJson.classRegistry.getValue(a[1]);
- if (!clazz) {
- throw new Error(`Trying to deserialize unknown class '${a[1]}' - check https://github.com/blitz-js/superjson/issues/116#issuecomment-773996564`);
- }
- return Object.assign(Object.create(clazz.prototype), v);
- });
- const customRule = compositeTransformation((value, superJson) => {
- return !!superJson.customTransformerRegistry.findApplicable(value);
- }, (value, superJson) => {
- const transformer = superJson.customTransformerRegistry.findApplicable(value);
- return ['custom', transformer.name];
- }, (value, superJson) => {
- const transformer = superJson.customTransformerRegistry.findApplicable(value);
- return transformer.serialize(value);
- }, (v, a, superJson) => {
- const transformer = superJson.customTransformerRegistry.findByName(a[1]);
- if (!transformer) {
- throw new Error('Trying to deserialize unknown custom value');
- }
- return transformer.deserialize(v);
- });
- const compositeRules = [classRule, symbolRule, customRule, typedArrayRule];
- export const transformValue = (value, superJson) => {
- const applicableCompositeRule = findArr(compositeRules, rule => rule.isApplicable(value, superJson));
- if (applicableCompositeRule) {
- return {
- value: applicableCompositeRule.transform(value, superJson),
- type: applicableCompositeRule.annotation(value, superJson),
- };
- }
- const applicableSimpleRule = findArr(simpleRules, rule => rule.isApplicable(value, superJson));
- if (applicableSimpleRule) {
- return {
- value: applicableSimpleRule.transform(value, superJson),
- type: applicableSimpleRule.annotation,
- };
- }
- return undefined;
- };
- const simpleRulesByAnnotation = {};
- simpleRules.forEach(rule => {
- simpleRulesByAnnotation[rule.annotation] = rule;
- });
- export const untransformValue = (json, type, superJson) => {
- if (isArray(type)) {
- switch (type[0]) {
- case 'symbol':
- return symbolRule.untransform(json, type, superJson);
- case 'class':
- return classRule.untransform(json, type, superJson);
- case 'custom':
- return customRule.untransform(json, type, superJson);
- case 'typed-array':
- return typedArrayRule.untransform(json, type, superJson);
- default:
- throw new Error('Unknown transformation: ' + type);
- }
- }
- else {
- const transformation = simpleRulesByAnnotation[type];
- if (!transformation) {
- throw new Error('Unknown transformation: ' + type);
- }
- return transformation.untransform(json, superJson);
- }
- };
- //# sourceMappingURL=transformer.js.map
|