This commit is contained in:
Rowan 2025-05-19 13:30:11 -05:00
parent d749044351
commit 69e56d2d74
16 changed files with 23 additions and 42 deletions

2
dist/de/impl.js vendored
View file

@ -5,8 +5,8 @@ const options_1 = require("../options");
const generic_1 = require("./generic"); const generic_1 = require("./generic");
function deserializeWith(deserializer, into, options) { function deserializeWith(deserializer, into, options) {
const visitor = new generic_1.GenericVisitor(); const visitor = new generic_1.GenericVisitor();
const obj = deserializer.deserializeObject(visitor);
const target = new into(); const target = new into();
const obj = deserializer.deserializeObject(visitor);
const newObject = {}; const newObject = {};
for (const property in target) { for (const property in target) {
const name = options.getPropertyName(property, options_1.Stage.Deserialize); const name = options.getPropertyName(property, options_1.Stage.Deserialize);

View file

@ -44,7 +44,6 @@ export interface Deserializer {
deserializeSymbol<T, V extends Visitor<T>>(visitor: V): T; deserializeSymbol<T, V extends Visitor<T>>(visitor: V): T;
deserializeNull<T, V extends Visitor<T>>(visitor: V): T; deserializeNull<T, V extends Visitor<T>>(visitor: V): T;
deserializeObject<T, V extends Visitor<T>>(visitor: V): T; deserializeObject<T, V extends Visitor<T>>(visitor: V): T;
deserializeClass<T, V extends Visitor<T>>(name: string, fields: string[], visitor: V): T;
deserializeIterable<T, V extends Visitor<T>>(visitor: V): T; deserializeIterable<T, V extends Visitor<T>>(visitor: V): T;
} }
export interface Deserialize<T> { export interface Deserialize<T> {

2
dist/de/mixin.js vendored
View file

@ -50,7 +50,7 @@ function deserialize(constructor) {
let _classSuper = constructor; let _classSuper = constructor;
var Deserializable = _classThis = class extends _classSuper { var Deserializable = _classThis = class extends _classSuper {
static deserialize(deserializer) { static deserialize(deserializer) {
return (0, impl_1.deserializeWith)(deserializer, this, constructor[Symbol.metadata]); return (0, impl_1.deserializeWith)(deserializer, this, this[Symbol.metadata].serde);
} }
}; };
__setFunctionName(_classThis, "Deserializable"); __setFunctionName(_classThis, "Deserializable");

8
dist/decorator.js vendored
View file

@ -7,23 +7,23 @@ const registry_1 = require("./registry");
function decorateContainer(target, context, options) { function decorateContainer(target, context, options) {
const meta = context.metadata; const meta = context.metadata;
const serde = (meta.serde || new options_1.SerdeOptions(target)); const serde = (meta.serde || new options_1.SerdeOptions(target));
serde.target = target;
serde.options = options; serde.options = options;
meta.serde = serde; meta.serde = serde;
} }
function decorateProperty(target, context, options) { function decorateProperty(target, context, options) {
const meta = context.metadata; const meta = context.metadata;
const serde = (meta.serde || new options_1.SerdeOptions(target)); const serde = (meta.serde || new options_1.SerdeOptions(target));
serde.properties.set(context, options); serde.properties.set(context.name, options);
meta.serde = serde; meta.serde = serde;
} }
function serde(options) { function serde(options) {
return function (target, context) { return function (target, context) {
if (context != null) { if (target == null) {
decorateProperty(target, context, options); decorateProperty(target, context, options);
} }
else { else
decorateContainer(target, context, options); decorateContainer(target, context, options);
}
}; };
} }
function register(registry = registry_1.GlobalRegistry) { function register(registry = registry_1.GlobalRegistry) {

4
dist/options.d.ts vendored
View file

@ -43,11 +43,11 @@ export declare const Stage: Readonly<{
}>; }>;
export type Stage = typeof Stage[keyof typeof Stage]; export type Stage = typeof Stage[keyof typeof Stage];
export declare class SerdeOptions { export declare class SerdeOptions {
private readonly target; target: any;
readonly options: ContainerOptions; readonly options: ContainerOptions;
readonly properties: Map<string, PropertyOptions>; readonly properties: Map<string, PropertyOptions>;
get registry(): Registry; get registry(): Registry;
constructor(target: any, options?: ContainerOptions, properties?: Map<string, PropertyOptions>); constructor(options?: ContainerOptions, properties?: Map<string, PropertyOptions>);
static from(target: any): SerdeOptions; static from(target: any): SerdeOptions;
getClassName(stage: Stage): any; getClassName(stage: Stage): any;
private getPropertyRename; private getPropertyRename;

3
dist/options.js vendored
View file

@ -12,7 +12,7 @@ class SerdeOptions {
get registry() { get registry() {
return this.options.registry || registry_1.GlobalRegistry; return this.options.registry || registry_1.GlobalRegistry;
} }
constructor(target, options = {}, properties = new Map()) { constructor(options = {}, properties = new Map()) {
Object.defineProperty(this, "target", { Object.defineProperty(this, "target", {
enumerable: true, enumerable: true,
configurable: true, configurable: true,
@ -31,7 +31,6 @@ class SerdeOptions {
writable: true, writable: true,
value: void 0 value: void 0
}); });
this.target = target;
this.options = options; this.options = options;
this.properties = properties; this.properties = properties;
} }

9
dist/ser/impl.js vendored
View file

@ -17,10 +17,6 @@ function serializeEntries(serializer, value, options) {
} }
return serializer.end(); return serializer.end();
} }
function serializeClass(serializer, value, options) {
const classSerializer = serializer.serializeClass(value.constructor.name);
return serializeEntries(classSerializer, Object.entries(value), options);
}
function serializeObject(serializer, value, options) { function serializeObject(serializer, value, options) {
return serializeEntries(serializer.serializeObject(), Object.entries(value), options); return serializeEntries(serializer.serializeObject(), Object.entries(value), options);
} }
@ -32,7 +28,7 @@ function serializeIter(serializer, value, options) {
return serializer.end(); return serializer.end();
} }
function defaultOptions(value) { function defaultOptions(value) {
return value.constructor[Symbol.metadata]; return value.constructor[Symbol.metadata].serde;
} }
// dispatches in the order of serializeType -> serializeAny -> throw TypeError // dispatches in the order of serializeType -> serializeAny -> throw TypeError
function serializeWith(serializer, value, optionsGetter = defaultOptions) { function serializeWith(serializer, value, optionsGetter = defaultOptions) {
@ -51,9 +47,6 @@ function serializeWith(serializer, value, optionsGetter = defaultOptions) {
if ((0, utils_1.isIterable)(value) && (0, utils_1.isFunction)(serializer.serializeIterable)) { if ((0, utils_1.isIterable)(value) && (0, utils_1.isFunction)(serializer.serializeIterable)) {
return serializeIter(serializer.serializeIterable(), value, options); return serializeIter(serializer.serializeIterable(), value, options);
} }
if (!(0, utils_1.isPlainObject)(value)) {
return serializeClass(serializer, value, options);
}
else if ((0, utils_1.isFunction)(serializer.serializeObject)) { else if ((0, utils_1.isFunction)(serializer.serializeObject)) {
return serializeObject(serializer, value, options); return serializeObject(serializer, value, options);
} // deliberate fallthrough when the above fail } // deliberate fallthrough when the above fail

View file

@ -17,7 +17,6 @@ interface TypeSerializer<T> {
serializeNull(): T; serializeNull(): T;
serializeObject(): ObjectSerializer<T>; serializeObject(): ObjectSerializer<T>;
serializeIterable?(): IterableSerializer<T>; serializeIterable?(): IterableSerializer<T>;
serializeClass(name: PropertyKey): ObjectSerializer<T>;
} }
interface AnySerializer<T> { interface AnySerializer<T> {
serializeAny?(value?: any): T; serializeAny?(value?: any): T;

View file

@ -12,7 +12,7 @@ const TypeSerializerMethods = [
'serializeIterable', 'serializeIterable',
'serializeNull', 'serializeNull',
'serializeObject', 'serializeObject',
'serializeClass', //'serializeClass',
]; ];
const AnySerializerMethods = ['serializeAny']; const AnySerializerMethods = ['serializeAny'];
function isGenericSerializer(value) { function isGenericSerializer(value) {

View file

@ -6,8 +6,8 @@ type DeserializeConstructor<T> = Deserialize<T> & { new(): Deserialize<T> }
export function deserializeWith<T, D extends Deserializer, E extends DeserializeConstructor<T>>(deserializer: D, into: E, options: SerdeOptions): T { export function deserializeWith<T, D extends Deserializer, E extends DeserializeConstructor<T>>(deserializer: D, into: E, options: SerdeOptions): T {
const visitor = new GenericVisitor<T>() const visitor = new GenericVisitor<T>()
const obj = deserializer.deserializeObject(visitor) as any
const target = new into() const target = new into()
const obj = deserializer.deserializeObject(visitor) as any
const newObject = {} as any const newObject = {} as any
for (const property in target) { for (const property in target) {

View file

@ -74,7 +74,6 @@ export interface Deserializer {
deserializeSymbol<T, V extends Visitor<T>>(visitor: V): T deserializeSymbol<T, V extends Visitor<T>>(visitor: V): T
deserializeNull<T, V extends Visitor<T>>(visitor: V): T deserializeNull<T, V extends Visitor<T>>(visitor: V): T
deserializeObject<T, V extends Visitor<T>>(visitor: V): T deserializeObject<T, V extends Visitor<T>>(visitor: V): T
deserializeClass<T, V extends Visitor<T>>(name: string, fields: string[], visitor: V): T
deserializeIterable<T, V extends Visitor<T>>(visitor: V): T deserializeIterable<T, V extends Visitor<T>>(visitor: V): T
} }

View file

@ -8,7 +8,7 @@ export function deserialize<T, C extends Constructor>(constructor: C) {
static name = constructor.name static name = constructor.name
static deserialize<D extends Deserializer>(deserializer: D): T { static deserialize<D extends Deserializer>(deserializer: D): T {
return deserializeWith(deserializer, this, (constructor as any)[Symbol.metadata]) return deserializeWith(deserializer, this, (this as any)[Symbol.metadata].serde)
} }
} }

View file

@ -4,6 +4,7 @@ import { GlobalRegistry, Registry } from './registry'
function decorateContainer(target: any, context: any, options: ContainerOptions) { function decorateContainer(target: any, context: any, options: ContainerOptions) {
const meta = context.metadata const meta = context.metadata
const serde = (meta.serde || new SerdeOptions(target)) const serde = (meta.serde || new SerdeOptions(target))
serde.target = target
serde.options = options serde.options = options
meta.serde = serde meta.serde = serde
} }
@ -11,18 +12,17 @@ function decorateContainer(target: any, context: any, options: ContainerOptions)
function decorateProperty(target: any, context: any, options: PropertyOptions) { function decorateProperty(target: any, context: any, options: PropertyOptions) {
const meta = context.metadata const meta = context.metadata
const serde = (meta.serde || new SerdeOptions(target)) const serde = (meta.serde || new SerdeOptions(target))
serde.properties.set(context, options) serde.properties.set(context.name, options)
meta.serde = serde meta.serde = serde
} }
export function serde(options: ContainerOptions | PropertyOptions) { export function serde(options: ContainerOptions | PropertyOptions) {
return function(target: any, context: any) { return function(target: any, context: any) {
if (context != null) { if (target == null) {
decorateProperty(target, context, options as PropertyOptions) decorateProperty(target, context, options as PropertyOptions)
} else { } else
decorateContainer(target, context, options as ContainerOptions) decorateContainer(target, context, options as ContainerOptions)
}
} }
} }

View file

@ -60,7 +60,7 @@ export const Stage = Object.freeze({
export type Stage = typeof Stage[keyof typeof Stage] export type Stage = typeof Stage[keyof typeof Stage]
export class SerdeOptions { export class SerdeOptions {
private readonly target: any target: any
readonly options: ContainerOptions readonly options: ContainerOptions
readonly properties: Map<string, PropertyOptions> readonly properties: Map<string, PropertyOptions>
@ -68,8 +68,7 @@ export class SerdeOptions {
return this.options.registry || GlobalRegistry return this.options.registry || GlobalRegistry
} }
constructor(target: any, options: ContainerOptions = {}, properties: Map<string, PropertyOptions> = new Map()) { constructor(options: ContainerOptions = {}, properties: Map<string, PropertyOptions> = new Map()) {
this.target = target
this.options = options this.options = options
this.properties = properties this.properties = properties
} }

View file

@ -1,6 +1,6 @@
import { IterableSerializer, ObjectSerializer, Serializable, Serializer } from './interface' import { IterableSerializer, ObjectSerializer, Serializable, Serializer } from './interface'
import { SerdeOptions, Stage } from '../options' import { SerdeOptions, Stage } from '../options'
import { ifNull, isFunction, isIterable, isPlainObject, Nullable, orElse } from '../utils' import { ifNull, isFunction, isIterable, Nullable, orElse } from '../utils'
const unhandledType = (serializer: any, value: any) => new TypeError(`'${serializer.constructor.name}' has no method for value type '${typeof value}'`) const unhandledType = (serializer: any, value: any) => new TypeError(`'${serializer.constructor.name}' has no method for value type '${typeof value}'`)
@ -20,11 +20,6 @@ function serializeEntries<T, K extends string, V extends Serializable, E extends
return serializer.end() return serializer.end()
} }
function serializeClass<T, K extends string, V extends Serializable, R extends Record<K, V>>(serializer: Serializer<T>, value: R, options?: SerdeOptions) {
const classSerializer = serializer.serializeClass!(value.constructor.name)
return serializeEntries(classSerializer, Object.entries(value) as Iterable<[K, V]>, options)
}
function serializeObject<T, K extends string, V extends Serializable, R extends Record<K, V>>(serializer: Serializer<T>, value: R, options?: SerdeOptions) { function serializeObject<T, K extends string, V extends Serializable, R extends Record<K, V>>(serializer: Serializer<T>, value: R, options?: SerdeOptions) {
return serializeEntries(serializer.serializeObject!(), Object.entries(value) as Iterable<[K, V]>, options) return serializeEntries(serializer.serializeObject!(), Object.entries(value) as Iterable<[K, V]>, options)
} }
@ -40,7 +35,7 @@ function serializeIter<T, V extends Iterable<any>>(serializer: IterableSerialize
} }
function defaultOptions(value: any) { function defaultOptions(value: any) {
return value.constructor[Symbol.metadata] return value.constructor[Symbol.metadata].serde
} }
// dispatches in the order of serializeType -> serializeAny -> throw TypeError // dispatches in the order of serializeType -> serializeAny -> throw TypeError
@ -66,8 +61,6 @@ export function serializeWith<T>(serializer: Serializer<T>, value: Serializable,
const options = optionsGetter(value) const options = optionsGetter(value)
if (isIterable(value) && isFunction(serializer.serializeIterable)) { if (isIterable(value) && isFunction(serializer.serializeIterable)) {
return serializeIter(serializer.serializeIterable(), value, options) return serializeIter(serializer.serializeIterable(), value, options)
} if (!isPlainObject(value)) {
return serializeClass(serializer, value as Record<PropertyKey, any>, options)
} else if (isFunction(serializer.serializeObject)) { } else if (isFunction(serializer.serializeObject)) {
return serializeObject(serializer, value as Record<PropertyKey, any>, options) return serializeObject(serializer, value as Record<PropertyKey, any>, options)
} // deliberate fallthrough when the above fail } // deliberate fallthrough when the above fail

View file

@ -21,7 +21,7 @@ const TypeSerializerMethods = [
'serializeIterable', 'serializeIterable',
'serializeNull', 'serializeNull',
'serializeObject', 'serializeObject',
'serializeClass', //'serializeClass',
] as const ] as const
interface TypeSerializer<T> { interface TypeSerializer<T> {
@ -34,7 +34,7 @@ interface TypeSerializer<T> {
serializeObject(): ObjectSerializer<T> serializeObject(): ObjectSerializer<T>
// serializeMap?(): ObjectSerializer<T> // serializeMap?(): ObjectSerializer<T>
serializeIterable?(): IterableSerializer<T> serializeIterable?(): IterableSerializer<T>
serializeClass(name: PropertyKey): ObjectSerializer<T> //serializeClass(name: PropertyKey): ObjectSerializer<T>
} }
const AnySerializerMethods = ['serializeAny'] const AnySerializerMethods = ['serializeAny']