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");
function deserializeWith(deserializer, into, options) {
const visitor = new generic_1.GenericVisitor();
const obj = deserializer.deserializeObject(visitor);
const target = new into();
const obj = deserializer.deserializeObject(visitor);
const newObject = {};
for (const property in target) {
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;
deserializeNull<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;
}
export interface Deserialize<T> {

2
dist/de/mixin.js vendored
View file

@ -50,7 +50,7 @@ function deserialize(constructor) {
let _classSuper = constructor;
var Deserializable = _classThis = class extends _classSuper {
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");

8
dist/decorator.js vendored
View file

@ -7,23 +7,23 @@ const registry_1 = require("./registry");
function decorateContainer(target, context, options) {
const meta = context.metadata;
const serde = (meta.serde || new options_1.SerdeOptions(target));
serde.target = target;
serde.options = options;
meta.serde = serde;
}
function decorateProperty(target, context, options) {
const meta = context.metadata;
const serde = (meta.serde || new options_1.SerdeOptions(target));
serde.properties.set(context, options);
serde.properties.set(context.name, options);
meta.serde = serde;
}
function serde(options) {
return function (target, context) {
if (context != null) {
if (target == null) {
decorateProperty(target, context, options);
}
else {
else
decorateContainer(target, context, options);
}
};
}
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 declare class SerdeOptions {
private readonly target;
target: any;
readonly options: ContainerOptions;
readonly properties: Map<string, PropertyOptions>;
get registry(): Registry;
constructor(target: any, options?: ContainerOptions, properties?: Map<string, PropertyOptions>);
constructor(options?: ContainerOptions, properties?: Map<string, PropertyOptions>);
static from(target: any): SerdeOptions;
getClassName(stage: Stage): any;
private getPropertyRename;

3
dist/options.js vendored
View file

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

9
dist/ser/impl.js vendored
View file

@ -17,10 +17,6 @@ function serializeEntries(serializer, value, options) {
}
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) {
return serializeEntries(serializer.serializeObject(), Object.entries(value), options);
}
@ -32,7 +28,7 @@ function serializeIter(serializer, value, options) {
return serializer.end();
}
function defaultOptions(value) {
return value.constructor[Symbol.metadata];
return value.constructor[Symbol.metadata].serde;
}
// dispatches in the order of serializeType -> serializeAny -> throw TypeError
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)) {
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)) {
return serializeObject(serializer, value, options);
} // deliberate fallthrough when the above fail

View file

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

View file

@ -12,7 +12,7 @@ const TypeSerializerMethods = [
'serializeIterable',
'serializeNull',
'serializeObject',
'serializeClass',
//'serializeClass',
];
const AnySerializerMethods = ['serializeAny'];
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 {
const visitor = new GenericVisitor<T>()
const obj = deserializer.deserializeObject(visitor) as any
const target = new into()
const obj = deserializer.deserializeObject(visitor) as any
const newObject = {} as any
for (const property in target) {

View file

@ -74,7 +74,6 @@ export interface Deserializer {
deserializeSymbol<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
deserializeClass<T, V extends Visitor<T>>(name: string, fields: string[], 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 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) {
const meta = context.metadata
const serde = (meta.serde || new SerdeOptions(target))
serde.target = target
serde.options = options
meta.serde = serde
}
@ -11,18 +12,17 @@ function decorateContainer(target: any, context: any, options: ContainerOptions)
function decorateProperty(target: any, context: any, options: PropertyOptions) {
const meta = context.metadata
const serde = (meta.serde || new SerdeOptions(target))
serde.properties.set(context, options)
serde.properties.set(context.name, options)
meta.serde = serde
}
export function serde(options: ContainerOptions | PropertyOptions) {
return function(target: any, context: any) {
if (context != null) {
if (target == null) {
decorateProperty(target, context, options as PropertyOptions)
} else {
} else
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 class SerdeOptions {
private readonly target: any
target: any
readonly options: ContainerOptions
readonly properties: Map<string, PropertyOptions>
@ -68,8 +68,7 @@ export class SerdeOptions {
return this.options.registry || GlobalRegistry
}
constructor(target: any, options: ContainerOptions = {}, properties: Map<string, PropertyOptions> = new Map()) {
this.target = target
constructor(options: ContainerOptions = {}, properties: Map<string, PropertyOptions> = new Map()) {
this.options = options
this.properties = properties
}

View file

@ -1,6 +1,6 @@
import { IterableSerializer, ObjectSerializer, Serializable, Serializer } from './interface'
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}'`)
@ -20,11 +20,6 @@ function serializeEntries<T, K extends string, V extends Serializable, E extends
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) {
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) {
return value.constructor[Symbol.metadata]
return value.constructor[Symbol.metadata].serde
}
// 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)
if (isIterable(value) && isFunction(serializer.serializeIterable)) {
return serializeIter(serializer.serializeIterable(), value, options)
} if (!isPlainObject(value)) {
return serializeClass(serializer, value as Record<PropertyKey, any>, options)
} else if (isFunction(serializer.serializeObject)) {
return serializeObject(serializer, value as Record<PropertyKey, any>, options)
} // deliberate fallthrough when the above fail

View file

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