@autometa/dto-builder
Advanced tools
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../../src/dto-default.decorator.ts","../../src/property.enum.ts","../../src/property.decorator.ts","../../src/dto.ts","../../src/interface-proxy.ts"],"sourcesContent":["import { metadata } from \"@autometa/injection\";\nimport { DtoBuilderSymbols } from \"./property.enum\";\nimport { Class, PropertyMetadata } from \"./types\";\nimport \"any-date-parser\";\n\nexport interface Default {\n value(value: unknown): PropertyDecorator;\n\n factory(factory: (...args: unknown[]) => unknown): PropertyDecorator;\n\n dto(dtoType: Class<unknown>): PropertyDecorator;\n\n date(): PropertyDecorator;\n date(format: string): PropertyDecorator;\n date(stamp: number): PropertyDecorator;\n date(stamp?: string | number): PropertyDecorator;\n}\n\nexport const DefaultValueDecorators: Default = {\n value: (value: unknown) => (target: object, propertyKey: string | symbol) => {\n const container = metadata(getConstructor(target)).custom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS,\n {},\n false\n );\n const datum = { value };\n container[propertyKey as string] = datum;\n },\n factory:\n (factory: (...args: unknown[]) => unknown) =>\n (target: object, propertyKey: string | symbol) => {\n const container = metadata(getConstructor(target)).custom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS,\n {},\n false\n );\n const datum = { factory };\n container[propertyKey as string] = datum;\n },\n dto: (dtoType: Class<unknown>) => (target: object, propertyKey: string | symbol) => {\n const container = metadata(getConstructor(target)).custom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS,\n {},\n false\n );\n const datum = { dtoType };\n container[propertyKey as string] = datum;\n },\n date: (stamp?: string | number | undefined) => {\n return (target: object, propertyKey: string | symbol) => {\n const container = metadata(getConstructor(target)).custom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS,\n {},\n false\n );\n const datum = {\n factory: () => {\n if (\"number\" === typeof stamp) {\n return new Date(stamp);\n }\n if (!stamp) {\n return new Date();\n }\n return (Date as unknown as { fromString: (s: string) => Date }).fromString(stamp);\n },\n };\n container[propertyKey as string] = datum;\n };\n },\n};\n\nexport function getConstructor(target: unknown) {\n if (target && \"constructor\" in (target as object)) {\n return target.constructor;\n }\n throw new Error(`Cannot get constructor for ${target}`);\n}","const PROPERTY_DEFAULTS: unique symbol = Symbol(\"autometa:meta-data:property-defaults\");\nexport const DtoBuilderSymbols = {\n PROPERTY_DEFAULTS,\n} as const;\n","import { DefaultValueDecorators } from \"./dto-default.decorator\";\nimport type { Class } from \"./types\";\n\n/**\n * \n * @param defaultValue \n * \n * @deprecated Use `@DTO.value`, `@DTO.factory` and `@DTO.dto` instead\n */\nexport function Property<T extends () => unknown>(defaultValue: T): PropertyDecorator;\nexport function Property<T>(defaultValue: T): PropertyDecorator;\nexport function Property(defaultOrFactory: unknown | (() => unknown)): PropertyDecorator {\n return determineDefaultType(defaultOrFactory);\n}\nfunction determineDefaultType(defaultOrFactory: unknown | Class<unknown> | (() => unknown)): PropertyDecorator {\n if (isClass(defaultOrFactory)) {\n return DefaultValueDecorators.dto(defaultOrFactory);\n }\n\n if (\"function\" === typeof defaultOrFactory) {\n return DefaultValueDecorators.factory(defaultOrFactory as () => unknown);\n }\n\n if (defaultOrFactory instanceof Date.constructor) {\n return DefaultValueDecorators.date();\n }\n\n return DefaultValueDecorators.value(defaultOrFactory);\n}\n\nfunction isClass(value: unknown): value is Class<unknown> {\n if (!(\"function\" != typeof value)) {\n return false;\n }\n\n return /^class[\\s{]/.test(toString.call(value));\n}\n","import { DefaultValueDecorators, Default } from \"./dto-default.decorator\";\nimport { Class } from \"./types\";\n\nexport function DTOWrapper<T extends object>() {\n return class {} as Class<T>;\n}\n\nexport const DTO: typeof DTOWrapper & Default = Object.assign(DTOWrapper, DefaultValueDecorators);\n","import { metadata } from \"@autometa/injection\";\nimport { Class, PropertyMetadata } from \"./types\";\nimport { DtoBuilderSymbols } from \"./property.enum\";\nexport type IBuilder<T> = {\n [k in keyof T]-?: ((arg: T[k]) => IBuilder<T>) & (() => T[k]);\n} & {\n /**\n * Build the object and return it\n */\n build(): T;\n /**\n * Derive a new builder from the current builder, copying it's\n * current values into a new builder. Allows default values to\n * be set in a copy, which will not be modified by child copies.\n */\n derive(): IBuilder<T>;\n /**\n * Assign an arbitrary value to a property. The value\n * does not need to match a valid property for the interface\n * and can be used to introduce \"unexpected\" values for testing,\n * or coming from other object maps.\n * @param property the name of the property to set a value for\n * @param value the value to set\n */\n assign<K>(property: string, value: K): IBuilder<T>;\n /**\n * Append a value to an array property. If no array\n * has been defined one will be created. If one exists,\n * it will be reused.\n * @param property\n * @param value\n */\n append<K>(property: string, value: K): IBuilder<T>;\n\n /**\n * Attach a value to a sub-property of a property.\n * If the property does not exist, a new empty object will be\n * assigned to it.\n *\n * The value is appended to the child object indexed by the sub-property.\n * @param property The name of the property to attach key:value pairs to\n * @param subProperty The name of the sub-property to attach the value to\n * @param value The value to attach to the child objects property\n */\n attach<K>(property: string, subProperty: string, value: K): ClsBuilder<T>;\n};\nexport type ClsBuilder<T> = {\n [k in keyof T]-?: BuilderMethod<T, T[k]>;\n} & {\n /**\n * Build the object and return it\n */\n build(): T;\n /**\n * Assign an arbitrary value to a property. The value\n * does not need to match a valid property for the interface\n * and can be used to introduce \"unexpected\" values for testing,\n * or coming from other object maps.\n * @param property the name of the property to set a value for\n * @param value the value to set\n */\n assign<K>(property: string, value: K): ClsBuilder<T>;\n /**\n * Append a value to an array property. If no array\n * has been defined one will be created. If one exists,\n * it will be reused.\n * @param property\n * @param value\n */\n append<K>(property: string, value: K): ClsBuilder<T>;\n\n /**\n * Attach a value to a sub-property of a property.\n * If the property does not exist, a new empty object will be\n * assigned to it.\n *\n * The value is appended to the child object indexed by the sub-property.\n * @param property The name of the property to attach key:value pairs to\n * @param subProperty The name of the sub-property to attach the value to\n * @param value The value to attach to the child objects property\n */\n attach<K>(property: string, subProperty: string, value: K): ClsBuilder<T>;\n};\n\nexport type BuilderMethod<TTarget, TType> = ((arg: TType) => ClsBuilder<TTarget>) & {\n value: TType;\n};\nexport type DtoBuilder<T> = Class<ClsBuilder<T>> & {\n /**\n * Construct a builder from a raw object or class instance,\n * inheriting any properties that have already been defined.\n * @param value /\n */\n fromRaw(value: Partial<T>): ClsBuilder<T>;\n /**\n * Constructs a DTO, prefilled with any default values\n * assigned to the DTO via either the `Property` decorator\n * or the `DTO.*` decorators.\n *\n * With property:\n *\n * ```ts\n * class FooDto {\n * @Property(1)\n * foo: number;\n * @Property(()=> \"factory string\")\n * bar: string;\n * @Property(SomeDto)\n * baz: SomeDto;\n * }\n * ```\n *\n * With DTO:\n *\n * ```ts\n * class FooDto {\n * @DTO.value(1)\n * foo: number;\n * @DTO.factory(()=> \"factory string\")\n * bar: string;\n * @DTO.dto(SomeDto)\n * baz: SomeDto;\n * }\n * ```\n */\n default(): T;\n};\n\nexport function Builder<T>(cls: Class<T>): DtoBuilder<T>;\nexport function Builder<T>(): IBuilder<T>;\nexport function Builder<T>(defaults?: Partial<T> | Class<T>): IBuilder<T> | DtoBuilder<T> {\n if (isClassBuilder(defaults)) {\n return class BuilderClass<TType> {\n constructor() {\n const built: Record<string, unknown> = { ...defaults };\n const proxy = classProxy.bind(null, defaults as Class<unknown>, built);\n return proxy(this) as BuilderClass<TType>;\n }\n declare build: () => T;\n declare assign: <K>(property: string, value: K) => BuilderClass<TType>;\n static fromRaw(value: T) {\n const builder = new this();\n const keys = Object.keys(value as object) as (keyof T)[];\n for (const key of keys) {\n builder.assign(key.toString(), value[key]);\n }\n return builder;\n }\n\n static default() {\n return new this().build();\n }\n } as DtoBuilder<T>;\n // return clsBuilder as IBuilder<T>;\n }\n const built: Record<string, unknown> = { ...defaults };\n const builder = new Proxy(built, {\n get(target, prop) {\n if (\"build\" === prop) {\n return () => built;\n }\n\n if (\"derive\" === prop) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return () => Builder<T>({ ...built } as any);\n }\n\n if (\"assign\" === prop) {\n return (property: keyof T, value: unknown) => {\n built[property.toString()] = value;\n return target;\n };\n }\n\n if (\"attach\" === prop) {\n return (property: keyof T, subProperty: string, value: unknown) => {\n if (typeof built[property.toString()] === undefined) {\n built[property.toString()] = {};\n }\n const dict = built[property.toString()] as Record<string, unknown>;\n dict[subProperty] = value;\n return target;\n };\n }\n\n if (\"append\" === prop) {\n return (property: keyof T, value: unknown) => {\n if (!Array.isArray(built[property.toString()])) {\n built[property.toString()] = [value];\n } else {\n (built[property.toString()] as unknown[]).push(value);\n }\n return target;\n };\n }\n\n return (...args: unknown[]): unknown => {\n // If no arguments passed return current value.\n if (0 === args.length) {\n return built[prop.toString()];\n }\n\n built[prop.toString()] = args[0];\n return builder;\n };\n },\n });\n\n return builder as IBuilder<T>;\n}\n\nfunction classProxy<T>(defaults: Class<T>, built: Record<string, unknown>, inst: T) {\n const clsBuilder = new Proxy(inst as object, {\n get(_, prop) {\n if (\"build\" === prop) {\n return () => {\n const instance = constructDefaultDto(defaults);\n return Object.assign(instance as object, { ...built });\n };\n }\n if (\"assign\" === prop) {\n const fn = (property: keyof T, value: unknown) => {\n built[property.toString()] = value;\n return clsBuilder;\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return fn as any;\n }\n if (\"append\" === prop) {\n const fn = (property: keyof T, value: unknown) => {\n if (!Array.isArray(built[property.toString()])) {\n built[property.toString()] = [value];\n } else {\n (built[property.toString()] as unknown[]).push(value);\n }\n return clsBuilder;\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return fn as any;\n }\n if (\"attach\" === prop) {\n return (property: keyof T, subProperty: string, value: unknown) => {\n if (built[property.toString()] === undefined) {\n built[property.toString()] = {};\n }\n const dict = built[property.toString()] as Record<string, unknown>;\n dict[subProperty] = value;\n return clsBuilder;\n };\n }\n if (prop in (inst as Record<string, unknown>)) {\n return (inst as Record<string, unknown>)[prop as string];\n }\n const fn = (...args: unknown[]): unknown => {\n // If no arguments passed return current value.\n if (0 === args.length) {\n return built[prop.toString()];\n }\n built[prop.toString()] = args[0];\n return clsBuilder;\n };\n const modified = Object.defineProperty(fn, \"value\", {\n get() {\n return built[prop.toString()];\n },\n });\n return modified;\n },\n });\n return clsBuilder as ClsBuilder<T>;\n}\n\nfunction isClassBuilder<T>(cls: unknown): cls is Class<T> {\n return \"function\" === typeof cls;\n}\n\nfunction constructDefaultDto<T>(base: Class<T>): T {\n const defaultSetters = metadata(base).getCustom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS\n );\n const instance = new base();\n if (!defaultSetters) {\n return instance;\n }\n const keys = Object.keys(defaultSetters) as unknown as (keyof typeof instance)[] &\n (keyof typeof defaultSetters)[];\n\n for (const key of keys) {\n const value = defaultSetters[key];\n if (\"value\" in value) {\n Object.defineProperty(instance as object, key, {\n value: value.value,\n writable: true,\n enumerable: true,\n });\n }\n if (\"factory\" in value) {\n Object.defineProperty(instance as object, key, {\n value: value.factory(),\n writable: true,\n enumerable: true,\n });\n }\n if (\"dtoType\" in value) {\n const dtoInst = constructDefaultDto(value.dtoType);\n Object.defineProperty(instance as object, key, {\n value: dtoInst,\n writable: true,\n enumerable: true,\n });\n }\n }\n return instance;\n}\n"],"mappings":"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","names":["metadata","built","builder","fn","metadata"]} | ||
| {"version":3,"sources":["../../src/dto-default.decorator.ts","../../src/property.enum.ts","../../src/property.decorator.ts","../../src/dto.ts","../../src/interface-proxy.ts"],"sourcesContent":["import { metadata } from \"@autometa/injection\";\nimport { DtoBuilderSymbols } from \"./property.enum\";\nimport { Class, PropertyMetadata } from \"./types\";\nimport \"any-date-parser\";\n\nexport interface Default {\n value(value: unknown): PropertyDecorator;\n\n factory(factory: (...args: unknown[]) => unknown): PropertyDecorator;\n\n dto(dtoType: Class<unknown>): PropertyDecorator;\n\n date(): PropertyDecorator;\n date(format: string): PropertyDecorator;\n date(stamp: number): PropertyDecorator;\n date(stamp?: string | number): PropertyDecorator;\n}\n\nexport const DefaultValueDecorators: Default = {\n value: (value: unknown) => (target: object, propertyKey: string | symbol) => {\n const container = metadata(getConstructor(target)).custom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS,\n {},\n false\n );\n const datum = { value };\n container[propertyKey as string] = datum;\n },\n factory:\n (factory: (...args: unknown[]) => unknown) =>\n (target: object, propertyKey: string | symbol) => {\n const container = metadata(getConstructor(target)).custom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS,\n {},\n false\n );\n const datum = { factory };\n container[propertyKey as string] = datum;\n },\n dto: (dtoType: Class<unknown>) => (target: object, propertyKey: string | symbol) => {\n const container = metadata(getConstructor(target)).custom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS,\n {},\n false\n );\n const datum = { dtoType };\n container[propertyKey as string] = datum;\n },\n date: (stamp?: string | number | undefined) => {\n return (target: object, propertyKey: string | symbol) => {\n const container = metadata(getConstructor(target)).custom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS,\n {},\n false\n );\n const datum = {\n factory: () => {\n if (\"number\" === typeof stamp) {\n return new Date(stamp);\n }\n if (!stamp) {\n return new Date();\n }\n return (Date as unknown as { fromString: (s: string) => Date }).fromString(stamp);\n },\n };\n container[propertyKey as string] = datum;\n };\n },\n};\n\nexport function getConstructor(target: unknown) {\n if (target && \"constructor\" in (target as object)) {\n return target.constructor;\n }\n throw new Error(`Cannot get constructor for ${target}`);\n}\n","const PROPERTY_DEFAULTS: unique symbol = Symbol(\"autometa:meta-data:property-defaults\");\nexport const DtoBuilderSymbols = {\n PROPERTY_DEFAULTS,\n} as const;\n","import { DefaultValueDecorators } from \"./dto-default.decorator\";\nimport type { Class } from \"./types\";\n\n/**\n *\n * @param defaultValue\n *\n * @deprecated Use `@DTO.value`, `@DTO.factory` and `@DTO.dto` instead\n */\nexport function Property<T extends () => unknown>(defaultValue: T): PropertyDecorator;\nexport function Property<T>(defaultValue: T): PropertyDecorator;\nexport function Property(defaultOrFactory: unknown | (() => unknown)): PropertyDecorator {\n return determineDefaultType(defaultOrFactory);\n}\nfunction determineDefaultType(\n defaultOrFactory: unknown | Class<unknown> | (() => unknown)\n): PropertyDecorator {\n if (isClass(defaultOrFactory)) {\n return DefaultValueDecorators.dto(defaultOrFactory);\n }\n\n if (\"function\" === typeof defaultOrFactory) {\n return DefaultValueDecorators.factory(defaultOrFactory as () => unknown);\n }\n\n if (defaultOrFactory instanceof Date.constructor) {\n return DefaultValueDecorators.date();\n }\n\n return DefaultValueDecorators.value(defaultOrFactory);\n}\n\nfunction isClass(value: unknown): value is Class<unknown> {\n if (!(\"function\" != typeof value)) {\n return false;\n }\n\n return /^class[\\s{]/.test(toString.call(value));\n}\n","import { DefaultValueDecorators, Default } from \"./dto-default.decorator\";\nimport { Class } from \"./types\";\n\nexport function DTOWrapper<T extends object>() {\n return class {} as Class<T>;\n}\n\nexport const DTO: typeof DTOWrapper & Default = Object.assign(DTOWrapper, DefaultValueDecorators);\n","import { metadata } from \"@autometa/injection\";\nimport { Class, PropertyMetadata } from \"./types\";\nimport { DtoBuilderSymbols } from \"./property.enum\";\nexport type IBuilder<T> = {\n [k in keyof T]-?: ((arg: T[k]) => IBuilder<T>) & (() => T[k]);\n} & {\n /**\n * Build the object and return it\n */\n build(): T;\n /**\n * Derive a new builder from the current builder, copying it's\n * current values into a new builder. Allows default values to\n * be set in a copy, which will not be modified by child copies.\n */\n derive(): IBuilder<T>;\n /**\n * Assign an arbitrary value to a property. The value\n * does not need to match a valid property for the interface\n * and can be used to introduce \"unexpected\" values for testing,\n * or coming from other object maps.\n * @param property the name of the property to set a value for\n * @param value the value to set\n */\n assign<K>(property: string, value: K): IBuilder<T>;\n /**\n * Append a value to an array property. If no array\n * has been defined one will be created. If one exists,\n * it will be reused.\n * @param property\n * @param value\n */\n append<K>(property: string, value: K): IBuilder<T>;\n\n /**\n * Attach a value to a sub-property of a property.\n * If the property does not exist, a new empty object will be\n * assigned to it.\n *\n * The value is appended to the child object indexed by the sub-property.\n * @param property The name of the property to attach key:value pairs to\n * @param subProperty The name of the sub-property to attach the value to\n * @param value The value to attach to the child objects property\n */\n attach<K>(property: string, subProperty: string, value: K): ClsBuilder<T>;\n};\nexport type ClsBuilder<T> = {\n [k in keyof T]-?: BuilderMethod<T, T[k]>;\n} & {\n /**\n * Build the object and return it\n */\n build(): T;\n /**\n * Assign an arbitrary value to a property. The value\n * does not need to match a valid property for the interface\n * and can be used to introduce \"unexpected\" values for testing,\n * or coming from other object maps.\n * @param property the name of the property to set a value for\n * @param value the value to set\n */\n assign<K>(property: string, value: K): ClsBuilder<T>;\n /**\n * Append a value to an array property. If no array\n * has been defined one will be created. If one exists,\n * it will be reused.\n * @param property\n * @param value\n */\n append<K>(property: string, value: K): ClsBuilder<T>;\n\n /**\n * Attach a value to a sub-property of a property.\n * If the property does not exist, a new empty object will be\n * assigned to it.\n *\n * The value is appended to the child object indexed by the sub-property.\n * @param property The name of the property to attach key:value pairs to\n * @param subProperty The name of the sub-property to attach the value to\n * @param value The value to attach to the child objects property\n */\n attach<K>(property: string, subProperty: string, value: K): ClsBuilder<T>;\n};\n\nexport type BuilderMethod<TTarget, TType> = ((arg: TType) => ClsBuilder<TTarget>) & {\n value: TType;\n};\nexport type DtoBuilder<T> = Class<ClsBuilder<T>> & {\n /**\n * Construct a builder from a raw object or class instance,\n * inheriting any properties that have already been defined.\n * @param value /\n */\n fromRaw(value: Partial<T>): ClsBuilder<T>;\n /**\n * Constructs a DTO, prefilled with any default values\n * assigned to the DTO via either the `Property` decorator\n * or the `DTO.*` decorators.\n *\n * With property:\n *\n * ```ts\n * class FooDto {\n * @Property(1)\n * foo: number;\n * @Property(()=> \"factory string\")\n * bar: string;\n * @Property(SomeDto)\n * baz: SomeDto;\n * }\n * ```\n *\n * With DTO:\n *\n * ```ts\n * class FooDto {\n * @DTO.value(1)\n * foo: number;\n * @DTO.factory(()=> \"factory string\")\n * bar: string;\n * @DTO.dto(SomeDto)\n * baz: SomeDto;\n * }\n * ```\n */\n default(): T;\n};\n\nexport function Builder<T>(cls: Class<T>): DtoBuilder<T>;\nexport function Builder<T>(): IBuilder<T>;\nexport function Builder<T>(defaults?: Partial<T> | Class<T>): IBuilder<T> | DtoBuilder<T> {\n if (isClassBuilder(defaults)) {\n return class BuilderClass<TType> {\n constructor() {\n const built: Record<string, unknown> = { ...defaults };\n const proxy = classProxy.bind(null, defaults as Class<unknown>, built);\n return proxy(this) as BuilderClass<TType>;\n }\n declare build: () => T;\n declare assign: <K>(property: string, value: K) => BuilderClass<TType>;\n static fromRaw(value: T) {\n const builder = new this();\n const keys = Object.keys(value as object) as (keyof T)[];\n for (const key of keys) {\n builder.assign(key.toString(), value[key]);\n }\n return builder;\n }\n\n static default() {\n return new this().build();\n }\n } as DtoBuilder<T>;\n // return clsBuilder as IBuilder<T>;\n }\n const built: Record<string, unknown> = { ...defaults };\n const builder = new Proxy(built, {\n get(target, prop) {\n if (\"build\" === prop) {\n return () => built;\n }\n\n if (\"derive\" === prop) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return () => Builder<T>({ ...built } as any);\n }\n\n if (\"assign\" === prop) {\n return (property: keyof T, value: unknown) => {\n built[property.toString()] = value;\n return target;\n };\n }\n\n if (\"attach\" === prop) {\n return (property: keyof T, subProperty: string, value: unknown) => {\n if (typeof built[property.toString()] === undefined) {\n built[property.toString()] = {};\n }\n const dict = built[property.toString()] as Record<string, unknown>;\n dict[subProperty] = value;\n return target;\n };\n }\n\n if (\"append\" === prop) {\n return (property: keyof T, value: unknown) => {\n if (!Array.isArray(built[property.toString()])) {\n built[property.toString()] = [value];\n } else {\n (built[property.toString()] as unknown[]).push(value);\n }\n return target;\n };\n }\n\n return (...args: unknown[]): unknown => {\n // If no arguments passed return current value.\n if (0 === args.length) {\n return built[prop.toString()];\n }\n\n built[prop.toString()] = args[0];\n return builder;\n };\n },\n });\n\n return builder as IBuilder<T>;\n}\n\nfunction classProxy<T>(defaults: Class<T>, built: Record<string, unknown>, inst: T) {\n const clsBuilder = new Proxy(inst as object, {\n get(_, prop) {\n if (\"build\" === prop) {\n return () => {\n const instance = constructDefaultDto(defaults);\n return Object.assign(instance as object, { ...built });\n };\n }\n if (\"assign\" === prop) {\n const fn = (property: keyof T, value: unknown) => {\n built[property.toString()] = value;\n return clsBuilder;\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return fn as any;\n }\n if (\"append\" === prop) {\n const fn = (property: keyof T, value: unknown) => {\n if (!Array.isArray(built[property.toString()])) {\n built[property.toString()] = [value];\n } else {\n (built[property.toString()] as unknown[]).push(value);\n }\n return clsBuilder;\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return fn as any;\n }\n if (\"attach\" === prop) {\n return (property: keyof T, subProperty: string, value: unknown) => {\n if (built[property.toString()] === undefined) {\n built[property.toString()] = {};\n }\n const dict = built[property.toString()] as Record<string, unknown>;\n dict[subProperty] = value;\n return clsBuilder;\n };\n }\n if (prop in (inst as Record<string, unknown>)) {\n return (inst as Record<string, unknown>)[prop as string];\n }\n const fn = (...args: unknown[]): unknown => {\n // If no arguments passed return current value.\n if (0 === args.length) {\n return built[prop.toString()];\n }\n built[prop.toString()] = args[0];\n return clsBuilder;\n };\n const modified = Object.defineProperty(fn, \"value\", {\n get() {\n return built[prop.toString()];\n },\n });\n return modified;\n },\n });\n return clsBuilder as ClsBuilder<T>;\n}\n\nfunction isClassBuilder<T>(cls: unknown): cls is Class<T> {\n return \"function\" === typeof cls;\n}\n\nfunction constructDefaultDto<T>(base: Class<T>): T {\n const defaultSetters = metadata(base).getCustom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS\n );\n const instance = new base();\n if (!defaultSetters) {\n return instance;\n }\n const keys = Object.keys(defaultSetters) as unknown as (keyof typeof instance)[] &\n (keyof typeof defaultSetters)[];\n\n for (const key of keys) {\n const value = defaultSetters[key];\n if (\"value\" in value) {\n Object.defineProperty(instance as object, key, {\n value: value.value,\n writable: true,\n enumerable: true,\n });\n }\n if (\"factory\" in value) {\n Object.defineProperty(instance as object, key, {\n value: value.factory(),\n writable: true,\n enumerable: true,\n });\n }\n if (\"dtoType\" in value) {\n const dtoInst = constructDefaultDto(value.dtoType);\n Object.defineProperty(instance as object, key, {\n value: dtoInst,\n writable: true,\n enumerable: true,\n });\n }\n }\n return instance;\n}\n"],"mappings":"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","names":["metadata","built","builder","fn","metadata"]} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../src/index.ts","../src/dto-default.decorator.ts","../src/property.enum.ts","../src/property.decorator.ts","../src/dto.ts","../src/interface-proxy.ts"],"sourcesContent":["export { Property } from './property.decorator'\nexport { DTO } from './dto'\nexport { Builder, DtoBuilder, ClsBuilder } from './interface-proxy'","import { metadata } from \"@autometa/injection\";\nimport { DtoBuilderSymbols } from \"./property.enum\";\nimport { Class, PropertyMetadata } from \"./types\";\nimport \"any-date-parser\";\n\nexport interface Default {\n value(value: unknown): PropertyDecorator;\n\n factory(factory: (...args: unknown[]) => unknown): PropertyDecorator;\n\n dto(dtoType: Class<unknown>): PropertyDecorator;\n\n date(): PropertyDecorator;\n date(format: string): PropertyDecorator;\n date(stamp: number): PropertyDecorator;\n date(stamp?: string | number): PropertyDecorator;\n}\n\nexport const DefaultValueDecorators: Default = {\n value: (value: unknown) => (target: object, propertyKey: string | symbol) => {\n const container = metadata(getConstructor(target)).custom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS,\n {},\n false\n );\n const datum = { value };\n container[propertyKey as string] = datum;\n },\n factory:\n (factory: (...args: unknown[]) => unknown) =>\n (target: object, propertyKey: string | symbol) => {\n const container = metadata(getConstructor(target)).custom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS,\n {},\n false\n );\n const datum = { factory };\n container[propertyKey as string] = datum;\n },\n dto: (dtoType: Class<unknown>) => (target: object, propertyKey: string | symbol) => {\n const container = metadata(getConstructor(target)).custom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS,\n {},\n false\n );\n const datum = { dtoType };\n container[propertyKey as string] = datum;\n },\n date: (stamp?: string | number | undefined) => {\n return (target: object, propertyKey: string | symbol) => {\n const container = metadata(getConstructor(target)).custom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS,\n {},\n false\n );\n const datum = {\n factory: () => {\n if (\"number\" === typeof stamp) {\n return new Date(stamp);\n }\n if (!stamp) {\n return new Date();\n }\n return (Date as unknown as { fromString: (s: string) => Date }).fromString(stamp);\n },\n };\n container[propertyKey as string] = datum;\n };\n },\n};\n\nexport function getConstructor(target: unknown) {\n if (target && \"constructor\" in (target as object)) {\n return target.constructor;\n }\n throw new Error(`Cannot get constructor for ${target}`);\n}","const PROPERTY_DEFAULTS: unique symbol = Symbol(\"autometa:meta-data:property-defaults\");\nexport const DtoBuilderSymbols = {\n PROPERTY_DEFAULTS,\n} as const;\n","import { DefaultValueDecorators } from \"./dto-default.decorator\";\nimport type { Class } from \"./types\";\n\n/**\n * \n * @param defaultValue \n * \n * @deprecated Use `@DTO.value`, `@DTO.factory` and `@DTO.dto` instead\n */\nexport function Property<T extends () => unknown>(defaultValue: T): PropertyDecorator;\nexport function Property<T>(defaultValue: T): PropertyDecorator;\nexport function Property(defaultOrFactory: unknown | (() => unknown)): PropertyDecorator {\n return determineDefaultType(defaultOrFactory);\n}\nfunction determineDefaultType(defaultOrFactory: unknown | Class<unknown> | (() => unknown)): PropertyDecorator {\n if (isClass(defaultOrFactory)) {\n return DefaultValueDecorators.dto(defaultOrFactory);\n }\n\n if (\"function\" === typeof defaultOrFactory) {\n return DefaultValueDecorators.factory(defaultOrFactory as () => unknown);\n }\n\n if (defaultOrFactory instanceof Date.constructor) {\n return DefaultValueDecorators.date();\n }\n\n return DefaultValueDecorators.value(defaultOrFactory);\n}\n\nfunction isClass(value: unknown): value is Class<unknown> {\n if (!(\"function\" != typeof value)) {\n return false;\n }\n\n return /^class[\\s{]/.test(toString.call(value));\n}\n","import { DefaultValueDecorators, Default } from \"./dto-default.decorator\";\nimport { Class } from \"./types\";\n\nexport function DTOWrapper<T extends object>() {\n return class {} as Class<T>;\n}\n\nexport const DTO: typeof DTOWrapper & Default = Object.assign(DTOWrapper, DefaultValueDecorators);\n","import { metadata } from \"@autometa/injection\";\nimport { Class, PropertyMetadata } from \"./types\";\nimport { DtoBuilderSymbols } from \"./property.enum\";\nexport type IBuilder<T> = {\n [k in keyof T]-?: ((arg: T[k]) => IBuilder<T>) & (() => T[k]);\n} & {\n /**\n * Build the object and return it\n */\n build(): T;\n /**\n * Derive a new builder from the current builder, copying it's\n * current values into a new builder. Allows default values to\n * be set in a copy, which will not be modified by child copies.\n */\n derive(): IBuilder<T>;\n /**\n * Assign an arbitrary value to a property. The value\n * does not need to match a valid property for the interface\n * and can be used to introduce \"unexpected\" values for testing,\n * or coming from other object maps.\n * @param property the name of the property to set a value for\n * @param value the value to set\n */\n assign<K>(property: string, value: K): IBuilder<T>;\n /**\n * Append a value to an array property. If no array\n * has been defined one will be created. If one exists,\n * it will be reused.\n * @param property\n * @param value\n */\n append<K>(property: string, value: K): IBuilder<T>;\n\n /**\n * Attach a value to a sub-property of a property.\n * If the property does not exist, a new empty object will be\n * assigned to it.\n *\n * The value is appended to the child object indexed by the sub-property.\n * @param property The name of the property to attach key:value pairs to\n * @param subProperty The name of the sub-property to attach the value to\n * @param value The value to attach to the child objects property\n */\n attach<K>(property: string, subProperty: string, value: K): ClsBuilder<T>;\n};\nexport type ClsBuilder<T> = {\n [k in keyof T]-?: BuilderMethod<T, T[k]>;\n} & {\n /**\n * Build the object and return it\n */\n build(): T;\n /**\n * Assign an arbitrary value to a property. The value\n * does not need to match a valid property for the interface\n * and can be used to introduce \"unexpected\" values for testing,\n * or coming from other object maps.\n * @param property the name of the property to set a value for\n * @param value the value to set\n */\n assign<K>(property: string, value: K): ClsBuilder<T>;\n /**\n * Append a value to an array property. If no array\n * has been defined one will be created. If one exists,\n * it will be reused.\n * @param property\n * @param value\n */\n append<K>(property: string, value: K): ClsBuilder<T>;\n\n /**\n * Attach a value to a sub-property of a property.\n * If the property does not exist, a new empty object will be\n * assigned to it.\n *\n * The value is appended to the child object indexed by the sub-property.\n * @param property The name of the property to attach key:value pairs to\n * @param subProperty The name of the sub-property to attach the value to\n * @param value The value to attach to the child objects property\n */\n attach<K>(property: string, subProperty: string, value: K): ClsBuilder<T>;\n};\n\nexport type BuilderMethod<TTarget, TType> = ((arg: TType) => ClsBuilder<TTarget>) & {\n value: TType;\n};\nexport type DtoBuilder<T> = Class<ClsBuilder<T>> & {\n /**\n * Construct a builder from a raw object or class instance,\n * inheriting any properties that have already been defined.\n * @param value /\n */\n fromRaw(value: Partial<T>): ClsBuilder<T>;\n /**\n * Constructs a DTO, prefilled with any default values\n * assigned to the DTO via either the `Property` decorator\n * or the `DTO.*` decorators.\n *\n * With property:\n *\n * ```ts\n * class FooDto {\n * @Property(1)\n * foo: number;\n * @Property(()=> \"factory string\")\n * bar: string;\n * @Property(SomeDto)\n * baz: SomeDto;\n * }\n * ```\n *\n * With DTO:\n *\n * ```ts\n * class FooDto {\n * @DTO.value(1)\n * foo: number;\n * @DTO.factory(()=> \"factory string\")\n * bar: string;\n * @DTO.dto(SomeDto)\n * baz: SomeDto;\n * }\n * ```\n */\n default(): T;\n};\n\nexport function Builder<T>(cls: Class<T>): DtoBuilder<T>;\nexport function Builder<T>(): IBuilder<T>;\nexport function Builder<T>(defaults?: Partial<T> | Class<T>): IBuilder<T> | DtoBuilder<T> {\n if (isClassBuilder(defaults)) {\n return class BuilderClass<TType> {\n constructor() {\n const built: Record<string, unknown> = { ...defaults };\n const proxy = classProxy.bind(null, defaults as Class<unknown>, built);\n return proxy(this) as BuilderClass<TType>;\n }\n declare build: () => T;\n declare assign: <K>(property: string, value: K) => BuilderClass<TType>;\n static fromRaw(value: T) {\n const builder = new this();\n const keys = Object.keys(value as object) as (keyof T)[];\n for (const key of keys) {\n builder.assign(key.toString(), value[key]);\n }\n return builder;\n }\n\n static default() {\n return new this().build();\n }\n } as DtoBuilder<T>;\n // return clsBuilder as IBuilder<T>;\n }\n const built: Record<string, unknown> = { ...defaults };\n const builder = new Proxy(built, {\n get(target, prop) {\n if (\"build\" === prop) {\n return () => built;\n }\n\n if (\"derive\" === prop) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return () => Builder<T>({ ...built } as any);\n }\n\n if (\"assign\" === prop) {\n return (property: keyof T, value: unknown) => {\n built[property.toString()] = value;\n return target;\n };\n }\n\n if (\"attach\" === prop) {\n return (property: keyof T, subProperty: string, value: unknown) => {\n if (typeof built[property.toString()] === undefined) {\n built[property.toString()] = {};\n }\n const dict = built[property.toString()] as Record<string, unknown>;\n dict[subProperty] = value;\n return target;\n };\n }\n\n if (\"append\" === prop) {\n return (property: keyof T, value: unknown) => {\n if (!Array.isArray(built[property.toString()])) {\n built[property.toString()] = [value];\n } else {\n (built[property.toString()] as unknown[]).push(value);\n }\n return target;\n };\n }\n\n return (...args: unknown[]): unknown => {\n // If no arguments passed return current value.\n if (0 === args.length) {\n return built[prop.toString()];\n }\n\n built[prop.toString()] = args[0];\n return builder;\n };\n },\n });\n\n return builder as IBuilder<T>;\n}\n\nfunction classProxy<T>(defaults: Class<T>, built: Record<string, unknown>, inst: T) {\n const clsBuilder = new Proxy(inst as object, {\n get(_, prop) {\n if (\"build\" === prop) {\n return () => {\n const instance = constructDefaultDto(defaults);\n return Object.assign(instance as object, { ...built });\n };\n }\n if (\"assign\" === prop) {\n const fn = (property: keyof T, value: unknown) => {\n built[property.toString()] = value;\n return clsBuilder;\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return fn as any;\n }\n if (\"append\" === prop) {\n const fn = (property: keyof T, value: unknown) => {\n if (!Array.isArray(built[property.toString()])) {\n built[property.toString()] = [value];\n } else {\n (built[property.toString()] as unknown[]).push(value);\n }\n return clsBuilder;\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return fn as any;\n }\n if (\"attach\" === prop) {\n return (property: keyof T, subProperty: string, value: unknown) => {\n if (built[property.toString()] === undefined) {\n built[property.toString()] = {};\n }\n const dict = built[property.toString()] as Record<string, unknown>;\n dict[subProperty] = value;\n return clsBuilder;\n };\n }\n if (prop in (inst as Record<string, unknown>)) {\n return (inst as Record<string, unknown>)[prop as string];\n }\n const fn = (...args: unknown[]): unknown => {\n // If no arguments passed return current value.\n if (0 === args.length) {\n return built[prop.toString()];\n }\n built[prop.toString()] = args[0];\n return clsBuilder;\n };\n const modified = Object.defineProperty(fn, \"value\", {\n get() {\n return built[prop.toString()];\n },\n });\n return modified;\n },\n });\n return clsBuilder as ClsBuilder<T>;\n}\n\nfunction isClassBuilder<T>(cls: unknown): cls is Class<T> {\n return \"function\" === typeof cls;\n}\n\nfunction constructDefaultDto<T>(base: Class<T>): T {\n const defaultSetters = metadata(base).getCustom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS\n );\n const instance = new base();\n if (!defaultSetters) {\n return instance;\n }\n const keys = Object.keys(defaultSetters) as unknown as (keyof typeof instance)[] &\n (keyof typeof defaultSetters)[];\n\n for (const key of keys) {\n const value = defaultSetters[key];\n if (\"value\" in value) {\n Object.defineProperty(instance as object, key, {\n value: value.value,\n writable: true,\n enumerable: true,\n });\n }\n if (\"factory\" in value) {\n Object.defineProperty(instance as object, key, {\n value: value.factory(),\n writable: true,\n enumerable: true,\n });\n }\n if (\"dtoType\" in value) {\n const dtoInst = constructDefaultDto(value.dtoType);\n Object.defineProperty(instance as object, key, {\n value: dtoInst,\n writable: true,\n enumerable: true,\n });\n }\n }\n return instance;\n}\n"],"mappings":"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","names":["import_injection","built","builder","fn"]} | ||
| {"version":3,"sources":["../src/index.ts","../src/dto-default.decorator.ts","../src/property.enum.ts","../src/property.decorator.ts","../src/dto.ts","../src/interface-proxy.ts"],"sourcesContent":["export { Property } from \"./property.decorator\";\nexport { DTO } from \"./dto\";\nexport { Builder, DtoBuilder, ClsBuilder } from \"./interface-proxy\";\n","import { metadata } from \"@autometa/injection\";\nimport { DtoBuilderSymbols } from \"./property.enum\";\nimport { Class, PropertyMetadata } from \"./types\";\nimport \"any-date-parser\";\n\nexport interface Default {\n value(value: unknown): PropertyDecorator;\n\n factory(factory: (...args: unknown[]) => unknown): PropertyDecorator;\n\n dto(dtoType: Class<unknown>): PropertyDecorator;\n\n date(): PropertyDecorator;\n date(format: string): PropertyDecorator;\n date(stamp: number): PropertyDecorator;\n date(stamp?: string | number): PropertyDecorator;\n}\n\nexport const DefaultValueDecorators: Default = {\n value: (value: unknown) => (target: object, propertyKey: string | symbol) => {\n const container = metadata(getConstructor(target)).custom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS,\n {},\n false\n );\n const datum = { value };\n container[propertyKey as string] = datum;\n },\n factory:\n (factory: (...args: unknown[]) => unknown) =>\n (target: object, propertyKey: string | symbol) => {\n const container = metadata(getConstructor(target)).custom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS,\n {},\n false\n );\n const datum = { factory };\n container[propertyKey as string] = datum;\n },\n dto: (dtoType: Class<unknown>) => (target: object, propertyKey: string | symbol) => {\n const container = metadata(getConstructor(target)).custom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS,\n {},\n false\n );\n const datum = { dtoType };\n container[propertyKey as string] = datum;\n },\n date: (stamp?: string | number | undefined) => {\n return (target: object, propertyKey: string | symbol) => {\n const container = metadata(getConstructor(target)).custom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS,\n {},\n false\n );\n const datum = {\n factory: () => {\n if (\"number\" === typeof stamp) {\n return new Date(stamp);\n }\n if (!stamp) {\n return new Date();\n }\n return (Date as unknown as { fromString: (s: string) => Date }).fromString(stamp);\n },\n };\n container[propertyKey as string] = datum;\n };\n },\n};\n\nexport function getConstructor(target: unknown) {\n if (target && \"constructor\" in (target as object)) {\n return target.constructor;\n }\n throw new Error(`Cannot get constructor for ${target}`);\n}\n","const PROPERTY_DEFAULTS: unique symbol = Symbol(\"autometa:meta-data:property-defaults\");\nexport const DtoBuilderSymbols = {\n PROPERTY_DEFAULTS,\n} as const;\n","import { DefaultValueDecorators } from \"./dto-default.decorator\";\nimport type { Class } from \"./types\";\n\n/**\n *\n * @param defaultValue\n *\n * @deprecated Use `@DTO.value`, `@DTO.factory` and `@DTO.dto` instead\n */\nexport function Property<T extends () => unknown>(defaultValue: T): PropertyDecorator;\nexport function Property<T>(defaultValue: T): PropertyDecorator;\nexport function Property(defaultOrFactory: unknown | (() => unknown)): PropertyDecorator {\n return determineDefaultType(defaultOrFactory);\n}\nfunction determineDefaultType(\n defaultOrFactory: unknown | Class<unknown> | (() => unknown)\n): PropertyDecorator {\n if (isClass(defaultOrFactory)) {\n return DefaultValueDecorators.dto(defaultOrFactory);\n }\n\n if (\"function\" === typeof defaultOrFactory) {\n return DefaultValueDecorators.factory(defaultOrFactory as () => unknown);\n }\n\n if (defaultOrFactory instanceof Date.constructor) {\n return DefaultValueDecorators.date();\n }\n\n return DefaultValueDecorators.value(defaultOrFactory);\n}\n\nfunction isClass(value: unknown): value is Class<unknown> {\n if (!(\"function\" != typeof value)) {\n return false;\n }\n\n return /^class[\\s{]/.test(toString.call(value));\n}\n","import { DefaultValueDecorators, Default } from \"./dto-default.decorator\";\nimport { Class } from \"./types\";\n\nexport function DTOWrapper<T extends object>() {\n return class {} as Class<T>;\n}\n\nexport const DTO: typeof DTOWrapper & Default = Object.assign(DTOWrapper, DefaultValueDecorators);\n","import { metadata } from \"@autometa/injection\";\nimport { Class, PropertyMetadata } from \"./types\";\nimport { DtoBuilderSymbols } from \"./property.enum\";\nexport type IBuilder<T> = {\n [k in keyof T]-?: ((arg: T[k]) => IBuilder<T>) & (() => T[k]);\n} & {\n /**\n * Build the object and return it\n */\n build(): T;\n /**\n * Derive a new builder from the current builder, copying it's\n * current values into a new builder. Allows default values to\n * be set in a copy, which will not be modified by child copies.\n */\n derive(): IBuilder<T>;\n /**\n * Assign an arbitrary value to a property. The value\n * does not need to match a valid property for the interface\n * and can be used to introduce \"unexpected\" values for testing,\n * or coming from other object maps.\n * @param property the name of the property to set a value for\n * @param value the value to set\n */\n assign<K>(property: string, value: K): IBuilder<T>;\n /**\n * Append a value to an array property. If no array\n * has been defined one will be created. If one exists,\n * it will be reused.\n * @param property\n * @param value\n */\n append<K>(property: string, value: K): IBuilder<T>;\n\n /**\n * Attach a value to a sub-property of a property.\n * If the property does not exist, a new empty object will be\n * assigned to it.\n *\n * The value is appended to the child object indexed by the sub-property.\n * @param property The name of the property to attach key:value pairs to\n * @param subProperty The name of the sub-property to attach the value to\n * @param value The value to attach to the child objects property\n */\n attach<K>(property: string, subProperty: string, value: K): ClsBuilder<T>;\n};\nexport type ClsBuilder<T> = {\n [k in keyof T]-?: BuilderMethod<T, T[k]>;\n} & {\n /**\n * Build the object and return it\n */\n build(): T;\n /**\n * Assign an arbitrary value to a property. The value\n * does not need to match a valid property for the interface\n * and can be used to introduce \"unexpected\" values for testing,\n * or coming from other object maps.\n * @param property the name of the property to set a value for\n * @param value the value to set\n */\n assign<K>(property: string, value: K): ClsBuilder<T>;\n /**\n * Append a value to an array property. If no array\n * has been defined one will be created. If one exists,\n * it will be reused.\n * @param property\n * @param value\n */\n append<K>(property: string, value: K): ClsBuilder<T>;\n\n /**\n * Attach a value to a sub-property of a property.\n * If the property does not exist, a new empty object will be\n * assigned to it.\n *\n * The value is appended to the child object indexed by the sub-property.\n * @param property The name of the property to attach key:value pairs to\n * @param subProperty The name of the sub-property to attach the value to\n * @param value The value to attach to the child objects property\n */\n attach<K>(property: string, subProperty: string, value: K): ClsBuilder<T>;\n};\n\nexport type BuilderMethod<TTarget, TType> = ((arg: TType) => ClsBuilder<TTarget>) & {\n value: TType;\n};\nexport type DtoBuilder<T> = Class<ClsBuilder<T>> & {\n /**\n * Construct a builder from a raw object or class instance,\n * inheriting any properties that have already been defined.\n * @param value /\n */\n fromRaw(value: Partial<T>): ClsBuilder<T>;\n /**\n * Constructs a DTO, prefilled with any default values\n * assigned to the DTO via either the `Property` decorator\n * or the `DTO.*` decorators.\n *\n * With property:\n *\n * ```ts\n * class FooDto {\n * @Property(1)\n * foo: number;\n * @Property(()=> \"factory string\")\n * bar: string;\n * @Property(SomeDto)\n * baz: SomeDto;\n * }\n * ```\n *\n * With DTO:\n *\n * ```ts\n * class FooDto {\n * @DTO.value(1)\n * foo: number;\n * @DTO.factory(()=> \"factory string\")\n * bar: string;\n * @DTO.dto(SomeDto)\n * baz: SomeDto;\n * }\n * ```\n */\n default(): T;\n};\n\nexport function Builder<T>(cls: Class<T>): DtoBuilder<T>;\nexport function Builder<T>(): IBuilder<T>;\nexport function Builder<T>(defaults?: Partial<T> | Class<T>): IBuilder<T> | DtoBuilder<T> {\n if (isClassBuilder(defaults)) {\n return class BuilderClass<TType> {\n constructor() {\n const built: Record<string, unknown> = { ...defaults };\n const proxy = classProxy.bind(null, defaults as Class<unknown>, built);\n return proxy(this) as BuilderClass<TType>;\n }\n declare build: () => T;\n declare assign: <K>(property: string, value: K) => BuilderClass<TType>;\n static fromRaw(value: T) {\n const builder = new this();\n const keys = Object.keys(value as object) as (keyof T)[];\n for (const key of keys) {\n builder.assign(key.toString(), value[key]);\n }\n return builder;\n }\n\n static default() {\n return new this().build();\n }\n } as DtoBuilder<T>;\n // return clsBuilder as IBuilder<T>;\n }\n const built: Record<string, unknown> = { ...defaults };\n const builder = new Proxy(built, {\n get(target, prop) {\n if (\"build\" === prop) {\n return () => built;\n }\n\n if (\"derive\" === prop) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return () => Builder<T>({ ...built } as any);\n }\n\n if (\"assign\" === prop) {\n return (property: keyof T, value: unknown) => {\n built[property.toString()] = value;\n return target;\n };\n }\n\n if (\"attach\" === prop) {\n return (property: keyof T, subProperty: string, value: unknown) => {\n if (typeof built[property.toString()] === undefined) {\n built[property.toString()] = {};\n }\n const dict = built[property.toString()] as Record<string, unknown>;\n dict[subProperty] = value;\n return target;\n };\n }\n\n if (\"append\" === prop) {\n return (property: keyof T, value: unknown) => {\n if (!Array.isArray(built[property.toString()])) {\n built[property.toString()] = [value];\n } else {\n (built[property.toString()] as unknown[]).push(value);\n }\n return target;\n };\n }\n\n return (...args: unknown[]): unknown => {\n // If no arguments passed return current value.\n if (0 === args.length) {\n return built[prop.toString()];\n }\n\n built[prop.toString()] = args[0];\n return builder;\n };\n },\n });\n\n return builder as IBuilder<T>;\n}\n\nfunction classProxy<T>(defaults: Class<T>, built: Record<string, unknown>, inst: T) {\n const clsBuilder = new Proxy(inst as object, {\n get(_, prop) {\n if (\"build\" === prop) {\n return () => {\n const instance = constructDefaultDto(defaults);\n return Object.assign(instance as object, { ...built });\n };\n }\n if (\"assign\" === prop) {\n const fn = (property: keyof T, value: unknown) => {\n built[property.toString()] = value;\n return clsBuilder;\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return fn as any;\n }\n if (\"append\" === prop) {\n const fn = (property: keyof T, value: unknown) => {\n if (!Array.isArray(built[property.toString()])) {\n built[property.toString()] = [value];\n } else {\n (built[property.toString()] as unknown[]).push(value);\n }\n return clsBuilder;\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return fn as any;\n }\n if (\"attach\" === prop) {\n return (property: keyof T, subProperty: string, value: unknown) => {\n if (built[property.toString()] === undefined) {\n built[property.toString()] = {};\n }\n const dict = built[property.toString()] as Record<string, unknown>;\n dict[subProperty] = value;\n return clsBuilder;\n };\n }\n if (prop in (inst as Record<string, unknown>)) {\n return (inst as Record<string, unknown>)[prop as string];\n }\n const fn = (...args: unknown[]): unknown => {\n // If no arguments passed return current value.\n if (0 === args.length) {\n return built[prop.toString()];\n }\n built[prop.toString()] = args[0];\n return clsBuilder;\n };\n const modified = Object.defineProperty(fn, \"value\", {\n get() {\n return built[prop.toString()];\n },\n });\n return modified;\n },\n });\n return clsBuilder as ClsBuilder<T>;\n}\n\nfunction isClassBuilder<T>(cls: unknown): cls is Class<T> {\n return \"function\" === typeof cls;\n}\n\nfunction constructDefaultDto<T>(base: Class<T>): T {\n const defaultSetters = metadata(base).getCustom<PropertyMetadata>(\n DtoBuilderSymbols.PROPERTY_DEFAULTS\n );\n const instance = new base();\n if (!defaultSetters) {\n return instance;\n }\n const keys = Object.keys(defaultSetters) as unknown as (keyof typeof instance)[] &\n (keyof typeof defaultSetters)[];\n\n for (const key of keys) {\n const value = defaultSetters[key];\n if (\"value\" in value) {\n Object.defineProperty(instance as object, key, {\n value: value.value,\n writable: true,\n enumerable: true,\n });\n }\n if (\"factory\" in value) {\n Object.defineProperty(instance as object, key, {\n value: value.factory(),\n writable: true,\n enumerable: true,\n });\n }\n if (\"dtoType\" in value) {\n const dtoInst = constructDefaultDto(value.dtoType);\n Object.defineProperty(instance as object, key, {\n value: dtoInst,\n writable: true,\n enumerable: true,\n });\n }\n }\n return instance;\n}\n"],"mappings":"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","names":["import_injection","built","builder","fn"]} |
+9
-9
| { | ||
| "name": "@autometa/dto-builder", | ||
| "version": "0.13.9", | ||
| "version": "0.13.10", | ||
| "description": "Define DTOs and Entities and automatically create a builder class.", | ||
@@ -39,5 +39,5 @@ "type": "module", | ||
| "@typescript-eslint/parser": "^5.54.1", | ||
| "@vitest/coverage-istanbul": "^0.31.0", | ||
| "@vitest/coverage-istanbul": "^1.4.0", | ||
| "@vitest/coverage-v8": "^1.4.0", | ||
| "eslint": "^8.37.0", | ||
| "eslint-config-custom": "0.6.0", | ||
| "istanbul": "^0.4.5", | ||
@@ -48,12 +48,13 @@ "node": "^19.6.0", | ||
| "rimraf": "^4.1.2", | ||
| "tsconfig": " *", | ||
| "tsup": "^7.2.0", | ||
| "typescript": "^4.9.5", | ||
| "vitest": "0.34.6" | ||
| "vitest": "1.4.0", | ||
| "eslint-config-custom": "0.6.0", | ||
| "tsconfig": "0.7.0" | ||
| }, | ||
| "dependencies": { | ||
| "@autometa/injection": "^0.1.3", | ||
| "any-date-parser": "^1.5.4", | ||
| "class-validator": "^0.14.0", | ||
| "closest-match": "^1.3.3" | ||
| "closest-match": "^1.3.3", | ||
| "@autometa/injection": "^0.1.4" | ||
| }, | ||
@@ -69,4 +70,3 @@ "scripts": { | ||
| "build:watch": "tsup --watch" | ||
| }, | ||
| "readme": "# DTO and Builder Pattern\n\n[Full documentation](https://bendat.github.io/autometa/docs/libraries/dto-builder/intro)\nThis library allows defining DTO classes with decoratated properties.\nYou an then automatically create a new builder class that incrementally\nassigns the value of the DTO, and returns the built result.\n\n:::caution\nThis library requires experimental decorators and a reflect polyfill\nlike [reflect-metadata](https://www.npmjs.com/package/reflect-metadata)\n:::\n\n## Installation\n\n```sh title=npm\n npm i -D @autometa/dto-builder\n```\n\n```sh title=yarn\n yarn add -D @autometa/dto-builder\n```\n\n```sh title=pnpm\n pnpm add -D @autometa/dto-builder\n```\n\n## Use\n\n### Creating a DTO\n\nTo create a DTO, simply create a class which matches the data type your\nrepresenting. Then, decorate its properties with the `@Property` decorator.\n\n```ts\nimport { Property } from \"@autometa/dto-builder\";\n\nexport class UserDto {\n @Property\n id: number;\n @Property\n name: string;\n @Property\n age: number;\n}\n```\n\n### Creating a builder\n\nNow that we have a DTO, we can make a builder for it. Simply pass\nyour DTO class prototype to the `Builder` function. It will return a new\nclass whos interface matches the DTO, but with functions accepting a value\ninstead of raw properties.\n\nThe builder functions are compile-time type safe but do no\nrun time validation.\n\nIf the `class validator` package is installed, the DTO will be validated on build. This can be bypassed by passing `false` to the build method\n\n```ts\nimport { Builder } from \"@autometa/dto-builder\";\nimport { UserDto } from \"./user-dto\";\n\nclass UserBuilder extends Builder(UserDto);\n\nconst userBuilder = new UserBuilder();\nuserBuilder.id(1).name(\"bob\").age(23);\n// methods are type safe\n// -------------\n// error |\n// V\nuserBuilder.id(\"1\").name(\"bob\").age(23);\n\n// Bypass\nuserBuilder\n .id(\"1\" as unknown as number)\n .name(\"bob\")\n .age(23);\n```\n\nYou can also pass in an already existing DTO and build it\nfurther.\n\n```ts\nconst cachedUser = new UserDto();\nconst userBuilder = new UserBuilder(cachedUser);\n```\n\n# Default Values\n\nYou can pass a value into the Property decorator to provide a default value.\nThe default value will be injected by the Builder class.\n\n```ts\nimport { DTO } from \"@autometa/dto-builder\";\n\nexport class UserDto {\n @DTO.value(100)\n id: number;\n @DTO.value(\"paul\")\n name: string;\n @DTO.value(20)\n age: number;\n}\n\nconst user = new UserBuilder().build();\n\nconsole.log(user.id === 100); // true\nconsole.log(user.name === \"paul\"); // true\nconsole.log(user.age === 20); // true\n```\n\nFactories can also be used:\n\n```ts\nimport { Property } from \"@autometa/dto-builder\";\n\nexport class UserDto {\n @DTO.factory(() => Math.random())\n id: number;\n @DTO.factory(() => \"paul\")\n name: string;\n @DTO.factory(() => 20)\n age: number;\n}\n```\n\nNote: factories must by synchronous.\n\n## Nesting DTOs\n\nFor complex classes with nested classes or objects it is advisable to use a type\nor interface rather than a Dto type.\n\n```ts\n// prefer not\nclass InnerDto {\n value: number;\n}\n\nclass OuterDto {\n @DTO.dto(InnerDto)\n inner: InnerDto;\n}\n\n// prefer\ninterface Inner {\n value: number;\n}\n\nclass InnerDto implements Inner {\n value: number;\n}\n\nclass OuterDto {\n @DTO.dto(InnerDto)\n inner: Inner;\n}\n```\n\nTo make a DTO available for nesting, pass its prototype to the Property decorator\nas its default value. Note, this is the prototype, not an instance.\n\n```ts\n\n// prefer\ninterface Inner {\n value: number\n}\n\nclass InnerDto {\n @DTO.value(1)\n value: number;\n}\n\nclass OuterDto {\n @DTO.value(InnerDto)\n inner: Inner;\n}\n\nconst Outer = new OuterBuilder().build()\nconsole.log(outer.inner instanceOf InnerDto); // true\nconsole.log(outer.innerr.value === 1); // true\n```\n\nYou can also create a unique dto with default values by calling the static `default`\nmethod on your builder\n\n```ts\nconst Outer = OuterBuilder.default();\n```\n\nFor many tests, valid default values may be all you need on your dto. If\nyou wish to make further edits you can pass the instance to a builder later\n\n```ts\nnew OuterBuilder(Outer).inner(new InnerBuilder().value(1).build());\n```\n\nNote that this will mutate the original dto. You do not need to reassign it or\neven `build` it.\n\n## Dates\n\nThe `date` decorator will create a new date object for that property\nwhen the builder is instantiated. If a unix timestamp or parseable\nstring is passed, it will be used to create the date.\n\n```ts\nimport { DTO } from \"@autometa/dto-builder\";\n\nexport class UserDto {\n @DTO.date\n createdAt: Date;\n}\n\n// with unix timestamp\n\nexport class UserDto {\n @DTO.date(1620000000000)\n createdAt: Date;\n}\n\n// with string\n\nexport class UserDto {\n @DTO.date(\"2021-05-02T00:00:00.000Z\")\n createdAt: Date;\n}\n```\n\n## Interfaces - reducing duplication\n\nIf you define your types initially as interfaces, or generate interfaces from\nvalidation libraries like `zod` and `myzod`, you can reduce duplication by\nextending the `DTO` function with an interface.\n\n```ts\nimport { DTO } from \"@autometa/dto-builder\";\n\ninterface IUser {\n id: number;\n name: string;\n age: number;\n}\n\nexport class UserDto extends DTO<IUser> {}\n\nconst user = new UserBuilder().id(0).name(\"bob\").build();\n```\n\n# DTO From Raw Object\n\nSometimes it's necessary to convert a raw object into a DTO. This can be achieved by\ncalling `fromRaw` on the Builder class, passing it the raw object.\n\n```ts\nconst raw = { Outer: { inner: { value: 1 } } };\nconst dto = OuterBuilder.fromRaw(raw);\n\nexpect(dto).toBeInstanceOf(Outer);\n```\n\n## Interfaces - Anonymous Object Builders\n\nIt might not be desirable to build your object as a class. When not used\nto extend a class, the `DTO` function will return an anonymous object builder,\nwith the same interface as the class builder.\n\n```ts\nimport { Builder } from \"@autometa/dto-builder\";\n\ninterface IUser {\n id: number;\n name: string;\n age: number;\n}\n\nconst UserBuilder = Builder<IUser>();\n```\n\n### Deriving a builder and default values\n\nSince anonymous objects cannot be decorated, they cannot\naccept default values or factories which might change between\ninstantiations.\n\nTo work around this, an anonymous builder is `derivable`. Any values\nassigned to the builder will stay until the builder is built. However\nwhen the `derive` method is called, a new builder will be created,\ncopying the values from the original. If those values are set agin\nin the derived builder, they will not affect the original.\n\n```ts\n\nconst bobBuilder = new UserBuilder().id(1).name(\"bob\").age(23);\n\nconst olderBobBuilder = bobBuilder.derive().age(24);\n```" | ||
| } | ||
| } |
+1
-2
@@ -294,6 +294,5 @@ # DTO and Builder Pattern | ||
| ```ts | ||
| const bobBuilder = new UserBuilder().id(1).name("bob").age(23); | ||
| const olderBobBuilder = bobBuilder.derive().age(24); | ||
| ``` | ||
| ``` |
73836
-8.51%18
5.88%Updated