diff --git a/package-lock.json b/package-lock.json index f38c4fd..670fc21 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "serde", "version": "1.0.0", "license": "ISC", + "dependencies": { + "@tsmetadata/polyfill": "^1.1.3" + }, "devDependencies": { "esbuild": "^0.25.4", "typescript": "^5.8.3" @@ -438,6 +441,12 @@ "node": ">=18" } }, + "node_modules/@tsmetadata/polyfill": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@tsmetadata/polyfill/-/polyfill-1.1.3.tgz", + "integrity": "sha512-uSRn4aPO4F3wlSG/cPCAvclF9Sxf01OizWfWbSoSYsSHAK8LnYdua9iJAm7v2ePUrGWMP4ZCn9QjniZEKZHyFg==", + "license": "MIT" + }, "node_modules/esbuild": { "version": "0.25.4", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", diff --git a/package.json b/package.json index c45de3f..0b9b61f 100644 --- a/package.json +++ b/package.json @@ -32,5 +32,8 @@ "devDependencies": { "esbuild": "^0.25.4", "typescript": "^5.8.3" + }, + "dependencies": { + "@tsmetadata/polyfill": "^1.1.3" } } diff --git a/src/decorator.ts b/src/decorator.ts index a45eb77..1817496 100644 --- a/src/decorator.ts +++ b/src/decorator.ts @@ -1,56 +1,33 @@ import { ContainerOptions, PropertyOptions, SerdeOptions } from './options' import { GlobalRegistry, Registry } from './registry' -export const Serde = Symbol('Serde') - -function decorateContainer(options: ContainerOptions, constructor: any) { - if (constructor[Serde] == null) { - constructor[Serde] = new SerdeOptions(constructor, options) - } else { - constructor[Serde].options = options - } - - return constructor +function decorateContainer(target: any, context: any, options: ContainerOptions) { + const meta = context.metadata + const serde = (meta.serde || new SerdeOptions(target)) + serde.options = options + meta.serde = serde } -function decorateProperty(options: PropertyOptions, target: any, property: PropertyKey) { - let constructor: any - if (typeof target === 'function') { - constructor = target - } else { - constructor = target.constructor - } - - if (constructor[Serde] == null) { - constructor[Serde] = SerdeOptions.from(target) - } - - constructor[Serde].properties.set(property, options) - return target +function decorateProperty(target: any, context: any, options: PropertyOptions) { + const meta = context.metadata + const serde = (meta.serde || new SerdeOptions(target)) + serde.properties.set(context, options) + meta.serde = serde } export function serde(options: ContainerOptions | PropertyOptions) { - return function(target: any, property?: PropertyKey) { - if (property != null) { - return decorateProperty(options as PropertyOptions, target, property) + return function(target: any, context: any) { + if (context != null) { + decorateProperty(target, context, options as PropertyOptions) } else { - return decorateContainer(options, target) + decorateContainer(target, context, options as ContainerOptions) } } } -export function getMetadata(value: any) { - return value[Serde] -} - export function register(registry: Registry = GlobalRegistry) { - return function(target: any) { - if (target[Serde] == null) { - target[Serde] = SerdeOptions.from(target) - } - + return function(target: any, _context: any) { registry.add(target) - return target } } diff --git a/src/ser/impl.ts b/src/ser/impl.ts index 8aff261..97153d2 100644 --- a/src/ser/impl.ts +++ b/src/ser/impl.ts @@ -1,5 +1,4 @@ import { IterableSerializer, ObjectSerializer, Serializable, Serializer } from './interface' -import { Serde } from '../decorator' import { SerdeOptions, Stage } from '../options' import { ifNull, isFunction, isIterable, isPlainObject, Nullable, orElse } from '../utils' @@ -41,7 +40,7 @@ function serializeIter>(serializer: IterableSerialize } function defaultOptions(value: any) { - return value.constructor[Serde] + return value.constructor[Symbol.metadata] } // dispatches in the order of serializeType -> serializeAny -> throw TypeError diff --git a/src/ser/index.ts b/src/ser/index.ts index 31ca20c..db68fd6 100644 --- a/src/ser/index.ts +++ b/src/ser/index.ts @@ -1,3 +1,5 @@ +import '@tsmetadata/polyfill' + export * from './interface' export * from './mixin' export * from './impl'