Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

class-transformer

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

class-transformer - npm Package Compare versions

Comparing version 0.1.0-beta.4 to 0.1.0-beta.5

metadata/TransformMetadata.d.ts

12

ClassTransformer.js

@@ -8,23 +8,23 @@ "use strict";

var executor = new TransformOperationExecutor_1.TransformOperationExecutor("classToPlain", options || {});
return executor.transform(undefined, object, undefined, undefined);
return executor.transform(undefined, object, undefined, undefined, undefined);
};
ClassTransformer.prototype.classToPlainFromExist = function (object, plainObject, options) {
var executor = new TransformOperationExecutor_1.TransformOperationExecutor("classToPlain", options || {});
return executor.transform(plainObject, object, undefined, undefined);
return executor.transform(plainObject, object, undefined, undefined, undefined);
};
ClassTransformer.prototype.plainToClass = function (cls, plain, options) {
var executor = new TransformOperationExecutor_1.TransformOperationExecutor("plainToClass", options || {});
return executor.transform(undefined, plain, cls, undefined);
return executor.transform(undefined, plain, cls, undefined, undefined);
};
ClassTransformer.prototype.plainToClassFromExist = function (clsObject, plain, options) {
var executor = new TransformOperationExecutor_1.TransformOperationExecutor("plainToClass", options || {});
return executor.transform(clsObject, plain, undefined, undefined);
return executor.transform(clsObject, plain, undefined, undefined, undefined);
};
ClassTransformer.prototype.classToClass = function (object, options) {
var executor = new TransformOperationExecutor_1.TransformOperationExecutor("classToClass", options || {});
return executor.transform(undefined, object, undefined, undefined);
return executor.transform(undefined, object, undefined, undefined, undefined);
};
ClassTransformer.prototype.classToClassFromExist = function (object, fromObject, options) {
var executor = new TransformOperationExecutor_1.TransformOperationExecutor("classToClass", options || {});
return executor.transform(fromObject, object, undefined, undefined);
return executor.transform(fromObject, object, undefined, undefined, undefined);
};

@@ -31,0 +31,0 @@ ClassTransformer.prototype.serialize = function (object, options) {

@@ -1,11 +0,10 @@

import { ExposeOptions, ExcludeOptions } from "./metadata/ExposeExcludeOptions";
export interface TypeTransformOptions {
newObject: any;
object: Object;
property: string;
}
import { ExposeOptions, ExcludeOptions, TypeOptions, TransformOptions } from "./metadata/ExposeExcludeOptions";
/**
* Defines a custom logic for value transformation.
*/
export declare function Transform(transformFn: (value: any) => any, options?: TransformOptions): (target: any, key: string) => void;
/**
* Specifies a type of the property.
*/
export declare function Type(typeFunction?: (type?: TypeTransformOptions) => Function): (target: any, key: string) => void;
export declare function Type(typeFunction?: (type?: TypeOptions) => Function): (target: any, key: string) => void;
/**

@@ -12,0 +11,0 @@ * Marks property as included in the process of transformation. By default it includes the property for both

@@ -6,3 +6,14 @@ "use strict";

var ExcludeMetadata_1 = require("./metadata/ExcludeMetadata");
var TransformMetadata_1 = require("./metadata/TransformMetadata");
/**
* Defines a custom logic for value transformation.
*/
function Transform(transformFn, options) {
return function (target, key) {
var metadata = new TransformMetadata_1.TransformMetadata(target.constructor, key, transformFn, options);
index_1.defaultMetadataStorage.addTransformMetadata(metadata);
};
}
exports.Transform = Transform;
/**
* Specifies a type of the property.

@@ -13,4 +24,3 @@ */

var type = Reflect.getMetadata("design:type", target, key);
var isArray = type && typeof type === "string" ? type.toLowerCase() === "array" : false;
var metadata = new TypeMetadata_1.TypeMetadata(target.constructor, key, type, typeFunction, isArray);
var metadata = new TypeMetadata_1.TypeMetadata(target.constructor, key, type, typeFunction);
index_1.defaultMetadataStorage.addTypeMetadata(metadata);

@@ -17,0 +27,0 @@ };

@@ -6,2 +6,3 @@ import { ClassType } from "./ClassTransformer";

export { ClassTransformOptions } from "./ClassTransformOptions";
export * from "./metadata/ExposeExcludeOptions";
export * from "./decorators";

