Skip to content

Commit a2369a9

Browse files
committed
feat: Add toJSObject, toClassObject, and morph function decorators 🎉
1 parent 1c3c2f6 commit a2369a9

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

‎src/morphism.ts

+55-1
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ function getSchemaForType<T>(type: Constructable<T>, baseSchema: Schema<T>): Sch
275275
const result = morphism(schema, data, Foo);
276276
// result is type of Foo
277277
* ```
278-
* @param {Schema} schema Configuration schema to compute data source properties
278+
* @param {Schema} schema Structure-preserving object from a source data towards a target data
279279
* @param {} items Object or Collection to be mapped
280280
* @param {} type
281281
*
@@ -476,6 +476,60 @@ export class MorphismRegistry implements IMorphismRegistry {
476476
}
477477
}
478478

479+
function decorator<Target>(mapper: Mapper<Target>) {
480+
return (target: any, name: string, descriptor: PropertyDescriptor) => {
481+
const fn = descriptor.value;
482+
if (typeof fn === 'function') {
483+
descriptor.value = function(...args: any[]) {
484+
const output = fn.apply(this, args);
485+
if (isPromise(output)) {
486+
return Promise.resolve(output).then(res => mapper(res));
487+
}
488+
return mapper(output);
489+
};
490+
}
491+
492+
return descriptor;
493+
};
494+
}
495+
function isPromise(object: any) {
496+
if (Promise && Promise.resolve) {
497+
return Promise.resolve(object) == object;
498+
} else {
499+
throw 'Promise not supported in your environment';
500+
}
501+
}
502+
503+
/**
504+
* Function Decorator transforming the return value of the targeted Function using the provided Schema and/or Type
505+
*
506+
* @param {Schema<Target>} schema Structure-preserving object from a source data towards a target data
507+
* @param {Constructable<Target>} [type] Target Class Type
508+
*/
509+
export function morph<Target>(schema: Schema<Target>, type?: Constructable<Target>) {
510+
const mapper = transformItems(schema, type);
511+
return decorator(mapper);
512+
}
513+
/**
514+
* Function Decorator transforming the return value of the targeted Function to JS Object(s) using the provided Schema
515+
*
516+
* @param {StrictSchema<Target>} schema Structure-preserving object from a source data towards a target data
517+
*/
518+
export function toJSObject<Target>(schema: StrictSchema<Target>) {
519+
const mapper = transformItems(schema);
520+
return decorator(mapper);
521+
}
522+
/**
523+
* Function Decorator transforming the return value of the targeted Function using the provided Schema and Class Type
524+
*
525+
* @param {Schema<Target>} schema Structure-preserving object from a source data towards a target data
526+
* @param {Constructable<Target>} [type] Target Class Type
527+
*/
528+
export function toClassObject<Target>(schema: Schema<Target>, type: Constructable<Target>) {
529+
const mapper = transformItems(schema, type);
530+
return decorator(mapper);
531+
}
532+
479533
const morphismRegistry = new MorphismRegistry();
480534
const morphismMixin: typeof morphism & any = morphism;
481535
morphismMixin.register = (t: any, s: any) => morphismRegistry.register(t, s);

0 commit comments

Comments
 (0)