@@ -8,0 +9,0 @@ /**

@@ -0,1 +1,13 @@

export interface TransformOptions {
since?: number;
until?: number;
groups?: string[];
toClassOnly?: boolean;
toPlainOnly?: boolean;
}
export interface TypeOptions {
newObject: any;
object: Object;
property: string;
}
export interface ExposeOptions {

@@ -2,0 +14,0 @@ name?: string;

@@ -5,2 +5,3 @@ import { TypeMetadata } from "./TypeMetadata";

import { TransformationType } from "../TransformOperationExecutor";
import { TransformMetadata } from "./TransformMetadata";
/**

@@ -11,7 +12,10 @@ * Storage all library metadata.

private _typeMetadatas;
private _transformMetadatas;
private _exposeMetadatas;
private _excludeMetadatas;
addTypeMetadata(metadata: TypeMetadata): void;
addTransformMetadata(metadata: TransformMetadata): void;
addExposeMetadata(metadata: ExposeMetadata): void;
addExcludeMetadata(metadata: ExcludeMetadata): void;
findTransformMetadatas(target: Function, propertyName: string, transformationType: TransformationType): TransformMetadata[];
findExcludeMetadata(target: Function, propertyName: string): ExcludeMetadata;

@@ -29,2 +33,3 @@ findExposeMetadata(target: Function, propertyName: string): ExposeMetadata;

private findMetadata<T>(metadatas, target, propertyName);
private findMetadatas<T>(metadatas, target, propertyName);
}

@@ -11,2 +11,3 @@ "use strict";

this._typeMetadatas = [];
this._transformMetadatas = [];
this._exposeMetadatas = [];

@@ -21,2 +22,5 @@ this._excludeMetadatas = [];

};
MetadataStorage.prototype.addTransformMetadata = function (metadata) {
this._transformMetadatas.push(metadata);
};
MetadataStorage.prototype.addExposeMetadata = function (metadata) {

@@ -31,2 +35,18 @@ this._exposeMetadatas.push(metadata);

// -------------------------------------------------------------------------
MetadataStorage.prototype.findTransformMetadatas = function (target, propertyName, transformationType) {
return this.findMetadatas(this._transformMetadatas, target, propertyName)
.filter(function (metadata) {
if (!metadata.options)
return true;
if (metadata.options.toClassOnly === true && metadata.options.toPlainOnly === true)
return true;
if (metadata.options.toClassOnly === true) {
return transformationType === "classToClass" || transformationType === "plainToClass";
}
if (metadata.options.toPlainOnly === true) {
return transformationType === "classToPlain";
}
return true;
});
};
MetadataStorage.prototype.findExcludeMetadata = function (target, propertyName) {

@@ -111,2 +131,7 @@ return this.findMetadata(this._excludeMetadatas, target, propertyName);

};
MetadataStorage.prototype.findMetadatas = function (metadatas, target, propertyName) {
var metadataFromTarget = metadatas.filter(function (meta) { return meta.target === target && meta.propertyName === propertyName; });
var metadataFromChildren = metadatas.filter(function (meta) { return target.prototype instanceof meta.target && meta.propertyName === propertyName; });
return metadataFromChildren.reverse().concat(metadataFromTarget.reverse());
};
return MetadataStorage;

@@ -113,0 +138,0 @@ }());

@@ -0,1 +1,2 @@

import { TypeOptions } from "./ExposeExcludeOptions";
export declare class TypeMetadata {

@@ -5,5 +6,4 @@ target: Function;

reflectedType: any;
typeFunction: (object?: Object) => Function;
isArray: boolean;
constructor(target: Function, propertyName: string, reflectedType: any, typeFunction: (object?: Object) => Function, isArray: boolean);
typeFunction: (options?: TypeOptions) => Function;
constructor(target: Function, propertyName: string, reflectedType: any, typeFunction: (options?: TypeOptions) => Function);
}
"use strict";
var TypeMetadata = (function () {
function TypeMetadata(target, propertyName, reflectedType, typeFunction, isArray) {
function TypeMetadata(target, propertyName, reflectedType, typeFunction) {
this.target = target;

@@ -8,3 +8,2 @@ this.propertyName = propertyName;

this.typeFunction = typeFunction;
this.isArray = isArray;
}

@@ -11,0 +10,0 @@ return TypeMetadata;

{
"name": "class-transformer",
"version": "0.1.0-beta.4",
"version": "0.1.0-beta.5",
"description": "Proper decorator-based transformation / serialization / deserialization of plain javascript objects to class constructors",

@@ -43,2 +43,3 @@ "license": "MIT",

"mocha": "^2.5.3",
"moment": "^2.14.1",
"reflect-metadata": "^0.1.3",

@@ -45,0 +46,0 @@ "remap-istanbul": "^0.6.4",

@@ -517,2 +517,33 @@ # class-transformer

### Additional data transformation
You can perform additional data transformation using `@Transform` decorator.
For example, you want to make your `Date` object to be a `moment` object when you are
transforming object from plain to class:
```javascript
import {Transform} from "class-transformer";
import * as moment from "moment";
import {Moment} from "moment";
export class Photo {
id: number;
@Transform(value => moment(value), { toClassOnly: true })
date: Moment;
}
```
Now when you call `plainToClass` and send a plain representation of the Photo object,
it will convert a date value in your photo object to moment date.
`@Transform` decorator also supports groups and versioning.
### Working with generics
Generics are not supported because TypeScript does not have good reflection abilities.
Once TypeScript team provide us better runtime type reelection tools, generics will be implemented.
There are some tweaks however you can use, that maybe can solve your problem.
[Checkout this example.](https://github.com/pleerock/class-transformer/tree/master/sample/sample4-generics)
### How does it handle circular references?

@@ -519,0 +550,0 @@

@@ -8,3 +8,4 @@ import { ClassTransformOptions } from "./ClassTransformOptions";

constructor(transformationType: TransformationType, options: ClassTransformOptions);
transform(source: Object | Object[] | any, value: Object | Object[] | any, targetType: Function, arrayType: Function, level?: number): any;
transform(source: Object | Object[] | any, value: Object | Object[] | any, targetType: Function, arrayType: Function, fromProperty: string, level?: number): any;
private applyCustomTransformations(value, target, key);
private isCircular(object, level);

@@ -14,2 +15,4 @@ private getKeyType(newObject, object, target, key);

private getKeys(target, object);
private checkVersion(since, until);
private checkGroups(groups);
}

@@ -18,3 +18,3 @@ "use strict";

// -------------------------------------------------------------------------
TransformOperationExecutor.prototype.transform = function (source, value, targetType, arrayType, level) {
TransformOperationExecutor.prototype.transform = function (source, value, targetType, arrayType, fromProperty, level) {
var _this = this;

@@ -27,3 +27,3 @@ if (level === void 0) { level = 0; }

if (!_this.isCircular(subValue, level)) {
newValue_1.push(_this.transform(subSource, subValue, targetType, undefined, level + 1));
newValue_1.push(_this.transform(subSource, subValue, targetType, undefined, String(index), level + 1));
}

@@ -62,2 +62,4 @@ else if (_this.transformationType === "classToClass") {

if (!source && (this.transformationType === "plainToClass" || this.transformationType === "classToClass")) {
if (!targetType)
throw new Error("Cannot determine type for " + targetType.name + "." + fromProperty + ", did you forget to specify a @Type?");
newValue = new targetType();

@@ -102,6 +104,8 @@ }

if (!this.isCircular(subValue, level)) {
newValue[newValueKey] = this.transform(subSource, subValue, type, arrayType_1, level + 1);
newValue[newValueKey] = this.transform(subSource, subValue, type, arrayType_1, propertyName, level + 1);
newValue[newValueKey] = this.applyCustomTransformations(newValue[newValueKey], targetType, key);
}
else if (this.transformationType === "classToClass") {
newValue[newValueKey] = subValue;
newValue[newValueKey] = this.applyCustomTransformations(newValue[newValueKey], targetType, key);
}

@@ -115,2 +119,33 @@ }

};
TransformOperationExecutor.prototype.applyCustomTransformations = function (value, target, key) {
var _this = this;
var metadatas = index_1.defaultMetadataStorage.findTransformMetadatas(target, key, this.transformationType);
// apply versioning options
if (this.options.version !== undefined) {
metadatas = metadatas.filter(function (metadata) {
if (!metadata.options)
return true;
return _this.checkVersion(metadata.options.since, metadata.options.until);
});
}
// apply grouping options
if (this.options.groups && this.options.groups.length) {
metadatas = metadatas.filter(function (metadata) {
if (!metadata.options)
return true;
return _this.checkGroups(metadata.options.groups);
});
}
else {
metadatas = metadatas.filter(function (metadata) {
return !metadata.options ||
!metadata.options.groups ||
!metadata.options.groups.length;
});
}
metadatas.forEach(function (metadata) {
value = metadata.transformFn(value);
});
return value;
};
// preventing circular references

@@ -124,3 +159,4 @@ TransformOperationExecutor.prototype.isCircular = function (object, level) {

var metadata = index_1.defaultMetadataStorage.findTypeMetadata(target, key);
return metadata ? metadata.typeFunction({ newObject: newObject, transformingObject: object, property: key }) : undefined;
var options = { newObject: newObject, object: object, property: key };
return metadata ? metadata.typeFunction(options) : undefined;
};

@@ -167,8 +203,3 @@ TransformOperationExecutor.prototype.getReflectedType = function (target, propertyName) {

return true;
var decision = true;
if (decision && exposeMetadata.options.since)
decision = _this.options.version >= exposeMetadata.options.since;
if (decision && exposeMetadata.options.until)
decision = _this.options.version < exposeMetadata.options.until;
return decision;
return _this.checkVersion(exposeMetadata.options.since, exposeMetadata.options.until);
});

@@ -180,5 +211,5 @@ }

var exposeMetadata = index_1.defaultMetadataStorage.findExposeMetadata(target, key);
if (!exposeMetadata || !exposeMetadata.options || !exposeMetadata.options.groups)
if (!exposeMetadata || !exposeMetadata.options)
return true;
return _this.options.groups.some(function (optionGroup) { return exposeMetadata.options.groups.indexOf(optionGroup) !== -1; });
return _this.checkGroups(exposeMetadata.options.groups);
});

@@ -208,2 +239,15 @@ }

};
TransformOperationExecutor.prototype.checkVersion = function (since, until) {
var decision = true;
if (decision && since)
decision = this.options.version >= since;
if (decision && until)
decision = this.options.version < until;
return decision;
};
TransformOperationExecutor.prototype.checkGroups = function (groups) {
if (!groups)
return true;
return this.options.groups.some(function (optionGroup) { return groups.indexOf(optionGroup) !== -1; });
};
return TransformOperationExecutor;

@@ -210,0 +254,0 @@ }());

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc