🎯 MapView v2.0 - Global Deployment Ready

 MAJOR FEATURES:
• Auto-zoom intelligence với smart bounds fitting
• Enhanced 3D GPS markers với pulsing effects
• Professional route display với 6-layer rendering
• Status-based parking icons với availability indicators
• Production-ready build optimizations

🗺️ AUTO-ZOOM FEATURES:
• Smart bounds fitting cho GPS + selected parking
• Adaptive padding (50px) cho visual balance
• Max zoom control (level 16) để tránh quá gần
• Dynamic centering khi không có selection

🎨 ENHANCED VISUALS:
• 3D GPS marker với multi-layer pulse effects
• Advanced parking icons với status colors
• Selection highlighting với animation
• Dimming system cho non-selected items

🛣️ ROUTE SYSTEM:
• OpenRouteService API integration
• Multi-layer route rendering (glow, shadow, main, animated)
• Real-time distance & duration calculation
• Visual route info trong popup

📱 PRODUCTION READY:
• SSR safe với dynamic imports
• Build errors resolved
• Global deployment via Vercel
• Optimized performance

🌍 DEPLOYMENT:
• Vercel: https://whatever-ctk2auuxr-phong12hexdockworks-projects.vercel.app
• Bundle size: 22.8 kB optimized
• Global CDN distribution
• HTTPS enabled

💾 VERSION CONTROL:
• MapView-v2.0.tsx backup created
• MAPVIEW_VERSIONS.md documentation
• Full version history tracking
This commit is contained in:
2025-07-20 19:52:16 +07:00
parent 3203463a6a
commit c65cc97a33
64624 changed files with 7199453 additions and 6462 deletions

21
backend/node_modules/class-transformer/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License
Copyright (c) 2015-2020 TypeStack
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

901
backend/node_modules/class-transformer/README.md generated vendored Normal file
View File

@@ -0,0 +1,901 @@
# class-transformer
![Build Status](https://github.com/typestack/class-transformer/workflows/CI/badge.svg)
[![codecov](https://codecov.io/gh/typestack/class-transformer/branch/develop/graph/badge.svg)](https://codecov.io/gh/typestack/class-transformer)
[![npm version](https://badge.fury.io/js/class-transformer.svg)](https://badge.fury.io/js/class-transformer)
Its ES6 and Typescript era. Nowadays you are working with classes and constructor objects more than ever.
Class-transformer allows you to transform plain object to some instance of class and versa.
Also it allows to serialize / deserialize object based on criteria.
This tool is super useful on both frontend and backend.
Example how to use with angular 2 in [plunker](http://plnkr.co/edit/Mja1ZYAjVySWASMHVB9R).
Source code is available [here](https://github.com/pleerock/class-transformer-demo).
## Table of contents
- [What is class-transformer](#what-is-class-transformer)
- [Installation](#installation)
- [Node.js](#nodejs)
- [Browser](#browser)
- [Methods](#methods)
- [plainToClass](#plaintoclass)
- [plainToClassFromExist](#plaintoclassfromexist)
- [classToPlain](#classtoplain)
- [classToClass](#classtoclass)
- [serialize](#serialize)
- [deserialize and deserializeArray](#deserialize-and-deserializearray)
- [Enforcing type-safe instance](#enforcing-type-safe-instance)
- [Working with nested objects](#working-with-nested-objects)
- [Providing more than one type option](#providing-more-than-one-type-option)
- [Exposing getters and method return values](#exposing-getters-and-method-return-values)
- [Exposing properties with different names](#exposing-properties-with-different-names)
- [Skipping specific properties](#skipping-specific-properties)
- [Skipping depend of operation](#skipping-depend-of-operation)
- [Skipping all properties of the class](#skipping-all-properties-of-the-class)
- [Skipping private properties, or some prefixed properties](#skipping-private-properties-or-some-prefixed-properties)
- [Using groups to control excluded properties](#using-groups-to-control-excluded-properties)
- [Using versioning to control exposed and excluded properties](#using-versioning-to-control-exposed-and-excluded-properties)
- [Сonverting date strings into Date objects](#сonverting-date-strings-into-date-objects)
- [Working with arrays](#working-with-arrays)
- [Additional data transformation](#additional-data-transformation)
- [Basic usage](#basic-usage)
- [Advanced usage](#advanced-usage)
- [Other decorators](#other-decorators)
- [Working with generics](#working-with-generics)
- [Implicit type conversion](#implicit-type-conversion)
- [How does it handle circular references?](#how-does-it-handle-circular-references)
- [Example with Angular2](#example-with-angular2)
- [Samples](#samples)
- [Release notes](#release-notes)
## What is class-transformer[⬆](#table-of-contents)
In JavaScript there are two types of objects:
- plain (literal) objects
- class (constructor) objects
Plain objects are objects that are instances of `Object` class.
Sometimes they are called **literal** objects, when created via `{}` notation.
Class objects are instances of classes with own defined constructor, properties and methods.
Usually you define them via `class` notation.
So, what is the problem?
Sometimes you want to transform plain javascript object to the ES6 **classes** you have.
For example, if you are loading a json from your backend, some api or from a json file,
and after you `JSON.parse` it you have a plain javascript object, not instance of class you have.
For example you have a list of users in your `users.json` that you are loading:
```json
[
{
"id": 1,
"firstName": "Johny",
"lastName": "Cage",
"age": 27
},
{
"id": 2,
"firstName": "Ismoil",
"lastName": "Somoni",
"age": 50
},
{
"id": 3,
"firstName": "Luke",
"lastName": "Dacascos",
"age": 12
}
]
```
And you have a `User` class:
```typescript
export class User {
id: number;
firstName: string;
lastName: string;
age: number;
getName() {
return this.firstName + ' ' + this.lastName;
}
isAdult() {
return this.age > 36 && this.age < 60;
}
}
```
You are assuming that you are downloading users of type `User` from `users.json` file and may want to write
following code:
```typescript
fetch('users.json').then((users: User[]) => {
// you can use users here, and type hinting also will be available to you,
// but users are not actually instances of User class
// this means that you can't use methods of User class
});
```
In this code you can use `users[0].id`, you can also use `users[0].firstName` and `users[0].lastName`.
However you cannot use `users[0].getName()` or `users[0].isAdult()` because "users" actually is
array of plain javascript objects, not instances of User object.
You actually lied to compiler when you said that its `users: User[]`.
So what to do? How to make a `users` array of instances of `User` objects instead of plain javascript objects?
Solution is to create new instances of User object and manually copy all properties to new objects.
But things may go wrong very fast once you have a more complex object hierarchy.
Alternatives? Yes, you can use class-transformer. Purpose of this library is to help you to map your plain javascript
objects to the instances of classes you have.
This library also great for models exposed in your APIs,
because it provides a great tooling to control what your models are exposing in your API.
Here is an example how it will look like:
```typescript
fetch('users.json').then((users: Object[]) => {
const realUsers = plainToClass(User, users);
// now each user in realUsers is an instance of User class
});
```
Now you can use `users[0].getName()` and `users[0].isAdult()` methods.
## Installation[⬆](#table-of-contents)
### Node.js[⬆](#table-of-contents)
1. Install module:
`npm install class-transformer --save`
2. `reflect-metadata` shim is required, install it too:
`npm install reflect-metadata --save`
and make sure to import it in a global place, like app.ts:
```typescript
import 'reflect-metadata';
```
3. ES6 features are used, if you are using old version of node.js you may need to install es6-shim:
`npm install es6-shim --save`
and import it in a global place like app.ts:
```typescript
import 'es6-shim';
```
### Browser[⬆](#table-of-contents)
1. Install module:
`npm install class-transformer --save`
2. `reflect-metadata` shim is required, install it too:
`npm install reflect-metadata --save`
add `<script>` to reflect-metadata in the head of your `index.html`:
```html
<html>
<head>
<!-- ... -->
<script src="node_modules/reflect-metadata/Reflect.js"></script>
</head>
<!-- ... -->
</html>
```
If you are using angular 2 you should already have this shim installed.
3. If you are using system.js you may want to add this into `map` and `package` config:
```json
{
"map": {
"class-transformer": "node_modules/class-transformer"
},
"packages": {
"class-transformer": { "main": "index.js", "defaultExtension": "js" }
}
}
```
## Methods[⬆](#table-of-contents)
### plainToClass[⬆](#table-of-contents)
This method transforms a plain javascript object to instance of specific class.
```typescript
import { plainToClass } from 'class-transformer';
let users = plainToClass(User, userJson); // to convert user plain object a single user. also supports arrays
```
### plainToClassFromExist[⬆](#table-of-contents)
This method transforms a plain object into an instance using an already filled Object which is an instance of the target class.
```typescript
const defaultUser = new User();
defaultUser.role = 'user';
let mixedUser = plainToClassFromExist(defaultUser, user); // mixed user should have the value role = user when no value is set otherwise.
```
### classToPlain[⬆](#table-of-contents)
This method transforms your class object back to plain javascript object, that can be `JSON.stringify` later.
```typescript
import { classToPlain } from 'class-transformer';
let photo = classToPlain(photo);
```
### classToClass[⬆](#table-of-contents)
This method transforms your class object into a new instance of the class object.
This may be treated as deep clone of your objects.
```typescript
import { classToClass } from 'class-transformer';
let photo = classToClass(photo);
```
You can also use an `ignoreDecorators` option in transformation options to ignore all decorators you classes is using.
### serialize[⬆](#table-of-contents)
You can serialize your model right to json using `serialize` method:
```typescript
import { serialize } from 'class-transformer';
let photo = serialize(photo);
```
`serialize` works with both arrays and non-arrays.
### deserialize and deserializeArray[⬆](#table-of-contents)
You can deserialize your model from json using the `deserialize` method:
```typescript
import { deserialize } from 'class-transformer';
let photo = deserialize(Photo, photo);
```
To make deserialization work with arrays, use the `deserializeArray` method:
```typescript
import { deserializeArray } from 'class-transformer';
let photos = deserializeArray(Photo, photos);
```
## Enforcing type-safe instance[⬆](#table-of-contents)
The default behaviour of the `plainToClass` method is to set _all_ properties from the plain object,
even those which are not specified in the class.
```typescript
import { plainToClass } from 'class-transformer';
class User {
id: number;
firstName: string;
lastName: string;
}
const fromPlainUser = {
unkownProp: 'hello there',
firstName: 'Umed',
lastName: 'Khudoiberdiev',
};
console.log(plainToClass(User, fromPlainUser));
// User {
// unkownProp: 'hello there',
// firstName: 'Umed',
// lastName: 'Khudoiberdiev',
// }
```
If this behaviour does not suit your needs, you can use the `excludeExtraneousValues` option
in the `plainToClass` method while _exposing all your class properties_ as a requirement.
```typescript
import { Expose, plainToClass } from 'class-transformer';
class User {
@Expose() id: number;
@Expose() firstName: string;
@Expose() lastName: string;
}
const fromPlainUser = {
unkownProp: 'hello there',
firstName: 'Umed',
lastName: 'Khudoiberdiev',
};
console.log(plainToClass(User, fromPlainUser, { excludeExtraneousValues: true }));
// User {
// id: undefined,
// firstName: 'Umed',
// lastName: 'Khudoiberdiev'
// }
```
## Working with nested objects[⬆](#table-of-contents)
When you are trying to transform objects that have nested objects,
it's required to known what type of object you are trying to transform.
Since Typescript does not have good reflection abilities yet,
we should implicitly specify what type of object each property contain.
This is done using `@Type` decorator.
Lets say we have an album with photos.
And we are trying to convert album plain object to class object:
```typescript
import { Type, plainToClass } from 'class-transformer';
export class Album {
id: number;
name: string;
@Type(() => Photo)
photos: Photo[];
}
export class Photo {
id: number;
filename: string;
}
let album = plainToClass(Album, albumJson);
// now album is Album object with Photo objects inside
```
### Providing more than one type option[⬆](#table-of-contents)
In case the nested object can be of different types, you can provide an additional options object,
that specifies a discriminator. The discriminator option must define a `property` that holds the subtype
name for the object and the possible `subTypes` that the nested object can converted to. A sub type
has a `value`, that holds the constructor of the Type and the `name`, that can match with the `property`
of the discriminator.
Lets say we have an album that has a top photo. But this photo can be of certain different types.
And we are trying to convert album plain object to class object. The plain object input has to define
the additional property `__type`. This property is removed during transformation by default:
**JSON input**:
```json
{
"id": 1,
"name": "foo",
"topPhoto": {
"id": 9,
"filename": "cool_wale.jpg",
"depth": 1245,
"__type": "underwater"
}
}
```
```typescript
import { Type, plainToClass } from 'class-transformer';
export abstract class Photo {
id: number;
filename: string;
}
export class Landscape extends Photo {
panorama: boolean;
}
export class Portrait extends Photo {
person: Person;
}
export class UnderWater extends Photo {
depth: number;
}
export class Album {
id: number;
name: string;
@Type(() => Photo, {
discriminator: {
property: '__type',
subTypes: [
{ value: Landscape, name: 'landscape' },
{ value: Portrait, name: 'portrait' },
{ value: UnderWater, name: 'underwater' },
],
},
})
topPhoto: Landscape | Portrait | UnderWater;
}
let album = plainToClass(Album, albumJson);
// now album is Album object with a UnderWater object without `__type` property.
```
Hint: The same applies for arrays with different sub types. Moreover you can specify `keepDiscriminatorProperty: true`
in the options to keep the discriminator property also inside your resulting class.
## Exposing getters and method return values[⬆](#table-of-contents)
You can expose what your getter or method return by setting an `@Expose()` decorator to those getters or methods:
```typescript
import { Expose } from 'class-transformer';
export class User {
id: number;
firstName: string;
lastName: string;
password: string;
@Expose()
get name() {
return this.firstName + ' ' + this.lastName;
}
@Expose()
getFullName() {
return this.firstName + ' ' + this.lastName;
}
}
```
## Exposing properties with different names[⬆](#table-of-contents)
If you want to expose some of the properties with a different name,
you can do that by specifying a `name` option to `@Expose` decorator:
```typescript
import { Expose } from 'class-transformer';
export class User {
@Expose({ name: 'uid' })
id: number;
firstName: string;
lastName: string;
@Expose({ name: 'secretKey' })
password: string;
@Expose({ name: 'fullName' })
getFullName() {
return this.firstName + ' ' + this.lastName;
}
}
```
## Skipping specific properties[⬆](#table-of-contents)
Sometimes you want to skip some properties during transformation.
This can be done using `@Exclude` decorator:
```typescript
import { Exclude } from 'class-transformer';
export class User {
id: number;
email: string;
@Exclude()
password: string;
}
```
Now when you transform a User, the `password` property will be skipped and not be included in the transformed result.
## Skipping depend of operation[⬆](#table-of-contents)
You can control on what operation you will exclude a property. Use `toClassOnly` or `toPlainOnly` options:
```typescript
import { Exclude } from 'class-transformer';
export class User {
id: number;
email: string;
@Exclude({ toPlainOnly: true })
password: string;
}
```
Now `password` property will be excluded only during `classToPlain` operation. Vice versa, use the `toClassOnly` option.
## Skipping all properties of the class[⬆](#table-of-contents)
You can skip all properties of the class, and expose only those are needed explicitly:
```typescript
import { Exclude, Expose } from 'class-transformer';
@Exclude()
export class User {
@Expose()
id: number;
@Expose()
email: string;
password: string;
}
```
Now `id` and `email` will be exposed, and password will be excluded during transformation.
Alternatively, you can set exclusion strategy during transformation:
```typescript
import { classToPlain } from 'class-transformer';
let photo = classToPlain(photo, { strategy: 'excludeAll' });
```
In this case you don't need to `@Exclude()` a whole class.
## Skipping private properties, or some prefixed properties[⬆](#table-of-contents)
If you name your private properties with a prefix, lets say with `_`,
then you can exclude such properties from transformation too:
```typescript
import { classToPlain } from 'class-transformer';
let photo = classToPlain(photo, { excludePrefixes: ['_'] });
```
This will skip all properties that start with `_` prefix.
You can pass any number of prefixes and all properties that begin with these prefixes will be ignored.
For example:
```typescript
import { Expose, classToPlain } from 'class-transformer';
export class User {
id: number;
private _firstName: string;
private _lastName: string;
_password: string;
setName(firstName: string, lastName: string) {
this._firstName = firstName;
this._lastName = lastName;
}
@Expose()
get name() {
return this._firstName + ' ' + this._lastName;
}
}
const user = new User();
user.id = 1;
user.setName('Johny', 'Cage');
user._password = '123';
const plainUser = classToPlain(user, { excludePrefixes: ['_'] });
// here plainUser will be equal to
// { id: 1, name: "Johny Cage" }
```
## Using groups to control excluded properties[⬆](#table-of-contents)
You can use groups to control what data will be exposed and what will not be:
```typescript
import { Exclude, Expose, classToPlain } from 'class-transformer';
export class User {
id: number;
name: string;
@Expose({ groups: ['user', 'admin'] }) // this means that this data will be exposed only to users and admins
email: string;
@Expose({ groups: ['user'] }) // this means that this data will be exposed only to users
password: string;
}
let user1 = classToPlain(user, { groups: ['user'] }); // will contain id, name, email and password
let user2 = classToPlain(user, { groups: ['admin'] }); // will contain id, name and email
```
## Using versioning to control exposed and excluded properties[⬆](#table-of-contents)
If you are building an API that has different versions, class-transformer has extremely useful tools for that.
You can control which properties of your model should be exposed or excluded in what version. Example:
```typescript
import { Exclude, Expose, classToPlain } from 'class-transformer';
export class User {
id: number;
name: string;
@Expose({ since: 0.7, until: 1 }) // this means that this property will be exposed for version starting from 0.7 until 1
email: string;
@Expose({ since: 2.1 }) // this means that this property will be exposed for version starting from 2.1
password: string;
}
let user1 = classToPlain(user, { version: 0.5 }); // will contain id and name
let user2 = classToPlain(user, { version: 0.7 }); // will contain id, name and email
let user3 = classToPlain(user, { version: 1 }); // will contain id and name
let user4 = classToPlain(user, { version: 2 }); // will contain id and name
let user5 = classToPlain(user, { version: 2.1 }); // will contain id, name and password
```
## Сonverting date strings into Date objects[⬆](#table-of-contents)
Sometimes you have a Date in your plain javascript object received in a string format.
And you want to create a real javascript Date object from it.
You can do it simply by passing a Date object to the `@Type` decorator:
```typescript
import { Type } from 'class-transformer';
export class User {
id: number;
email: string;
password: string;
@Type(() => Date)
registrationDate: Date;
}
```
Same technique can be used with `Number`, `String`, `Boolean`
primitive types when you want to convert your values into these types.
## Working with arrays[⬆](#table-of-contents)
When you are using arrays you must provide a type of the object that array contains.
This type, you specify in a `@Type()` decorator:
```typescript
import { Type } from 'class-transformer';
export class Photo {
id: number;
name: string;
@Type(() => Album)
albums: Album[];
}
```
You can also use custom array types:
```typescript
import { Type } from 'class-transformer';
export class AlbumCollection extends Array<Album> {
// custom array functions ...
}
export class Photo {
id: number;
name: string;
@Type(() => Album)
albums: AlbumCollection;
}
```
Library will handle proper transformation automatically.
ES6 collections `Set` and `Map` also require the `@Type` decorator:
```typescript
export class Skill {
name: string;
}
export class Weapon {
name: string;
range: number;
}
export class Player {
name: string;
@Type(() => Skill)
skills: Set<Skill>;
@Type(() => Weapon)
weapons: Map<string, Weapon>;
}
```
## Additional data transformation[⬆](#table-of-contents)
### Basic usage[⬆](#table-of-contents)
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:
```typescript
import { Transform } from 'class-transformer';
import * as moment from 'moment';
import { Moment } from 'moment';
export class Photo {
id: number;
@Type(() => Date)
@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.
### Advanced usage[⬆](#table-of-contents)
The `@Transform` decorator is given more arguments to let you configure how you want the transformation to be done.
```ts
@Transform(({ value, key, obj, type }) => value)
```
| Argument | Description |
| --------- | ------------------------------------------------------- |
| `value` | The property value before the transformation. |
| `key` | The name of the transformed property. |
| `obj` | The transformation source object. |
| `type` | The transformation type. |
| `options` | The options object passed to the transformation method. |
## Other decorators[⬆](#table-of-contents)
| Signature | Example | Description |
| ------------------------ | ---------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `@TransformClassToPlain` | `@TransformClassToPlain({ groups: ["user"] })` | Transform the method return with classToPlain and expose the properties on the class. |
| `@TransformClassToClass` | `@TransformClassToClass({ groups: ["user"] })` | Transform the method return with classToClass and expose the properties on the class. |
| `@TransformPlainToClass` | `@TransformPlainToClass(User, { groups: ["user"] })` | Transform the method return with plainToClass and expose the properties on the class. |
The above decorators accept one optional argument:
ClassTransformOptions - The transform options like groups, version, name
An example:
```typescript
@Exclude()
class User {
id: number;
@Expose()
firstName: string;
@Expose()
lastName: string;
@Expose({ groups: ['user.email'] })
email: string;
password: string;
}
class UserController {
@TransformClassToPlain({ groups: ['user.email'] })
getUser() {
const user = new User();
user.firstName = 'Snir';
user.lastName = 'Segal';
user.password = 'imnosuperman';
return user;
}
}
const controller = new UserController();
const user = controller.getUser();
```
the `user` variable will contain only firstName,lastName, email properties because they are
the exposed variables. email property is also exposed because we metioned the group "user.email".
## Working with generics[⬆](#table-of-contents)
Generics are not supported because TypeScript does not have good reflection abilities yet.
Once TypeScript team provide us better runtime type reflection 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)
## Implicit type conversion[⬆](#table-of-contents)
> **NOTE** If you use class-validator together with class-transformer you propably DON'T want to enable this function.
Enables automatic conversion between built-in types based on type information provided by Typescript. Disabled by default.
```ts
import { IsString } from 'class-validator';
class MyPayload {
@IsString()
prop: string;
}
const result1 = plainToClass(MyPayload, { prop: 1234 }, { enableImplicitConversion: true });
const result2 = plainToClass(MyPayload, { prop: 1234 }, { enableImplicitConversion: false });
/**
* result1 will be `{ prop: "1234" }` - notice how the prop value has been converted to string.
* result2 will be `{ prop: 1234 }` - default behaviour
*/
```
## How does it handle circular references?[⬆](#table-of-contents)
Circular references are ignored.
For example, if you are transforming class `User` that contains property `photos` with type of `Photo`,
and `Photo` contains link `user` to its parent `User`, then `user` will be ignored during transformation.
Circular references are not ignored only during `classToClass` operation.
## Example with Angular2[⬆](#table-of-contents)
Lets say you want to download users and want them automatically to be mapped to the instances of `User` class.
```typescript
import { plainToClass } from 'class-transformer';
this.http
.get('users.json')
.map(res => res.json())
.map(res => plainToClass(User, res as Object[]))
.subscribe(users => {
// now "users" is type of User[] and each user has getName() and isAdult() methods available
console.log(users);
});
```
You can also inject a class `ClassTransformer` as a service in `providers`, and use its methods.
Example how to use with angular 2 in [plunker](http://plnkr.co/edit/Mja1ZYAjVySWASMHVB9R).
Source code is [here](https://github.com/pleerock/class-transformer-demo).
## Samples[⬆](#table-of-contents)
Take a look on samples in [./sample](https://github.com/pleerock/class-transformer/tree/master/sample) for more examples of
usages.
## Release notes[⬆](#table-of-contents)
See information about breaking changes and release notes [here](https://github.com/typestack/class-transformer/blob/master/CHANGELOG.md).

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,69 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClassTransformer = void 0;
const TransformOperationExecutor_1 = require("./TransformOperationExecutor");
const enums_1 = require("./enums");
const default_options_constant_1 = require("./constants/default-options.constant");
class ClassTransformer {
instanceToPlain(object, options) {
const executor = new TransformOperationExecutor_1.TransformOperationExecutor(enums_1.TransformationType.CLASS_TO_PLAIN, {
...default_options_constant_1.defaultOptions,
...options,
});
return executor.transform(undefined, object, undefined, undefined, undefined, undefined);
}
classToPlainFromExist(object, plainObject, options) {
const executor = new TransformOperationExecutor_1.TransformOperationExecutor(enums_1.TransformationType.CLASS_TO_PLAIN, {
...default_options_constant_1.defaultOptions,
...options,
});
return executor.transform(plainObject, object, undefined, undefined, undefined, undefined);
}
plainToInstance(cls, plain, options) {
const executor = new TransformOperationExecutor_1.TransformOperationExecutor(enums_1.TransformationType.PLAIN_TO_CLASS, {
...default_options_constant_1.defaultOptions,
...options,
});
return executor.transform(undefined, plain, cls, undefined, undefined, undefined);
}
plainToClassFromExist(clsObject, plain, options) {
const executor = new TransformOperationExecutor_1.TransformOperationExecutor(enums_1.TransformationType.PLAIN_TO_CLASS, {
...default_options_constant_1.defaultOptions,
...options,
});
return executor.transform(clsObject, plain, undefined, undefined, undefined, undefined);
}
instanceToInstance(object, options) {
const executor = new TransformOperationExecutor_1.TransformOperationExecutor(enums_1.TransformationType.CLASS_TO_CLASS, {
...default_options_constant_1.defaultOptions,
...options,
});
return executor.transform(undefined, object, undefined, undefined, undefined, undefined);
}
classToClassFromExist(object, fromObject, options) {
const executor = new TransformOperationExecutor_1.TransformOperationExecutor(enums_1.TransformationType.CLASS_TO_CLASS, {
...default_options_constant_1.defaultOptions,
...options,
});
return executor.transform(fromObject, object, undefined, undefined, undefined, undefined);
}
serialize(object, options) {
return JSON.stringify(this.instanceToPlain(object, options));
}
/**
* Deserializes given JSON string to a object of the given class.
*/
deserialize(cls, json, options) {
const jsonObject = JSON.parse(json);
return this.plainToInstance(cls, jsonObject, options);
}
/**
* Deserializes given JSON string to an array of objects of the given class.
*/
deserializeArray(cls, json, options) {
const jsonObject = JSON.parse(json);
return this.plainToInstance(cls, jsonObject, options);
}
}
exports.ClassTransformer = ClassTransformer;
//# sourceMappingURL=ClassTransformer.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,211 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MetadataStorage = void 0;
const enums_1 = require("./enums");
/**
* Storage all library metadata.
*/
class MetadataStorage {
constructor() {
// -------------------------------------------------------------------------
// Properties
// -------------------------------------------------------------------------
this._typeMetadatas = new Map();
this._transformMetadatas = new Map();
this._exposeMetadatas = new Map();
this._excludeMetadatas = new Map();
this._ancestorsMap = new Map();
}
// -------------------------------------------------------------------------
// Adder Methods
// -------------------------------------------------------------------------
addTypeMetadata(metadata) {
if (!this._typeMetadatas.has(metadata.target)) {
this._typeMetadatas.set(metadata.target, new Map());
}
this._typeMetadatas.get(metadata.target).set(metadata.propertyName, metadata);
}
addTransformMetadata(metadata) {
if (!this._transformMetadatas.has(metadata.target)) {
this._transformMetadatas.set(metadata.target, new Map());
}
if (!this._transformMetadatas.get(metadata.target).has(metadata.propertyName)) {
this._transformMetadatas.get(metadata.target).set(metadata.propertyName, []);
}
this._transformMetadatas.get(metadata.target).get(metadata.propertyName).push(metadata);
}
addExposeMetadata(metadata) {
if (!this._exposeMetadatas.has(metadata.target)) {
this._exposeMetadatas.set(metadata.target, new Map());
}
this._exposeMetadatas.get(metadata.target).set(metadata.propertyName, metadata);
}
addExcludeMetadata(metadata) {
if (!this._excludeMetadatas.has(metadata.target)) {
this._excludeMetadatas.set(metadata.target, new Map());
}
this._excludeMetadatas.get(metadata.target).set(metadata.propertyName, metadata);
}
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
findTransformMetadatas(target, propertyName, transformationType) {
return this.findMetadatas(this._transformMetadatas, target, propertyName).filter(metadata => {
if (!metadata.options)
return true;
if (metadata.options.toClassOnly === true && metadata.options.toPlainOnly === true)
return true;
if (metadata.options.toClassOnly === true) {
return (transformationType === enums_1.TransformationType.CLASS_TO_CLASS ||
transformationType === enums_1.TransformationType.PLAIN_TO_CLASS);
}
if (metadata.options.toPlainOnly === true) {
return transformationType === enums_1.TransformationType.CLASS_TO_PLAIN;
}
return true;
});
}
findExcludeMetadata(target, propertyName) {
return this.findMetadata(this._excludeMetadatas, target, propertyName);
}
findExposeMetadata(target, propertyName) {
return this.findMetadata(this._exposeMetadatas, target, propertyName);
}
findExposeMetadataByCustomName(target, name) {
return this.getExposedMetadatas(target).find(metadata => {
return metadata.options && metadata.options.name === name;
});
}
findTypeMetadata(target, propertyName) {
return this.findMetadata(this._typeMetadatas, target, propertyName);
}
getStrategy(target) {
const excludeMap = this._excludeMetadatas.get(target);
const exclude = excludeMap && excludeMap.get(undefined);
const exposeMap = this._exposeMetadatas.get(target);
const expose = exposeMap && exposeMap.get(undefined);
if ((exclude && expose) || (!exclude && !expose))
return 'none';
return exclude ? 'excludeAll' : 'exposeAll';
}
getExposedMetadatas(target) {
return this.getMetadata(this._exposeMetadatas, target);
}
getExcludedMetadatas(target) {
return this.getMetadata(this._excludeMetadatas, target);
}
getExposedProperties(target, transformationType) {
return this.getExposedMetadatas(target)
.filter(metadata => {
if (!metadata.options)
return true;
if (metadata.options.toClassOnly === true && metadata.options.toPlainOnly === true)
return true;
if (metadata.options.toClassOnly === true) {
return (transformationType === enums_1.TransformationType.CLASS_TO_CLASS ||
transformationType === enums_1.TransformationType.PLAIN_TO_CLASS);
}
if (metadata.options.toPlainOnly === true) {
return transformationType === enums_1.TransformationType.CLASS_TO_PLAIN;
}
return true;
})
.map(metadata => metadata.propertyName);
}
getExcludedProperties(target, transformationType) {
return this.getExcludedMetadatas(target)
.filter(metadata => {
if (!metadata.options)
return true;
if (metadata.options.toClassOnly === true && metadata.options.toPlainOnly === true)
return true;
if (metadata.options.toClassOnly === true) {
return (transformationType === enums_1.TransformationType.CLASS_TO_CLASS ||
transformationType === enums_1.TransformationType.PLAIN_TO_CLASS);
}
if (metadata.options.toPlainOnly === true) {
return transformationType === enums_1.TransformationType.CLASS_TO_PLAIN;
}
return true;
})
.map(metadata => metadata.propertyName);
}
clear() {
this._typeMetadatas.clear();
this._exposeMetadatas.clear();
this._excludeMetadatas.clear();
this._ancestorsMap.clear();
}
// -------------------------------------------------------------------------
// Private Methods
// -------------------------------------------------------------------------
getMetadata(metadatas, target) {
const metadataFromTargetMap = metadatas.get(target);
let metadataFromTarget;
if (metadataFromTargetMap) {
metadataFromTarget = Array.from(metadataFromTargetMap.values()).filter(meta => meta.propertyName !== undefined);
}
const metadataFromAncestors = [];
for (const ancestor of this.getAncestors(target)) {
const ancestorMetadataMap = metadatas.get(ancestor);
if (ancestorMetadataMap) {
const metadataFromAncestor = Array.from(ancestorMetadataMap.values()).filter(meta => meta.propertyName !== undefined);
metadataFromAncestors.push(...metadataFromAncestor);
}
}
return metadataFromAncestors.concat(metadataFromTarget || []);
}
findMetadata(metadatas, target, propertyName) {
const metadataFromTargetMap = metadatas.get(target);
if (metadataFromTargetMap) {
const metadataFromTarget = metadataFromTargetMap.get(propertyName);
if (metadataFromTarget) {
return metadataFromTarget;
}
}
for (const ancestor of this.getAncestors(target)) {
const ancestorMetadataMap = metadatas.get(ancestor);
if (ancestorMetadataMap) {
const ancestorResult = ancestorMetadataMap.get(propertyName);
if (ancestorResult) {
return ancestorResult;
}
}
}
return undefined;
}
findMetadatas(metadatas, target, propertyName) {
const metadataFromTargetMap = metadatas.get(target);
let metadataFromTarget;
if (metadataFromTargetMap) {
metadataFromTarget = metadataFromTargetMap.get(propertyName);
}
const metadataFromAncestorsTarget = [];
for (const ancestor of this.getAncestors(target)) {
const ancestorMetadataMap = metadatas.get(ancestor);
if (ancestorMetadataMap) {
if (ancestorMetadataMap.has(propertyName)) {
metadataFromAncestorsTarget.push(...ancestorMetadataMap.get(propertyName));
}
}
}
return metadataFromAncestorsTarget
.slice()
.reverse()
.concat((metadataFromTarget || []).slice().reverse());
}
getAncestors(target) {
if (!target)
return [];
if (!this._ancestorsMap.has(target)) {
const ancestors = [];
for (let baseClass = Object.getPrototypeOf(target.prototype.constructor); typeof baseClass.prototype !== 'undefined'; baseClass = Object.getPrototypeOf(baseClass.prototype.constructor)) {
ancestors.push(baseClass);
}
this._ancestorsMap.set(target, ancestors);
}
return this._ancestorsMap.get(target);
}
}
exports.MetadataStorage = MetadataStorage;
//# sourceMappingURL=MetadataStorage.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,480 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransformOperationExecutor = void 0;
const storage_1 = require("./storage");
const enums_1 = require("./enums");
const utils_1 = require("./utils");
function instantiateArrayType(arrayType) {
const array = new arrayType();
if (!(array instanceof Set) && !('push' in array)) {
return [];
}
return array;
}
class TransformOperationExecutor {
// -------------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------------
constructor(transformationType, options) {
this.transformationType = transformationType;
this.options = options;
// -------------------------------------------------------------------------
// Private Properties
// -------------------------------------------------------------------------
this.recursionStack = new Set();
}
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
transform(source, value, targetType, arrayType, isMap, level = 0) {
if (Array.isArray(value) || value instanceof Set) {
const newValue = arrayType && this.transformationType === enums_1.TransformationType.PLAIN_TO_CLASS
? instantiateArrayType(arrayType)
: [];
value.forEach((subValue, index) => {
const subSource = source ? source[index] : undefined;
if (!this.options.enableCircularCheck || !this.isCircular(subValue)) {
let realTargetType;
if (typeof targetType !== 'function' &&
targetType &&
targetType.options &&
targetType.options.discriminator &&
targetType.options.discriminator.property &&
targetType.options.discriminator.subTypes) {
if (this.transformationType === enums_1.TransformationType.PLAIN_TO_CLASS) {
realTargetType = targetType.options.discriminator.subTypes.find(subType => subType.name === subValue[targetType.options.discriminator.property]);
const options = { newObject: newValue, object: subValue, property: undefined };
const newType = targetType.typeFunction(options);
realTargetType === undefined ? (realTargetType = newType) : (realTargetType = realTargetType.value);
if (!targetType.options.keepDiscriminatorProperty)
delete subValue[targetType.options.discriminator.property];
}
if (this.transformationType === enums_1.TransformationType.CLASS_TO_CLASS) {
realTargetType = subValue.constructor;
}
if (this.transformationType === enums_1.TransformationType.CLASS_TO_PLAIN) {
subValue[targetType.options.discriminator.property] = targetType.options.discriminator.subTypes.find(subType => subType.value === subValue.constructor).name;
}
}
else {
realTargetType = targetType;
}
const value = this.transform(subSource, subValue, realTargetType, undefined, subValue instanceof Map, level + 1);
if (newValue instanceof Set) {
newValue.add(value);
}
else {
newValue.push(value);
}
}
else if (this.transformationType === enums_1.TransformationType.CLASS_TO_CLASS) {
if (newValue instanceof Set) {
newValue.add(subValue);
}
else {
newValue.push(subValue);
}
}
});
return newValue;
}
else if (targetType === String && !isMap) {
if (value === null || value === undefined)
return value;
return String(value);
}
else if (targetType === Number && !isMap) {
if (value === null || value === undefined)
return value;
return Number(value);
}
else if (targetType === Boolean && !isMap) {
if (value === null || value === undefined)
return value;
return Boolean(value);
}
else if ((targetType === Date || value instanceof Date) && !isMap) {
if (value instanceof Date) {
return new Date(value.valueOf());
}
if (value === null || value === undefined)
return value;
return new Date(value);
}
else if (!!(0, utils_1.getGlobal)().Buffer && (targetType === Buffer || value instanceof Buffer) && !isMap) {
if (value === null || value === undefined)
return value;
return Buffer.from(value);
}
else if ((0, utils_1.isPromise)(value) && !isMap) {
return new Promise((resolve, reject) => {
value.then((data) => resolve(this.transform(undefined, data, targetType, undefined, undefined, level + 1)), reject);
});
}
else if (!isMap && value !== null && typeof value === 'object' && typeof value.then === 'function') {
// Note: We should not enter this, as promise has been handled above
// This option simply returns the Promise preventing a JS error from happening and should be an inaccessible path.
return value; // skip promise transformation
}
else if (typeof value === 'object' && value !== null) {
// try to guess the type
if (!targetType && value.constructor !== Object /* && TransformationType === TransformationType.CLASS_TO_PLAIN*/)
if (!Array.isArray(value) && value.constructor === Array) {
// Somebody attempts to convert special Array like object to Array, eg:
// const evilObject = { '100000000': '100000000', __proto__: [] };
// This could be used to cause Denial-of-service attack so we don't allow it.
// See prevent-array-bomb.spec.ts for more details.
}
else {
// We are good we can use the built-in constructor
targetType = value.constructor;
}
if (!targetType && source)
targetType = source.constructor;
if (this.options.enableCircularCheck) {
// add transformed type to prevent circular references
this.recursionStack.add(value);
}
const keys = this.getKeys(targetType, value, isMap);
let newValue = source ? source : {};
if (!source &&
(this.transformationType === enums_1.TransformationType.PLAIN_TO_CLASS ||
this.transformationType === enums_1.TransformationType.CLASS_TO_CLASS)) {
if (isMap) {
newValue = new Map();
}
else if (targetType) {
newValue = new targetType();
}
else {
newValue = {};
}
}
// traverse over keys
for (const key of keys) {
if (key === '__proto__' || key === 'constructor') {
continue;
}
const valueKey = key;
let newValueKey = key, propertyName = key;
if (!this.options.ignoreDecorators && targetType) {
if (this.transformationType === enums_1.TransformationType.PLAIN_TO_CLASS) {
const exposeMetadata = storage_1.defaultMetadataStorage.findExposeMetadataByCustomName(targetType, key);
if (exposeMetadata) {
propertyName = exposeMetadata.propertyName;
newValueKey = exposeMetadata.propertyName;
}
}
else if (this.transformationType === enums_1.TransformationType.CLASS_TO_PLAIN ||
this.transformationType === enums_1.TransformationType.CLASS_TO_CLASS) {
const exposeMetadata = storage_1.defaultMetadataStorage.findExposeMetadata(targetType, key);
if (exposeMetadata && exposeMetadata.options && exposeMetadata.options.name) {
newValueKey = exposeMetadata.options.name;
}
}
}
// get a subvalue
let subValue = undefined;
if (this.transformationType === enums_1.TransformationType.PLAIN_TO_CLASS) {
/**
* This section is added for the following report:
* https://github.com/typestack/class-transformer/issues/596
*
* We should not call functions or constructors when transforming to class.
*/
subValue = value[valueKey];
}
else {
if (value instanceof Map) {
subValue = value.get(valueKey);
}
else if (value[valueKey] instanceof Function) {
subValue = value[valueKey]();
}
else {
subValue = value[valueKey];
}
}
// determine a type
let type = undefined, isSubValueMap = subValue instanceof Map;
if (targetType && isMap) {
type = targetType;
}
else if (targetType) {
const metadata = storage_1.defaultMetadataStorage.findTypeMetadata(targetType, propertyName);
if (metadata) {
const options = { newObject: newValue, object: value, property: propertyName };
const newType = metadata.typeFunction ? metadata.typeFunction(options) : metadata.reflectedType;
if (metadata.options &&
metadata.options.discriminator &&
metadata.options.discriminator.property &&
metadata.options.discriminator.subTypes) {
if (!(value[valueKey] instanceof Array)) {
if (this.transformationType === enums_1.TransformationType.PLAIN_TO_CLASS) {
type = metadata.options.discriminator.subTypes.find(subType => {
if (subValue && subValue instanceof Object && metadata.options.discriminator.property in subValue) {
return subType.name === subValue[metadata.options.discriminator.property];
}
});
type === undefined ? (type = newType) : (type = type.value);
if (!metadata.options.keepDiscriminatorProperty) {
if (subValue && subValue instanceof Object && metadata.options.discriminator.property in subValue) {
delete subValue[metadata.options.discriminator.property];
}
}
}
if (this.transformationType === enums_1.TransformationType.CLASS_TO_CLASS) {
type = subValue.constructor;
}
if (this.transformationType === enums_1.TransformationType.CLASS_TO_PLAIN) {
if (subValue) {
subValue[metadata.options.discriminator.property] = metadata.options.discriminator.subTypes.find(subType => subType.value === subValue.constructor).name;
}
}
}
else {
type = metadata;
}
}
else {
type = newType;
}
isSubValueMap = isSubValueMap || metadata.reflectedType === Map;
}
else if (this.options.targetMaps) {
// try to find a type in target maps
this.options.targetMaps
.filter(map => map.target === targetType && !!map.properties[propertyName])
.forEach(map => (type = map.properties[propertyName]));
}
else if (this.options.enableImplicitConversion &&
this.transformationType === enums_1.TransformationType.PLAIN_TO_CLASS) {
// if we have no registererd type via the @Type() decorator then we check if we have any
// type declarations in reflect-metadata (type declaration is emited only if some decorator is added to the property.)
const reflectedType = Reflect.getMetadata('design:type', targetType.prototype, propertyName);
if (reflectedType) {
type = reflectedType;
}
}
}
// if value is an array try to get its custom array type
const arrayType = Array.isArray(value[valueKey])
? this.getReflectedType(targetType, propertyName)
: undefined;
// const subValueKey = TransformationType === TransformationType.PLAIN_TO_CLASS && newKeyName ? newKeyName : key;
const subSource = source ? source[valueKey] : undefined;
// if its deserialization then type if required
// if we uncomment this types like string[] will not work
// if (this.transformationType === TransformationType.PLAIN_TO_CLASS && !type && subValue instanceof Object && !(subValue instanceof Date))
// throw new Error(`Cannot determine type for ${(targetType as any).name }.${propertyName}, did you forget to specify a @Type?`);
// if newValue is a source object that has method that match newKeyName then skip it
if (newValue.constructor.prototype) {
const descriptor = Object.getOwnPropertyDescriptor(newValue.constructor.prototype, newValueKey);
if ((this.transformationType === enums_1.TransformationType.PLAIN_TO_CLASS ||
this.transformationType === enums_1.TransformationType.CLASS_TO_CLASS) &&
// eslint-disable-next-line @typescript-eslint/unbound-method
((descriptor && !descriptor.set) || newValue[newValueKey] instanceof Function))
// || TransformationType === TransformationType.CLASS_TO_CLASS
continue;
}
if (!this.options.enableCircularCheck || !this.isCircular(subValue)) {
const transformKey = this.transformationType === enums_1.TransformationType.PLAIN_TO_CLASS ? newValueKey : key;
let finalValue;
if (this.transformationType === enums_1.TransformationType.CLASS_TO_PLAIN) {
// Get original value
finalValue = value[transformKey];
// Apply custom transformation
finalValue = this.applyCustomTransformations(finalValue, targetType, transformKey, value, this.transformationType);
// If nothing change, it means no custom transformation was applied, so use the subValue.
finalValue = value[transformKey] === finalValue ? subValue : finalValue;
// Apply the default transformation
finalValue = this.transform(subSource, finalValue, type, arrayType, isSubValueMap, level + 1);
}
else {
if (subValue === undefined && this.options.exposeDefaultValues) {
// Set default value if nothing provided
finalValue = newValue[newValueKey];
}
else {
finalValue = this.transform(subSource, subValue, type, arrayType, isSubValueMap, level + 1);
finalValue = this.applyCustomTransformations(finalValue, targetType, transformKey, value, this.transformationType);
}
}
if (finalValue !== undefined || this.options.exposeUnsetFields) {
if (newValue instanceof Map) {
newValue.set(newValueKey, finalValue);
}
else {
newValue[newValueKey] = finalValue;
}
}
}
else if (this.transformationType === enums_1.TransformationType.CLASS_TO_CLASS) {
let finalValue = subValue;
finalValue = this.applyCustomTransformations(finalValue, targetType, key, value, this.transformationType);
if (finalValue !== undefined || this.options.exposeUnsetFields) {
if (newValue instanceof Map) {
newValue.set(newValueKey, finalValue);
}
else {
newValue[newValueKey] = finalValue;
}
}
}
}
if (this.options.enableCircularCheck) {
this.recursionStack.delete(value);
}
return newValue;
}
else {
return value;
}
}
applyCustomTransformations(value, target, key, obj, transformationType) {
let metadatas = storage_1.defaultMetadataStorage.findTransformMetadatas(target, key, this.transformationType);
// apply versioning options
if (this.options.version !== undefined) {
metadatas = metadatas.filter(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(metadata => {
if (!metadata.options)
return true;
return this.checkGroups(metadata.options.groups);
});
}
else {
metadatas = metadatas.filter(metadata => {
return !metadata.options || !metadata.options.groups || !metadata.options.groups.length;
});
}
metadatas.forEach(metadata => {
value = metadata.transformFn({ value, key, obj, type: transformationType, options: this.options });
});
return value;
}
// preventing circular references
isCircular(object) {
return this.recursionStack.has(object);
}
getReflectedType(target, propertyName) {
if (!target)
return undefined;
const meta = storage_1.defaultMetadataStorage.findTypeMetadata(target, propertyName);
return meta ? meta.reflectedType : undefined;
}
getKeys(target, object, isMap) {
// determine exclusion strategy
let strategy = storage_1.defaultMetadataStorage.getStrategy(target);
if (strategy === 'none')
strategy = this.options.strategy || 'exposeAll'; // exposeAll is default strategy
// get all keys that need to expose
let keys = [];
if (strategy === 'exposeAll' || isMap) {
if (object instanceof Map) {
keys = Array.from(object.keys());
}
else {
keys = Object.keys(object);
}
}
if (isMap) {
// expose & exclude do not apply for map keys only to fields
return keys;
}
/**
* If decorators are ignored but we don't want the extraneous values, then we use the
* metadata to decide which property is needed, but doesn't apply the decorator effect.
*/
if (this.options.ignoreDecorators && this.options.excludeExtraneousValues && target) {
const exposedProperties = storage_1.defaultMetadataStorage.getExposedProperties(target, this.transformationType);
const excludedProperties = storage_1.defaultMetadataStorage.getExcludedProperties(target, this.transformationType);
keys = [...exposedProperties, ...excludedProperties];
}
if (!this.options.ignoreDecorators && target) {
// add all exposed to list of keys
let exposedProperties = storage_1.defaultMetadataStorage.getExposedProperties(target, this.transformationType);
if (this.transformationType === enums_1.TransformationType.PLAIN_TO_CLASS) {
exposedProperties = exposedProperties.map(key => {
const exposeMetadata = storage_1.defaultMetadataStorage.findExposeMetadata(target, key);
if (exposeMetadata && exposeMetadata.options && exposeMetadata.options.name) {
return exposeMetadata.options.name;
}
return key;
});
}
if (this.options.excludeExtraneousValues) {
keys = exposedProperties;
}
else {
keys = keys.concat(exposedProperties);
}
// exclude excluded properties
const excludedProperties = storage_1.defaultMetadataStorage.getExcludedProperties(target, this.transformationType);
if (excludedProperties.length > 0) {
keys = keys.filter(key => {
return !excludedProperties.includes(key);
});
}
// apply versioning options
if (this.options.version !== undefined) {
keys = keys.filter(key => {
const exposeMetadata = storage_1.defaultMetadataStorage.findExposeMetadata(target, key);
if (!exposeMetadata || !exposeMetadata.options)
return true;
return this.checkVersion(exposeMetadata.options.since, exposeMetadata.options.until);
});
}
// apply grouping options
if (this.options.groups && this.options.groups.length) {
keys = keys.filter(key => {
const exposeMetadata = storage_1.defaultMetadataStorage.findExposeMetadata(target, key);
if (!exposeMetadata || !exposeMetadata.options)
return true;
return this.checkGroups(exposeMetadata.options.groups);
});
}
else {
keys = keys.filter(key => {
const exposeMetadata = storage_1.defaultMetadataStorage.findExposeMetadata(target, key);
return (!exposeMetadata ||
!exposeMetadata.options ||
!exposeMetadata.options.groups ||
!exposeMetadata.options.groups.length);
});
}
}
// exclude prefixed properties
if (this.options.excludePrefixes && this.options.excludePrefixes.length) {
keys = keys.filter(key => this.options.excludePrefixes.every(prefix => {
return key.substr(0, prefix.length) !== prefix;
}));
}
// make sure we have unique keys
keys = keys.filter((key, index, self) => {
return self.indexOf(key) === index;
});
return keys;
}
checkVersion(since, until) {
let decision = true;
if (decision && since)
decision = this.options.version >= since;
if (decision && until)
decision = this.options.version < until;
return decision;
}
checkGroups(groups) {
if (!groups)
return true;
return this.options.groups.some(optionGroup => groups.includes(optionGroup));
}
}
exports.TransformOperationExecutor = TransformOperationExecutor;
//# sourceMappingURL=TransformOperationExecutor.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultOptions = void 0;
/**
* These are the default options used by any transformation operation.
*/
exports.defaultOptions = {
enableCircularCheck: false,
enableImplicitConversion: false,
excludeExtraneousValues: false,
excludePrefixes: undefined,
exposeDefaultValues: false,
exposeUnsetFields: true,
groups: undefined,
ignoreDecorators: false,
strategy: undefined,
targetMaps: undefined,
version: undefined,
};
//# sourceMappingURL=default-options.constant.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"default-options.constant.js","sourceRoot":"","sources":["../../../src/constants/default-options.constant.ts"],"names":[],"mappings":";;;AAEA;;GAEG;AACU,QAAA,cAAc,GAAmC;IAC5D,mBAAmB,EAAE,KAAK;IAC1B,wBAAwB,EAAE,KAAK;IAC/B,uBAAuB,EAAE,KAAK;IAC9B,eAAe,EAAE,SAAS;IAC1B,mBAAmB,EAAE,KAAK;IAC1B,iBAAiB,EAAE,IAAI;IACvB,MAAM,EAAE,SAAS;IACjB,gBAAgB,EAAE,KAAK;IACvB,QAAQ,EAAE,SAAS;IACnB,UAAU,EAAE,SAAS;IACrB,OAAO,EAAE,SAAS;CACnB,CAAC","sourcesContent":["import { ClassTransformOptions } from '../interfaces/class-transformer-options.interface';\n\n/**\n * These are the default options used by any transformation operation.\n */\nexport const defaultOptions: Partial<ClassTransformOptions> = {\n enableCircularCheck: false,\n enableImplicitConversion: false,\n excludeExtraneousValues: false,\n excludePrefixes: undefined,\n exposeDefaultValues: false,\n exposeUnsetFields: true,\n groups: undefined,\n ignoreDecorators: false,\n strategy: undefined,\n targetMaps: undefined,\n version: undefined,\n};\n"]}

View File

@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Exclude = void 0;
const storage_1 = require("../storage");
/**
* Marks the given class or property as excluded. By default the property is excluded in both
* constructorToPlain and plainToConstructor transformations. It can be limited to only one direction
* via using the `toPlainOnly` or `toClassOnly` option.
*
* Can be applied to class definitions and properties.
*/
function Exclude(options = {}) {
/**
* NOTE: The `propertyName` property must be marked as optional because
* this decorator used both as a class and a property decorator and the
* Typescript compiler will freak out if we make it mandatory as a class
* decorator only receives one parameter.
*/
return function (object, propertyName) {
storage_1.defaultMetadataStorage.addExcludeMetadata({
target: object instanceof Function ? object : object.constructor,
propertyName: propertyName,
options,
});
};
}
exports.Exclude = Exclude;
//# sourceMappingURL=exclude.decorator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"exclude.decorator.js","sourceRoot":"","sources":["../../../src/decorators/exclude.decorator.ts"],"names":[],"mappings":";;;AAAA,wCAAoD;AAGpD;;;;;;GAMG;AACH,SAAgB,OAAO,CAAC,UAA0B,EAAE;IAClD;;;;;OAKG;IACH,OAAO,UAAU,MAAW,EAAE,YAA8B;QAC1D,gCAAsB,CAAC,kBAAkB,CAAC;YACxC,MAAM,EAAE,MAAM,YAAY,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW;YAChE,YAAY,EAAE,YAAsB;YACpC,OAAO;SACR,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAdD,0BAcC","sourcesContent":["import { defaultMetadataStorage } from '../storage';\nimport { ExcludeOptions } from '../interfaces';\n\n/**\n * Marks the given class or property as excluded. By default the property is excluded in both\n * constructorToPlain and plainToConstructor transformations. It can be limited to only one direction\n * via using the `toPlainOnly` or `toClassOnly` option.\n *\n * Can be applied to class definitions and properties.\n */\nexport function Exclude(options: ExcludeOptions = {}): PropertyDecorator & ClassDecorator {\n /**\n * NOTE: The `propertyName` property must be marked as optional because\n * this decorator used both as a class and a property decorator and the\n * Typescript compiler will freak out if we make it mandatory as a class\n * decorator only receives one parameter.\n */\n return function (object: any, propertyName?: string | Symbol): void {\n defaultMetadataStorage.addExcludeMetadata({\n target: object instanceof Function ? object : object.constructor,\n propertyName: propertyName as string,\n options,\n });\n };\n}\n"]}

View File

@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Expose = void 0;
const storage_1 = require("../storage");
/**
* Marks the given class or property as included. By default the property is included in both
* constructorToPlain and plainToConstructor transformations. It can be limited to only one direction
* via using the `toPlainOnly` or `toClassOnly` option.
*
* Can be applied to class definitions and properties.
*/
function Expose(options = {}) {
/**
* NOTE: The `propertyName` property must be marked as optional because
* this decorator used both as a class and a property decorator and the
* Typescript compiler will freak out if we make it mandatory as a class
* decorator only receives one parameter.
*/
return function (object, propertyName) {
storage_1.defaultMetadataStorage.addExposeMetadata({
target: object instanceof Function ? object : object.constructor,
propertyName: propertyName,
options,
});
};
}
exports.Expose = Expose;
//# sourceMappingURL=expose.decorator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"expose.decorator.js","sourceRoot":"","sources":["../../../src/decorators/expose.decorator.ts"],"names":[],"mappings":";;;AAAA,wCAAoD;AAGpD;;;;;;GAMG;AACH,SAAgB,MAAM,CAAC,UAAyB,EAAE;IAChD;;;;;OAKG;IACH,OAAO,UAAU,MAAW,EAAE,YAA8B;QAC1D,gCAAsB,CAAC,iBAAiB,CAAC;YACvC,MAAM,EAAE,MAAM,YAAY,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW;YAChE,YAAY,EAAE,YAAsB;YACpC,OAAO;SACR,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAdD,wBAcC","sourcesContent":["import { defaultMetadataStorage } from '../storage';\nimport { ExposeOptions } from '../interfaces';\n\n/**\n * Marks the given class or property as included. By default the property is included in both\n * constructorToPlain and plainToConstructor transformations. It can be limited to only one direction\n * via using the `toPlainOnly` or `toClassOnly` option.\n *\n * Can be applied to class definitions and properties.\n */\nexport function Expose(options: ExposeOptions = {}): PropertyDecorator & ClassDecorator {\n /**\n * NOTE: The `propertyName` property must be marked as optional because\n * this decorator used both as a class and a property decorator and the\n * Typescript compiler will freak out if we make it mandatory as a class\n * decorator only receives one parameter.\n */\n return function (object: any, propertyName?: string | Symbol): void {\n defaultMetadataStorage.addExposeMetadata({\n target: object instanceof Function ? object : object.constructor,\n propertyName: propertyName as string,\n options,\n });\n };\n}\n"]}

View File

@@ -0,0 +1,20 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./exclude.decorator"), exports);
__exportStar(require("./expose.decorator"), exports);
__exportStar(require("./transform-instance-to-instance.decorator"), exports);
__exportStar(require("./transform-instance-to-plain.decorator"), exports);
__exportStar(require("./transform-plain-to-instance.decorator"), exports);
__exportStar(require("./transform.decorator"), exports);
__exportStar(require("./type.decorator"), exports);
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/decorators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,sDAAoC;AACpC,qDAAmC;AACnC,6EAA2D;AAC3D,0EAAwD;AACxD,0EAAwD;AACxD,wDAAsC;AACtC,mDAAiC","sourcesContent":["export * from './exclude.decorator';\nexport * from './expose.decorator';\nexport * from './transform-instance-to-instance.decorator';\nexport * from './transform-instance-to-plain.decorator';\nexport * from './transform-plain-to-instance.decorator';\nexport * from './transform.decorator';\nexport * from './type.decorator';\n"]}

View File

@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransformInstanceToInstance = void 0;
const ClassTransformer_1 = require("../ClassTransformer");
/**
* Return the class instance only with the exposed properties.
*
* Can be applied to functions and getters/setters only.
*/
function TransformInstanceToInstance(params) {
return function (target, propertyKey, descriptor) {
const classTransformer = new ClassTransformer_1.ClassTransformer();
const originalMethod = descriptor.value;
descriptor.value = function (...args) {
const result = originalMethod.apply(this, args);
const isPromise = !!result && (typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function';
return isPromise
? result.then((data) => classTransformer.instanceToInstance(data, params))
: classTransformer.instanceToInstance(result, params);
};
};
}
exports.TransformInstanceToInstance = TransformInstanceToInstance;
//# sourceMappingURL=transform-instance-to-instance.decorator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"transform-instance-to-instance.decorator.js","sourceRoot":"","sources":["../../../src/decorators/transform-instance-to-instance.decorator.ts"],"names":[],"mappings":";;;AAAA,0DAAuD;AAGvD;;;;GAIG;AACH,SAAgB,2BAA2B,CAAC,MAA8B;IACxE,OAAO,UAAU,MAA2B,EAAE,WAA4B,EAAE,UAA8B;QACxG,MAAM,gBAAgB,GAAqB,IAAI,mCAAgB,EAAE,CAAC;QAClE,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC;QAExC,UAAU,CAAC,KAAK,GAAG,UAAU,GAAG,IAAW;YACzC,MAAM,MAAM,GAAQ,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACrD,MAAM,SAAS,GACb,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,UAAU,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC;YAChH,OAAO,SAAS;gBACd,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAC/E,CAAC,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1D,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAdD,kEAcC","sourcesContent":["import { ClassTransformer } from '../ClassTransformer';\nimport { ClassTransformOptions } from '../interfaces';\n\n/**\n * Return the class instance only with the exposed properties.\n *\n * Can be applied to functions and getters/setters only.\n */\nexport function TransformInstanceToInstance(params?: ClassTransformOptions): MethodDecorator {\n return function (target: Record<string, any>, propertyKey: string | Symbol, descriptor: PropertyDescriptor): void {\n const classTransformer: ClassTransformer = new ClassTransformer();\n const originalMethod = descriptor.value;\n\n descriptor.value = function (...args: any[]): Record<string, any> {\n const result: any = originalMethod.apply(this, args);\n const isPromise =\n !!result && (typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function';\n return isPromise\n ? result.then((data: any) => classTransformer.instanceToInstance(data, params))\n : classTransformer.instanceToInstance(result, params);\n };\n };\n}\n"]}

View File

@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransformInstanceToPlain = void 0;
const ClassTransformer_1 = require("../ClassTransformer");
/**
* Transform the object from class to plain object and return only with the exposed properties.
*
* Can be applied to functions and getters/setters only.
*/
function TransformInstanceToPlain(params) {
return function (target, propertyKey, descriptor) {
const classTransformer = new ClassTransformer_1.ClassTransformer();
const originalMethod = descriptor.value;
descriptor.value = function (...args) {
const result = originalMethod.apply(this, args);
const isPromise = !!result && (typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function';
return isPromise
? result.then((data) => classTransformer.instanceToPlain(data, params))
: classTransformer.instanceToPlain(result, params);
};
};
}
exports.TransformInstanceToPlain = TransformInstanceToPlain;
//# sourceMappingURL=transform-instance-to-plain.decorator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"transform-instance-to-plain.decorator.js","sourceRoot":"","sources":["../../../src/decorators/transform-instance-to-plain.decorator.ts"],"names":[],"mappings":";;;AAAA,0DAAuD;AAGvD;;;;GAIG;AACH,SAAgB,wBAAwB,CAAC,MAA8B;IACrE,OAAO,UAAU,MAA2B,EAAE,WAA4B,EAAE,UAA8B;QACxG,MAAM,gBAAgB,GAAqB,IAAI,mCAAgB,EAAE,CAAC;QAClE,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC;QAExC,UAAU,CAAC,KAAK,GAAG,UAAU,GAAG,IAAW;YACzC,MAAM,MAAM,GAAQ,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACrD,MAAM,SAAS,GACb,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,UAAU,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC;YAChH,OAAO,SAAS;gBACd,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,gBAAgB,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAC5E,CAAC,CAAC,gBAAgB,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvD,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAdD,4DAcC","sourcesContent":["import { ClassTransformer } from '../ClassTransformer';\nimport { ClassTransformOptions } from '../interfaces';\n\n/**\n * Transform the object from class to plain object and return only with the exposed properties.\n *\n * Can be applied to functions and getters/setters only.\n */\nexport function TransformInstanceToPlain(params?: ClassTransformOptions): MethodDecorator {\n return function (target: Record<string, any>, propertyKey: string | Symbol, descriptor: PropertyDescriptor): void {\n const classTransformer: ClassTransformer = new ClassTransformer();\n const originalMethod = descriptor.value;\n\n descriptor.value = function (...args: any[]): Record<string, any> {\n const result: any = originalMethod.apply(this, args);\n const isPromise =\n !!result && (typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function';\n return isPromise\n ? result.then((data: any) => classTransformer.instanceToPlain(data, params))\n : classTransformer.instanceToPlain(result, params);\n };\n };\n}\n"]}

View File

@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransformPlainToInstance = void 0;
const ClassTransformer_1 = require("../ClassTransformer");
/**
* Return the class instance only with the exposed properties.
*
* Can be applied to functions and getters/setters only.
*/
function TransformPlainToInstance(classType, params) {
return function (target, propertyKey, descriptor) {
const classTransformer = new ClassTransformer_1.ClassTransformer();
const originalMethod = descriptor.value;
descriptor.value = function (...args) {
const result = originalMethod.apply(this, args);
const isPromise = !!result && (typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function';
return isPromise
? result.then((data) => classTransformer.plainToInstance(classType, data, params))
: classTransformer.plainToInstance(classType, result, params);
};
};
}
exports.TransformPlainToInstance = TransformPlainToInstance;
//# sourceMappingURL=transform-plain-to-instance.decorator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"transform-plain-to-instance.decorator.js","sourceRoot":"","sources":["../../../src/decorators/transform-plain-to-instance.decorator.ts"],"names":[],"mappings":";;;AAAA,0DAAuD;AAGvD;;;;GAIG;AACH,SAAgB,wBAAwB,CACtC,SAAgC,EAChC,MAA8B;IAE9B,OAAO,UAAU,MAA2B,EAAE,WAA4B,EAAE,UAA8B;QACxG,MAAM,gBAAgB,GAAqB,IAAI,mCAAgB,EAAE,CAAC;QAClE,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC;QAExC,UAAU,CAAC,KAAK,GAAG,UAAU,GAAG,IAAW;YACzC,MAAM,MAAM,GAAQ,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACrD,MAAM,SAAS,GACb,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,UAAU,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC;YAChH,OAAO,SAAS;gBACd,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,gBAAgB,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;gBACvF,CAAC,CAAC,gBAAgB,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAClE,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAjBD,4DAiBC","sourcesContent":["import { ClassTransformer } from '../ClassTransformer';\nimport { ClassTransformOptions, ClassConstructor } from '../interfaces';\n\n/**\n * Return the class instance only with the exposed properties.\n *\n * Can be applied to functions and getters/setters only.\n */\nexport function TransformPlainToInstance(\n classType: ClassConstructor<any>,\n params?: ClassTransformOptions\n): MethodDecorator {\n return function (target: Record<string, any>, propertyKey: string | Symbol, descriptor: PropertyDescriptor): void {\n const classTransformer: ClassTransformer = new ClassTransformer();\n const originalMethod = descriptor.value;\n\n descriptor.value = function (...args: any[]): Record<string, any> {\n const result: any = originalMethod.apply(this, args);\n const isPromise =\n !!result && (typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function';\n return isPromise\n ? result.then((data: any) => classTransformer.plainToInstance(classType, data, params))\n : classTransformer.plainToInstance(classType, result, params);\n };\n };\n}\n"]}

View File

@@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Transform = void 0;
const storage_1 = require("../storage");
/**
* Defines a custom logic for value transformation.
*
* Can be applied to properties only.
*/
function Transform(transformFn, options = {}) {
return function (target, propertyName) {
storage_1.defaultMetadataStorage.addTransformMetadata({
target: target.constructor,
propertyName: propertyName,
transformFn,
options,
});
};
}
exports.Transform = Transform;
//# sourceMappingURL=transform.decorator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"transform.decorator.js","sourceRoot":"","sources":["../../../src/decorators/transform.decorator.ts"],"names":[],"mappings":";;;AAAA,wCAAoD;AAGpD;;;;GAIG;AACH,SAAgB,SAAS,CACvB,WAA+C,EAC/C,UAA4B,EAAE;IAE9B,OAAO,UAAU,MAAW,EAAE,YAA6B;QACzD,gCAAsB,CAAC,oBAAoB,CAAC;YAC1C,MAAM,EAAE,MAAM,CAAC,WAAW;YAC1B,YAAY,EAAE,YAAsB;YACpC,WAAW;YACX,OAAO;SACR,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAZD,8BAYC","sourcesContent":["import { defaultMetadataStorage } from '../storage';\nimport { TransformFnParams, TransformOptions } from '../interfaces';\n\n/**\n * Defines a custom logic for value transformation.\n *\n * Can be applied to properties only.\n */\nexport function Transform(\n transformFn: (params: TransformFnParams) => any,\n options: TransformOptions = {}\n): PropertyDecorator {\n return function (target: any, propertyName: string | Symbol): void {\n defaultMetadataStorage.addTransformMetadata({\n target: target.constructor,\n propertyName: propertyName as string,\n transformFn,\n options,\n });\n };\n}\n"]}

View File

@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Type = void 0;
const storage_1 = require("../storage");
/**
* Specifies a type of the property.
* The given TypeFunction can return a constructor. A discriminator can be given in the options.
*
* Can be applied to properties only.
*/
function Type(typeFunction, options = {}) {
return function (target, propertyName) {
const reflectedType = Reflect.getMetadata('design:type', target, propertyName);
storage_1.defaultMetadataStorage.addTypeMetadata({
target: target.constructor,
propertyName: propertyName,
reflectedType,
typeFunction,
options,
});
};
}
exports.Type = Type;
//# sourceMappingURL=type.decorator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"type.decorator.js","sourceRoot":"","sources":["../../../src/decorators/type.decorator.ts"],"names":[],"mappings":";;;AAAA,wCAAoD;AAGpD;;;;;GAKG;AACH,SAAgB,IAAI,CAClB,YAAmD,EACnD,UAAuB,EAAE;IAEzB,OAAO,UAAU,MAAW,EAAE,YAA6B;QACzD,MAAM,aAAa,GAAI,OAAe,CAAC,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;QACxF,gCAAsB,CAAC,eAAe,CAAC;YACrC,MAAM,EAAE,MAAM,CAAC,WAAW;YAC1B,YAAY,EAAE,YAAsB;YACpC,aAAa;YACb,YAAY;YACZ,OAAO;SACR,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAdD,oBAcC","sourcesContent":["import { defaultMetadataStorage } from '../storage';\nimport { TypeHelpOptions, TypeOptions } from '../interfaces';\n\n/**\n * Specifies a type of the property.\n * The given TypeFunction can return a constructor. A discriminator can be given in the options.\n *\n * Can be applied to properties only.\n */\nexport function Type(\n typeFunction?: (type?: TypeHelpOptions) => Function,\n options: TypeOptions = {}\n): PropertyDecorator {\n return function (target: any, propertyName: string | Symbol): void {\n const reflectedType = (Reflect as any).getMetadata('design:type', target, propertyName);\n defaultMetadataStorage.addTypeMetadata({\n target: target.constructor,\n propertyName: propertyName as string,\n reflectedType,\n typeFunction,\n options,\n });\n };\n}\n"]}

View File

@@ -0,0 +1,14 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./transformation-type.enum"), exports);
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/enums/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6DAA2C","sourcesContent":["export * from './transformation-type.enum';\n"]}

View File

@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransformationType = void 0;
var TransformationType;
(function (TransformationType) {
TransformationType[TransformationType["PLAIN_TO_CLASS"] = 0] = "PLAIN_TO_CLASS";
TransformationType[TransformationType["CLASS_TO_PLAIN"] = 1] = "CLASS_TO_PLAIN";
TransformationType[TransformationType["CLASS_TO_CLASS"] = 2] = "CLASS_TO_CLASS";
})(TransformationType = exports.TransformationType || (exports.TransformationType = {}));
//# sourceMappingURL=transformation-type.enum.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"transformation-type.enum.js","sourceRoot":"","sources":["../../../src/enums/transformation-type.enum.ts"],"names":[],"mappings":";;;AAAA,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,+EAAc,CAAA;IACd,+EAAc,CAAA;IACd,+EAAc,CAAA;AAChB,CAAC,EAJW,kBAAkB,GAAlB,0BAAkB,KAAlB,0BAAkB,QAI7B","sourcesContent":["export enum TransformationType {\n PLAIN_TO_CLASS,\n CLASS_TO_PLAIN,\n CLASS_TO_CLASS,\n}\n"]}

82
backend/node_modules/class-transformer/cjs/index.js generated vendored Normal file
View File

@@ -0,0 +1,82 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.deserializeArray = exports.deserialize = exports.serialize = exports.classToClassFromExist = exports.instanceToInstance = exports.plainToClassFromExist = exports.plainToInstance = exports.plainToClass = exports.classToPlainFromExist = exports.instanceToPlain = exports.classToPlain = exports.ClassTransformer = void 0;
const ClassTransformer_1 = require("./ClassTransformer");
var ClassTransformer_2 = require("./ClassTransformer");
Object.defineProperty(exports, "ClassTransformer", { enumerable: true, get: function () { return ClassTransformer_2.ClassTransformer; } });
__exportStar(require("./decorators"), exports);
__exportStar(require("./interfaces"), exports);
__exportStar(require("./enums"), exports);
const classTransformer = new ClassTransformer_1.ClassTransformer();
function classToPlain(object, options) {
return classTransformer.instanceToPlain(object, options);
}
exports.classToPlain = classToPlain;
function instanceToPlain(object, options) {
return classTransformer.instanceToPlain(object, options);
}
exports.instanceToPlain = instanceToPlain;
function classToPlainFromExist(object, plainObject, options) {
return classTransformer.classToPlainFromExist(object, plainObject, options);
}
exports.classToPlainFromExist = classToPlainFromExist;
function plainToClass(cls, plain, options) {
return classTransformer.plainToInstance(cls, plain, options);
}
exports.plainToClass = plainToClass;
function plainToInstance(cls, plain, options) {
return classTransformer.plainToInstance(cls, plain, options);
}
exports.plainToInstance = plainToInstance;
function plainToClassFromExist(clsObject, plain, options) {
return classTransformer.plainToClassFromExist(clsObject, plain, options);
}
exports.plainToClassFromExist = plainToClassFromExist;
function instanceToInstance(object, options) {
return classTransformer.instanceToInstance(object, options);
}
exports.instanceToInstance = instanceToInstance;
function classToClassFromExist(object, fromObject, options) {
return classTransformer.classToClassFromExist(object, fromObject, options);
}
exports.classToClassFromExist = classToClassFromExist;
function serialize(object, options) {
return classTransformer.serialize(object, options);
}
exports.serialize = serialize;
/**
* Deserializes given JSON string to a object of the given class.
*
* @deprecated This function is being removed. Please use the following instead:
* ```
* instanceToClass(cls, JSON.parse(json), options)
* ```
*/
function deserialize(cls, json, options) {
return classTransformer.deserialize(cls, json, options);
}
exports.deserialize = deserialize;
/**
* Deserializes given JSON string to an array of objects of the given class.
*
* @deprecated This function is being removed. Please use the following instead:
* ```
* JSON.parse(json).map(value => instanceToClass(cls, value, options))
* ```
*
*/
function deserializeArray(cls, json, options) {
return classTransformer.deserializeArray(cls, json, options);
}
exports.deserializeArray = deserializeArray;
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=class-constructor.type.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"class-constructor.type.js","sourceRoot":"","sources":["../../../src/interfaces/class-constructor.type.ts"],"names":[],"mappings":"","sourcesContent":["export type ClassConstructor<T> = {\n new (...args: any[]): T;\n};\n"]}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=class-transformer-options.interface.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"class-transformer-options.interface.js","sourceRoot":"","sources":["../../../src/interfaces/class-transformer-options.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { TargetMap } from './target-map.interface';\n\n/**\n * Options to be passed during transformation.\n */\nexport interface ClassTransformOptions {\n /**\n * Exclusion strategy. By default exposeAll is used, which means that it will expose all properties are transformed\n * by default.\n */\n strategy?: 'excludeAll' | 'exposeAll';\n\n /**\n * Indicates if extraneous properties should be excluded from the value when converting a plain value to a class.\n *\n * This option requires that each property on the target class has at least one `@Expose` or `@Exclude` decorator\n * assigned from this library.\n */\n excludeExtraneousValues?: boolean;\n\n /**\n * Only properties with given groups gonna be transformed.\n */\n groups?: string[];\n\n /**\n * Only properties with \"since\" > version < \"until\" gonna be transformed.\n */\n version?: number;\n\n /**\n * Excludes properties with the given prefixes. For example, if you mark your private properties with \"_\" and \"__\"\n * you can set this option's value to [\"_\", \"__\"] and all private properties will be skipped.\n * This works only for \"exposeAll\" strategy.\n */\n excludePrefixes?: string[];\n\n /**\n * If set to true then class transformer will ignore the effect of all @Expose and @Exclude decorators.\n * This option is useful if you want to kinda clone your object but do not apply decorators affects.\n *\n * __NOTE:__ You may still have to add the decorators to make other options work.\n */\n ignoreDecorators?: boolean;\n\n /**\n * Target maps allows to set a Types of the transforming object without using @Type decorator.\n * This is useful when you are transforming external classes, or if you already have type metadata for\n * objects and you don't want to set it up again.\n */\n targetMaps?: TargetMap[];\n\n /**\n * If set to true then class transformer will perform a circular check. (circular check is turned off by default)\n * This option is useful when you know for sure that your types might have a circular dependency.\n */\n enableCircularCheck?: boolean;\n\n /**\n * If set to true then class transformer will try to convert properties implicitly to their target type based on their typing information.\n *\n * DEFAULT: `false`\n */\n enableImplicitConversion?: boolean;\n\n /**\n * If set to true then class transformer will take default values for unprovided fields.\n * This is useful when you convert a plain object to a class and have an optional field with a default value.\n */\n exposeDefaultValues?: boolean;\n\n /**\n * When set to true, fields with `undefined` as value will be included in class to plain transformation. Otherwise\n * those fields will be omitted from the result.\n *\n * DEFAULT: `true`\n */\n exposeUnsetFields?: boolean;\n}\n"]}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=exclude-options.interface.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"exclude-options.interface.js","sourceRoot":"","sources":["../../../../src/interfaces/decorator-options/exclude-options.interface.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Possible transformation options for the @Exclude decorator.\n */\nexport interface ExcludeOptions {\n /**\n * Expose this property only when transforming from plain to class instance.\n */\n toClassOnly?: boolean;\n\n /**\n * Expose this property only when transforming from class instance to plain object.\n */\n toPlainOnly?: boolean;\n}\n"]}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=expose-options.interface.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"expose-options.interface.js","sourceRoot":"","sources":["../../../../src/interfaces/decorator-options/expose-options.interface.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Possible transformation options for the @Expose decorator.\n */\nexport interface ExposeOptions {\n /**\n * Name of property on the target object to expose the value of this property.\n */\n name?: string;\n\n /**\n * First version where this property should be exposed.\n *\n * Example:\n * ```ts\n * instanceToPlain(payload, { version: 1.0 });\n * ```\n */\n since?: number;\n\n /**\n * Last version where this property should be exposed.\n *\n * Example:\n * ```ts\n * instanceToPlain(payload, { version: 1.0 });\n * ```\n */\n until?: number;\n\n /**\n * List of transformation groups this property belongs to. When set,\n * the property will be exposed only when transform is called with\n * one of the groups specified.\n *\n * Example:\n * ```ts\n * instanceToPlain(payload, { groups: ['user'] });\n * ```\n */\n groups?: string[];\n\n /**\n * Expose this property only when transforming from plain to class instance.\n */\n toClassOnly?: boolean;\n\n /**\n * Expose this property only when transforming from class instance to plain object.\n */\n toPlainOnly?: boolean;\n}\n"]}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=transform-options.interface.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"transform-options.interface.js","sourceRoot":"","sources":["../../../../src/interfaces/decorator-options/transform-options.interface.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Possible transformation options for the @Transform decorator.\n */\nexport interface TransformOptions {\n /**\n * First version where this property should be exposed.\n *\n * Example:\n * ```ts\n * instanceToPlain(payload, { version: 1.0 });\n * ```\n */\n since?: number;\n\n /**\n * Last version where this property should be exposed.\n *\n * Example:\n * ```ts\n * instanceToPlain(payload, { version: 1.0 });\n * ```\n */\n until?: number;\n\n /**\n * List of transformation groups this property belongs to. When set,\n * the property will be exposed only when transform is called with\n * one of the groups specified.\n *\n * Example:\n * ```ts\n * instanceToPlain(payload, { groups: ['user'] });\n * ```\n */\n groups?: string[];\n\n /**\n * Expose this property only when transforming from plain to class instance.\n */\n toClassOnly?: boolean;\n\n /**\n * Expose this property only when transforming from class instance to plain object.\n */\n toPlainOnly?: boolean;\n}\n"]}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=type-discriminator-descriptor.interface.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"type-discriminator-descriptor.interface.js","sourceRoot":"","sources":["../../../../src/interfaces/decorator-options/type-discriminator-descriptor.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { ClassConstructor } from '..';\n\n/**\n * Discriminator object containing the type information to select a proper type\n * during transformation when a discriminator property is provided.\n */\nexport interface DiscriminatorDescriptor {\n /**\n * The name of the property which holds the type information in the received object.\n */\n property: string;\n /**\n * List of the available types. The transformer will try to lookup the object\n * with the same key as the value received in the defined discriminator property\n * and create an instance of the defined class.\n */\n subTypes: {\n /**\n * Name of the type.\n */\n name: string;\n\n /**\n * A class constructor which can be used to create the object.\n */\n value: ClassConstructor<any>;\n }[];\n}\n"]}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=type-options.interface.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"type-options.interface.js","sourceRoot":"","sources":["../../../../src/interfaces/decorator-options/type-options.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { DiscriminatorDescriptor } from './type-discriminator-descriptor.interface';\n\n/**\n * Possible transformation options for the @Type decorator.\n */\nexport interface TypeOptions {\n /**\n * Optional discriminator object, when provided the property value will be\n * initialized according to the specified object.\n */\n discriminator?: DiscriminatorDescriptor;\n\n /**\n * Indicates whether to keep the discriminator property on the\n * transformed object or not. Disabled by default.\n *\n * @default false\n */\n keepDiscriminatorProperty?: boolean;\n}\n"]}

View File

@@ -0,0 +1,27 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./decorator-options/expose-options.interface"), exports);
__exportStar(require("./decorator-options/exclude-options.interface"), exports);
__exportStar(require("./decorator-options/transform-options.interface"), exports);
__exportStar(require("./decorator-options/type-discriminator-descriptor.interface"), exports);
__exportStar(require("./decorator-options/type-options.interface"), exports);
__exportStar(require("./metadata/exclude-metadata.interface"), exports);
__exportStar(require("./metadata/expose-metadata.interface"), exports);
__exportStar(require("./metadata/transform-metadata.interface"), exports);
__exportStar(require("./metadata/transform-fn-params.interface"), exports);
__exportStar(require("./metadata/type-metadata.interface"), exports);
__exportStar(require("./class-constructor.type"), exports);
__exportStar(require("./class-transformer-options.interface"), exports);
__exportStar(require("./target-map.interface"), exports);
__exportStar(require("./type-help-options.interface"), exports);
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/interfaces/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,+EAA6D;AAC7D,gFAA8D;AAC9D,kFAAgE;AAChE,8FAA4E;AAC5E,6EAA2D;AAC3D,wEAAsD;AACtD,uEAAqD;AACrD,0EAAwD;AACxD,2EAAyD;AACzD,qEAAmD;AACnD,2DAAyC;AACzC,wEAAsD;AACtD,yDAAuC;AACvC,gEAA8C","sourcesContent":["export * from './decorator-options/expose-options.interface';\nexport * from './decorator-options/exclude-options.interface';\nexport * from './decorator-options/transform-options.interface';\nexport * from './decorator-options/type-discriminator-descriptor.interface';\nexport * from './decorator-options/type-options.interface';\nexport * from './metadata/exclude-metadata.interface';\nexport * from './metadata/expose-metadata.interface';\nexport * from './metadata/transform-metadata.interface';\nexport * from './metadata/transform-fn-params.interface';\nexport * from './metadata/type-metadata.interface';\nexport * from './class-constructor.type';\nexport * from './class-transformer-options.interface';\nexport * from './target-map.interface';\nexport * from './type-help-options.interface';\n"]}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=exclude-metadata.interface.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"exclude-metadata.interface.js","sourceRoot":"","sources":["../../../../src/interfaces/metadata/exclude-metadata.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { ExcludeOptions } from '..';\n\n/**\n * This object represents metadata assigned to a property via the @Exclude decorator.\n */\nexport interface ExcludeMetadata {\n target: Function;\n\n /**\n * The property name this metadata belongs to on the target (class or property).\n *\n * Note: If the decorator is applied to a class the propertyName will be undefined.\n */\n propertyName: string | undefined;\n\n /**\n * Options passed to the @Exclude operator for this property.\n */\n options: ExcludeOptions;\n}\n"]}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=expose-metadata.interface.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"expose-metadata.interface.js","sourceRoot":"","sources":["../../../../src/interfaces/metadata/expose-metadata.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { ExposeOptions } from '..';\n\n/**\n * This object represents metadata assigned to a property via the @Expose decorator.\n */\nexport interface ExposeMetadata {\n target: Function;\n\n /**\n * The property name this metadata belongs to on the target (class or property).\n *\n * Note: If the decorator is applied to a class the propertyName will be undefined.\n */\n propertyName: string | undefined;\n\n /**\n * Options passed to the @Expose operator for this property.\n */\n options: ExposeOptions;\n}\n"]}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=transform-fn-params.interface.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"transform-fn-params.interface.js","sourceRoot":"","sources":["../../../../src/interfaces/metadata/transform-fn-params.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { TransformationType } from '../../enums';\nimport { ClassTransformOptions } from '../class-transformer-options.interface';\n\nexport interface TransformFnParams {\n value: any;\n key: string;\n obj: any;\n type: TransformationType;\n options: ClassTransformOptions;\n}\n"]}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=transform-metadata.interface.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"transform-metadata.interface.js","sourceRoot":"","sources":["../../../../src/interfaces/metadata/transform-metadata.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { TransformOptions } from '..';\nimport { TransformFnParams } from './transform-fn-params.interface';\n\n/**\n * This object represents metadata assigned to a property via the @Transform decorator.\n */\nexport interface TransformMetadata {\n target: Function;\n\n /**\n * The property name this metadata belongs to on the target (property only).\n */\n propertyName: string;\n\n /**\n * The custom transformation function provided by the user in the @Transform decorator.\n */\n transformFn: (params: TransformFnParams) => any;\n\n /**\n * Options passed to the @Transform operator for this property.\n */\n options: TransformOptions;\n}\n"]}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=type-metadata.interface.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"type-metadata.interface.js","sourceRoot":"","sources":["../../../../src/interfaces/metadata/type-metadata.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { TypeHelpOptions, TypeOptions } from '..';\n\n/**\n * This object represents metadata assigned to a property via the @Type decorator.\n */\nexport interface TypeMetadata {\n target: Function;\n\n /**\n * The property name this metadata belongs to on the target (property only).\n */\n propertyName: string;\n\n /**\n * The type guessed from assigned Reflect metadata ('design:type')\n */\n reflectedType: any;\n\n /**\n * The custom function provided by the user in the @Type decorator which\n * returns the target type for the transformation.\n */\n typeFunction: (options?: TypeHelpOptions) => Function;\n\n /**\n * Options passed to the @Type operator for this property.\n */\n options: TypeOptions;\n}\n"]}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=target-map.interface.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"target-map.interface.js","sourceRoot":"","sources":["../../../src/interfaces/target-map.interface.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Allows to specify a map of Types in the object without using @Type decorator.\n * This is useful when you have external classes.\n */\nexport interface TargetMap {\n /**\n * Target which Types are being specified.\n */\n target: Function;\n\n /**\n * List of properties and their Types.\n */\n properties: { [key: string]: Function };\n}\n"]}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=type-help-options.interface.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"type-help-options.interface.js","sourceRoot":"","sources":["../../../src/interfaces/type-help-options.interface.ts"],"names":[],"mappings":"","sourcesContent":["// TODO: Document this interface. What does each property means?\nexport interface TypeHelpOptions {\n newObject: any;\n object: Record<string, any>;\n property: string;\n}\n"]}

View File

@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultMetadataStorage = void 0;
const MetadataStorage_1 = require("./MetadataStorage");
/**
* Default metadata storage is used as singleton and can be used to storage all metadatas.
*/
exports.defaultMetadataStorage = new MetadataStorage_1.MetadataStorage();
//# sourceMappingURL=storage.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/storage.ts"],"names":[],"mappings":";;;AAAA,uDAAoD;AAEpD;;GAEG;AACU,QAAA,sBAAsB,GAAG,IAAI,iCAAe,EAAE,CAAC","sourcesContent":["import { MetadataStorage } from './MetadataStorage';\n\n/**\n * Default metadata storage is used as singleton and can be used to storage all metadatas.\n */\nexport const defaultMetadataStorage = new MetadataStorage();\n"]}

View File

@@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getGlobal = void 0;
/**
* This function returns the global object across Node and browsers.
*
* Note: `globalThis` is the standardized approach however it has been added to
* Node.js in version 12. We need to include this snippet until Node 12 EOL.
*/
function getGlobal() {
if (typeof globalThis !== 'undefined') {
return globalThis;
}
if (typeof global !== 'undefined') {
return global;
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Cannot find name 'window'.
if (typeof window !== 'undefined') {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Cannot find name 'window'.
return window;
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Cannot find name 'self'.
if (typeof self !== 'undefined') {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: Cannot find name 'self'.
return self;
}
}
exports.getGlobal = getGlobal;
//# sourceMappingURL=get-global.util.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"get-global.util.js","sourceRoot":"","sources":["../../../src/utils/get-global.util.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH,SAAgB,SAAS;IACvB,IAAI,OAAO,UAAU,KAAK,WAAW,EAAE;QACrC,OAAO,UAAU,CAAC;KACnB;IAED,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACjC,OAAO,MAAM,CAAC;KACf;IAED,6DAA6D;IAC7D,yCAAyC;IACzC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACjC,6DAA6D;QAC7D,yCAAyC;QACzC,OAAO,MAAM,CAAC;KACf;IAED,6DAA6D;IAC7D,uCAAuC;IACvC,IAAI,OAAO,IAAI,KAAK,WAAW,EAAE;QAC/B,6DAA6D;QAC7D,uCAAuC;QACvC,OAAO,IAAI,CAAC;KACb;AACH,CAAC;AAxBD,8BAwBC","sourcesContent":["/**\n * This function returns the global object across Node and browsers.\n *\n * Note: `globalThis` is the standardized approach however it has been added to\n * Node.js in version 12. We need to include this snippet until Node 12 EOL.\n */\nexport function getGlobal() {\n if (typeof globalThis !== 'undefined') {\n return globalThis;\n }\n\n if (typeof global !== 'undefined') {\n return global;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore: Cannot find name 'window'.\n if (typeof window !== 'undefined') {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore: Cannot find name 'window'.\n return window;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore: Cannot find name 'self'.\n if (typeof self !== 'undefined') {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore: Cannot find name 'self'.\n return self;\n }\n}\n"]}

View File

@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const _1 = require(".");
describe('getGlobal()', () => {
it('should return true if Buffer is present in globalThis', () => {
expect((0, _1.getGlobal)().Buffer).toBe(true);
});
it('should return false if Buffer is not present in globalThis', () => {
const bufferImp = global.Buffer;
delete global.Buffer;
expect((0, _1.getGlobal)().Buffer).toBe(false);
global.Buffer = bufferImp;
});
});
//# sourceMappingURL=get-global.util.spect.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"get-global.util.spect.js","sourceRoot":"","sources":["../../../src/utils/get-global.util.spect.ts"],"names":[],"mappings":";;AAAA,wBAA8B;AAE9B,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,IAAA,YAAS,GAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;QAChC,OAAO,MAAM,CAAC,MAAM,CAAC;QAErB,MAAM,CAAC,IAAA,YAAS,GAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEvC,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { getGlobal } from '.';\n\ndescribe('getGlobal()', () => {\n it('should return true if Buffer is present in globalThis', () => {\n expect(getGlobal().Buffer).toBe(true);\n });\n\n it('should return false if Buffer is not present in globalThis', () => {\n const bufferImp = global.Buffer;\n delete global.Buffer;\n\n expect(getGlobal().Buffer).toBe(false);\n\n global.Buffer = bufferImp;\n });\n});\n"]}

View File

@@ -0,0 +1,15 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./get-global.util"), exports);
__exportStar(require("./is-promise.util"), exports);
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,oDAAkC;AAClC,oDAAkC","sourcesContent":["export * from './get-global.util';\nexport * from './is-promise.util';\n"]}

View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isPromise = void 0;
function isPromise(p) {
return p !== null && typeof p === 'object' && typeof p.then === 'function';
}
exports.isPromise = isPromise;
//# sourceMappingURL=is-promise.util.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"is-promise.util.js","sourceRoot":"","sources":["../../../src/utils/is-promise.util.ts"],"names":[],"mappings":";;;AAAA,SAAgB,SAAS,CAAI,CAAM;IACjC,OAAO,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC;AAC7E,CAAC;AAFD,8BAEC","sourcesContent":["export function isPromise<T>(p: any): p is Promise<T> {\n return p !== null && typeof p === 'object' && typeof p.then === 'function';\n}\n"]}

View File

@@ -0,0 +1,65 @@
import { TransformOperationExecutor } from './TransformOperationExecutor';
import { TransformationType } from './enums';
import { defaultOptions } from './constants/default-options.constant';
export class ClassTransformer {
instanceToPlain(object, options) {
const executor = new TransformOperationExecutor(TransformationType.CLASS_TO_PLAIN, {
...defaultOptions,
...options,
});
return executor.transform(undefined, object, undefined, undefined, undefined, undefined);
}
classToPlainFromExist(object, plainObject, options) {
const executor = new TransformOperationExecutor(TransformationType.CLASS_TO_PLAIN, {
...defaultOptions,
...options,
});
return executor.transform(plainObject, object, undefined, undefined, undefined, undefined);
}
plainToInstance(cls, plain, options) {
const executor = new TransformOperationExecutor(TransformationType.PLAIN_TO_CLASS, {
...defaultOptions,
...options,
});
return executor.transform(undefined, plain, cls, undefined, undefined, undefined);
}
plainToClassFromExist(clsObject, plain, options) {
const executor = new TransformOperationExecutor(TransformationType.PLAIN_TO_CLASS, {
...defaultOptions,
...options,
});
return executor.transform(clsObject, plain, undefined, undefined, undefined, undefined);
}
instanceToInstance(object, options) {
const executor = new TransformOperationExecutor(TransformationType.CLASS_TO_CLASS, {
...defaultOptions,
...options,
});
return executor.transform(undefined, object, undefined, undefined, undefined, undefined);
}
classToClassFromExist(object, fromObject, options) {
const executor = new TransformOperationExecutor(TransformationType.CLASS_TO_CLASS, {
...defaultOptions,
...options,
});
return executor.transform(fromObject, object, undefined, undefined, undefined, undefined);
}
serialize(object, options) {
return JSON.stringify(this.instanceToPlain(object, options));
}
/**
* Deserializes given JSON string to a object of the given class.
*/
deserialize(cls, json, options) {
const jsonObject = JSON.parse(json);
return this.plainToInstance(cls, jsonObject, options);
}
/**
* Deserializes given JSON string to an array of objects of the given class.
*/
deserializeArray(cls, json, options) {
const jsonObject = JSON.parse(json);
return this.plainToInstance(cls, jsonObject, options);
}
}
//# sourceMappingURL=ClassTransformer.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,207 @@
import { TransformationType } from './enums';
/**
* Storage all library metadata.
*/
export class MetadataStorage {
constructor() {
// -------------------------------------------------------------------------
// Properties
// -------------------------------------------------------------------------
this._typeMetadatas = new Map();
this._transformMetadatas = new Map();
this._exposeMetadatas = new Map();
this._excludeMetadatas = new Map();
this._ancestorsMap = new Map();
}
// -------------------------------------------------------------------------
// Adder Methods
// -------------------------------------------------------------------------
addTypeMetadata(metadata) {
if (!this._typeMetadatas.has(metadata.target)) {
this._typeMetadatas.set(metadata.target, new Map());
}
this._typeMetadatas.get(metadata.target).set(metadata.propertyName, metadata);
}
addTransformMetadata(metadata) {
if (!this._transformMetadatas.has(metadata.target)) {
this._transformMetadatas.set(metadata.target, new Map());
}
if (!this._transformMetadatas.get(metadata.target).has(metadata.propertyName)) {
this._transformMetadatas.get(metadata.target).set(metadata.propertyName, []);
}
this._transformMetadatas.get(metadata.target).get(metadata.propertyName).push(metadata);
}
addExposeMetadata(metadata) {
if (!this._exposeMetadatas.has(metadata.target)) {
this._exposeMetadatas.set(metadata.target, new Map());
}
this._exposeMetadatas.get(metadata.target).set(metadata.propertyName, metadata);
}
addExcludeMetadata(metadata) {
if (!this._excludeMetadatas.has(metadata.target)) {
this._excludeMetadatas.set(metadata.target, new Map());
}
this._excludeMetadatas.get(metadata.target).set(metadata.propertyName, metadata);
}
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
findTransformMetadatas(target, propertyName, transformationType) {
return this.findMetadatas(this._transformMetadatas, target, propertyName).filter(metadata => {
if (!metadata.options)
return true;
if (metadata.options.toClassOnly === true && metadata.options.toPlainOnly === true)
return true;
if (metadata.options.toClassOnly === true) {
return (transformationType === TransformationType.CLASS_TO_CLASS ||
transformationType === TransformationType.PLAIN_TO_CLASS);
}
if (metadata.options.toPlainOnly === true) {
return transformationType === TransformationType.CLASS_TO_PLAIN;
}
return true;
});
}
findExcludeMetadata(target, propertyName) {
return this.findMetadata(this._excludeMetadatas, target, propertyName);
}
findExposeMetadata(target, propertyName) {
return this.findMetadata(this._exposeMetadatas, target, propertyName);
}
findExposeMetadataByCustomName(target, name) {
return this.getExposedMetadatas(target).find(metadata => {
return metadata.options && metadata.options.name === name;
});
}
findTypeMetadata(target, propertyName) {
return this.findMetadata(this._typeMetadatas, target, propertyName);
}
getStrategy(target) {
const excludeMap = this._excludeMetadatas.get(target);
const exclude = excludeMap && excludeMap.get(undefined);
const exposeMap = this._exposeMetadatas.get(target);
const expose = exposeMap && exposeMap.get(undefined);
if ((exclude && expose) || (!exclude && !expose))
return 'none';
return exclude ? 'excludeAll' : 'exposeAll';
}
getExposedMetadatas(target) {
return this.getMetadata(this._exposeMetadatas, target);
}
getExcludedMetadatas(target) {
return this.getMetadata(this._excludeMetadatas, target);
}
getExposedProperties(target, transformationType) {
return this.getExposedMetadatas(target)
.filter(metadata => {
if (!metadata.options)
return true;
if (metadata.options.toClassOnly === true && metadata.options.toPlainOnly === true)
return true;
if (metadata.options.toClassOnly === true) {
return (transformationType === TransformationType.CLASS_TO_CLASS ||
transformationType === TransformationType.PLAIN_TO_CLASS);
}
if (metadata.options.toPlainOnly === true) {
return transformationType === TransformationType.CLASS_TO_PLAIN;
}
return true;
})
.map(metadata => metadata.propertyName);
}
getExcludedProperties(target, transformationType) {
return this.getExcludedMetadatas(target)
.filter(metadata => {
if (!metadata.options)
return true;
if (metadata.options.toClassOnly === true && metadata.options.toPlainOnly === true)
return true;
if (metadata.options.toClassOnly === true) {
return (transformationType === TransformationType.CLASS_TO_CLASS ||
transformationType === TransformationType.PLAIN_TO_CLASS);
}
if (metadata.options.toPlainOnly === true) {
return transformationType === TransformationType.CLASS_TO_PLAIN;
}
return true;
})
.map(metadata => metadata.propertyName);
}
clear() {
this._typeMetadatas.clear();
this._exposeMetadatas.clear();
this._excludeMetadatas.clear();
this._ancestorsMap.clear();
}
// -------------------------------------------------------------------------
// Private Methods
// -------------------------------------------------------------------------
getMetadata(metadatas, target) {
const metadataFromTargetMap = metadatas.get(target);
let metadataFromTarget;
if (metadataFromTargetMap) {
metadataFromTarget = Array.from(metadataFromTargetMap.values()).filter(meta => meta.propertyName !== undefined);
}
const metadataFromAncestors = [];
for (const ancestor of this.getAncestors(target)) {
const ancestorMetadataMap = metadatas.get(ancestor);
if (ancestorMetadataMap) {
const metadataFromAncestor = Array.from(ancestorMetadataMap.values()).filter(meta => meta.propertyName !== undefined);
metadataFromAncestors.push(...metadataFromAncestor);
}
}
return metadataFromAncestors.concat(metadataFromTarget || []);
}
findMetadata(metadatas, target, propertyName) {
const metadataFromTargetMap = metadatas.get(target);
if (metadataFromTargetMap) {
const metadataFromTarget = metadataFromTargetMap.get(propertyName);
if (metadataFromTarget) {
return metadataFromTarget;
}
}
for (const ancestor of this.getAncestors(target)) {
const ancestorMetadataMap = metadatas.get(ancestor);
if (ancestorMetadataMap) {
const ancestorResult = ancestorMetadataMap.get(propertyName);
if (ancestorResult) {
return ancestorResult;
}
}
}
return undefined;
}
findMetadatas(metadatas, target, propertyName) {
const metadataFromTargetMap = metadatas.get(target);
let metadataFromTarget;
if (metadataFromTargetMap) {
metadataFromTarget = metadataFromTargetMap.get(propertyName);
}
const metadataFromAncestorsTarget = [];
for (const ancestor of this.getAncestors(target)) {
const ancestorMetadataMap = metadatas.get(ancestor);
if (ancestorMetadataMap) {
if (ancestorMetadataMap.has(propertyName)) {
metadataFromAncestorsTarget.push(...ancestorMetadataMap.get(propertyName));
}
}
}
return metadataFromAncestorsTarget
.slice()
.reverse()
.concat((metadataFromTarget || []).slice().reverse());
}
getAncestors(target) {
if (!target)
return [];
if (!this._ancestorsMap.has(target)) {
const ancestors = [];
for (let baseClass = Object.getPrototypeOf(target.prototype.constructor); typeof baseClass.prototype !== 'undefined'; baseClass = Object.getPrototypeOf(baseClass.prototype.constructor)) {
ancestors.push(baseClass);
}
this._ancestorsMap.set(target, ancestors);
}
return this._ancestorsMap.get(target);
}
}
//# sourceMappingURL=MetadataStorage.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,476 @@
import { defaultMetadataStorage } from './storage';
import { TransformationType } from './enums';
import { getGlobal, isPromise } from './utils';
function instantiateArrayType(arrayType) {
const array = new arrayType();
if (!(array instanceof Set) && !('push' in array)) {
return [];
}
return array;
}
export class TransformOperationExecutor {
// -------------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------------
constructor(transformationType, options) {
this.transformationType = transformationType;
this.options = options;
// -------------------------------------------------------------------------
// Private Properties
// -------------------------------------------------------------------------
this.recursionStack = new Set();
}
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
transform(source, value, targetType, arrayType, isMap, level = 0) {
if (Array.isArray(value) || value instanceof Set) {
const newValue = arrayType && this.transformationType === TransformationType.PLAIN_TO_CLASS
? instantiateArrayType(arrayType)
: [];
value.forEach((subValue, index) => {
const subSource = source ? source[index] : undefined;
if (!this.options.enableCircularCheck || !this.isCircular(subValue)) {
let realTargetType;
if (typeof targetType !== 'function' &&
targetType &&
targetType.options &&
targetType.options.discriminator &&
targetType.options.discriminator.property &&
targetType.options.discriminator.subTypes) {
if (this.transformationType === TransformationType.PLAIN_TO_CLASS) {
realTargetType = targetType.options.discriminator.subTypes.find(subType => subType.name === subValue[targetType.options.discriminator.property]);
const options = { newObject: newValue, object: subValue, property: undefined };
const newType = targetType.typeFunction(options);
realTargetType === undefined ? (realTargetType = newType) : (realTargetType = realTargetType.value);
if (!targetType.options.keepDiscriminatorProperty)
delete subValue[targetType.options.discriminator.property];
}
if (this.transformationType === TransformationType.CLASS_TO_CLASS) {
realTargetType = subValue.constructor;
}
if (this.transformationType === TransformationType.CLASS_TO_PLAIN) {
subValue[targetType.options.discriminator.property] = targetType.options.discriminator.subTypes.find(subType => subType.value === subValue.constructor).name;
}
}
else {
realTargetType = targetType;
}
const value = this.transform(subSource, subValue, realTargetType, undefined, subValue instanceof Map, level + 1);
if (newValue instanceof Set) {
newValue.add(value);
}
else {
newValue.push(value);
}
}
else if (this.transformationType === TransformationType.CLASS_TO_CLASS) {
if (newValue instanceof Set) {
newValue.add(subValue);
}
else {
newValue.push(subValue);
}
}
});
return newValue;
}
else if (targetType === String && !isMap) {
if (value === null || value === undefined)
return value;
return String(value);
}
else if (targetType === Number && !isMap) {
if (value === null || value === undefined)
return value;
return Number(value);
}
else if (targetType === Boolean && !isMap) {
if (value === null || value === undefined)
return value;
return Boolean(value);
}
else if ((targetType === Date || value instanceof Date) && !isMap) {
if (value instanceof Date) {
return new Date(value.valueOf());
}
if (value === null || value === undefined)
return value;
return new Date(value);
}
else if (!!getGlobal().Buffer && (targetType === Buffer || value instanceof Buffer) && !isMap) {
if (value === null || value === undefined)
return value;
return Buffer.from(value);
}
else if (isPromise(value) && !isMap) {
return new Promise((resolve, reject) => {
value.then((data) => resolve(this.transform(undefined, data, targetType, undefined, undefined, level + 1)), reject);
});
}
else if (!isMap && value !== null && typeof value === 'object' && typeof value.then === 'function') {
// Note: We should not enter this, as promise has been handled above
// This option simply returns the Promise preventing a JS error from happening and should be an inaccessible path.
return value; // skip promise transformation
}
else if (typeof value === 'object' && value !== null) {
// try to guess the type
if (!targetType && value.constructor !== Object /* && TransformationType === TransformationType.CLASS_TO_PLAIN*/)
if (!Array.isArray(value) && value.constructor === Array) {
// Somebody attempts to convert special Array like object to Array, eg:
// const evilObject = { '100000000': '100000000', __proto__: [] };
// This could be used to cause Denial-of-service attack so we don't allow it.
// See prevent-array-bomb.spec.ts for more details.
}
else {
// We are good we can use the built-in constructor
targetType = value.constructor;
}
if (!targetType && source)
targetType = source.constructor;
if (this.options.enableCircularCheck) {
// add transformed type to prevent circular references
this.recursionStack.add(value);
}
const keys = this.getKeys(targetType, value, isMap);
let newValue = source ? source : {};
if (!source &&
(this.transformationType === TransformationType.PLAIN_TO_CLASS ||
this.transformationType === TransformationType.CLASS_TO_CLASS)) {
if (isMap) {
newValue = new Map();
}
else if (targetType) {
newValue = new targetType();
}
else {
newValue = {};
}
}
// traverse over keys
for (const key of keys) {
if (key === '__proto__' || key === 'constructor') {
continue;
}
const valueKey = key;
let newValueKey = key, propertyName = key;
if (!this.options.ignoreDecorators && targetType) {
if (this.transformationType === TransformationType.PLAIN_TO_CLASS) {
const exposeMetadata = defaultMetadataStorage.findExposeMetadataByCustomName(targetType, key);
if (exposeMetadata) {
propertyName = exposeMetadata.propertyName;
newValueKey = exposeMetadata.propertyName;
}
}
else if (this.transformationType === TransformationType.CLASS_TO_PLAIN ||
this.transformationType === TransformationType.CLASS_TO_CLASS) {
const exposeMetadata = defaultMetadataStorage.findExposeMetadata(targetType, key);
if (exposeMetadata && exposeMetadata.options && exposeMetadata.options.name) {
newValueKey = exposeMetadata.options.name;
}
}
}
// get a subvalue
let subValue = undefined;
if (this.transformationType === TransformationType.PLAIN_TO_CLASS) {
/**
* This section is added for the following report:
* https://github.com/typestack/class-transformer/issues/596
*
* We should not call functions or constructors when transforming to class.
*/
subValue = value[valueKey];
}
else {
if (value instanceof Map) {
subValue = value.get(valueKey);
}
else if (value[valueKey] instanceof Function) {
subValue = value[valueKey]();
}
else {
subValue = value[valueKey];
}
}
// determine a type
let type = undefined, isSubValueMap = subValue instanceof Map;
if (targetType && isMap) {
type = targetType;
}
else if (targetType) {
const metadata = defaultMetadataStorage.findTypeMetadata(targetType, propertyName);
if (metadata) {
const options = { newObject: newValue, object: value, property: propertyName };
const newType = metadata.typeFunction ? metadata.typeFunction(options) : metadata.reflectedType;
if (metadata.options &&
metadata.options.discriminator &&
metadata.options.discriminator.property &&
metadata.options.discriminator.subTypes) {
if (!(value[valueKey] instanceof Array)) {
if (this.transformationType === TransformationType.PLAIN_TO_CLASS) {
type = metadata.options.discriminator.subTypes.find(subType => {
if (subValue && subValue instanceof Object && metadata.options.discriminator.property in subValue) {
return subType.name === subValue[metadata.options.discriminator.property];
}
});
type === undefined ? (type = newType) : (type = type.value);
if (!metadata.options.keepDiscriminatorProperty) {
if (subValue && subValue instanceof Object && metadata.options.discriminator.property in subValue) {
delete subValue[metadata.options.discriminator.property];
}
}
}
if (this.transformationType === TransformationType.CLASS_TO_CLASS) {
type = subValue.constructor;
}
if (this.transformationType === TransformationType.CLASS_TO_PLAIN) {
if (subValue) {
subValue[metadata.options.discriminator.property] = metadata.options.discriminator.subTypes.find(subType => subType.value === subValue.constructor).name;
}
}
}
else {
type = metadata;
}
}
else {
type = newType;
}
isSubValueMap = isSubValueMap || metadata.reflectedType === Map;
}
else if (this.options.targetMaps) {
// try to find a type in target maps
this.options.targetMaps
.filter(map => map.target === targetType && !!map.properties[propertyName])
.forEach(map => (type = map.properties[propertyName]));
}
else if (this.options.enableImplicitConversion &&
this.transformationType === TransformationType.PLAIN_TO_CLASS) {
// if we have no registererd type via the @Type() decorator then we check if we have any
// type declarations in reflect-metadata (type declaration is emited only if some decorator is added to the property.)
const reflectedType = Reflect.getMetadata('design:type', targetType.prototype, propertyName);
if (reflectedType) {
type = reflectedType;
}
}
}
// if value is an array try to get its custom array type
const arrayType = Array.isArray(value[valueKey])
? this.getReflectedType(targetType, propertyName)
: undefined;
// const subValueKey = TransformationType === TransformationType.PLAIN_TO_CLASS && newKeyName ? newKeyName : key;
const subSource = source ? source[valueKey] : undefined;
// if its deserialization then type if required
// if we uncomment this types like string[] will not work
// if (this.transformationType === TransformationType.PLAIN_TO_CLASS && !type && subValue instanceof Object && !(subValue instanceof Date))
// throw new Error(`Cannot determine type for ${(targetType as any).name }.${propertyName}, did you forget to specify a @Type?`);
// if newValue is a source object that has method that match newKeyName then skip it
if (newValue.constructor.prototype) {
const descriptor = Object.getOwnPropertyDescriptor(newValue.constructor.prototype, newValueKey);
if ((this.transformationType === TransformationType.PLAIN_TO_CLASS ||
this.transformationType === TransformationType.CLASS_TO_CLASS) &&
// eslint-disable-next-line @typescript-eslint/unbound-method
((descriptor && !descriptor.set) || newValue[newValueKey] instanceof Function))
// || TransformationType === TransformationType.CLASS_TO_CLASS
continue;
}
if (!this.options.enableCircularCheck || !this.isCircular(subValue)) {
const transformKey = this.transformationType === TransformationType.PLAIN_TO_CLASS ? newValueKey : key;
let finalValue;
if (this.transformationType === TransformationType.CLASS_TO_PLAIN) {
// Get original value
finalValue = value[transformKey];
// Apply custom transformation
finalValue = this.applyCustomTransformations(finalValue, targetType, transformKey, value, this.transformationType);
// If nothing change, it means no custom transformation was applied, so use the subValue.
finalValue = value[transformKey] === finalValue ? subValue : finalValue;
// Apply the default transformation
finalValue = this.transform(subSource, finalValue, type, arrayType, isSubValueMap, level + 1);
}
else {
if (subValue === undefined && this.options.exposeDefaultValues) {
// Set default value if nothing provided
finalValue = newValue[newValueKey];
}
else {
finalValue = this.transform(subSource, subValue, type, arrayType, isSubValueMap, level + 1);
finalValue = this.applyCustomTransformations(finalValue, targetType, transformKey, value, this.transformationType);
}
}
if (finalValue !== undefined || this.options.exposeUnsetFields) {
if (newValue instanceof Map) {
newValue.set(newValueKey, finalValue);
}
else {
newValue[newValueKey] = finalValue;
}
}
}
else if (this.transformationType === TransformationType.CLASS_TO_CLASS) {
let finalValue = subValue;
finalValue = this.applyCustomTransformations(finalValue, targetType, key, value, this.transformationType);
if (finalValue !== undefined || this.options.exposeUnsetFields) {
if (newValue instanceof Map) {
newValue.set(newValueKey, finalValue);
}
else {
newValue[newValueKey] = finalValue;
}
}
}
}
if (this.options.enableCircularCheck) {
this.recursionStack.delete(value);
}
return newValue;
}
else {
return value;
}
}
applyCustomTransformations(value, target, key, obj, transformationType) {
let metadatas = defaultMetadataStorage.findTransformMetadatas(target, key, this.transformationType);
// apply versioning options
if (this.options.version !== undefined) {
metadatas = metadatas.filter(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(metadata => {
if (!metadata.options)
return true;
return this.checkGroups(metadata.options.groups);
});
}
else {
metadatas = metadatas.filter(metadata => {
return !metadata.options || !metadata.options.groups || !metadata.options.groups.length;
});
}
metadatas.forEach(metadata => {
value = metadata.transformFn({ value, key, obj, type: transformationType, options: this.options });
});
return value;
}
// preventing circular references
isCircular(object) {
return this.recursionStack.has(object);
}
getReflectedType(target, propertyName) {
if (!target)
return undefined;
const meta = defaultMetadataStorage.findTypeMetadata(target, propertyName);
return meta ? meta.reflectedType : undefined;
}
getKeys(target, object, isMap) {
// determine exclusion strategy
let strategy = defaultMetadataStorage.getStrategy(target);
if (strategy === 'none')
strategy = this.options.strategy || 'exposeAll'; // exposeAll is default strategy
// get all keys that need to expose
let keys = [];
if (strategy === 'exposeAll' || isMap) {
if (object instanceof Map) {
keys = Array.from(object.keys());
}
else {
keys = Object.keys(object);
}
}
if (isMap) {
// expose & exclude do not apply for map keys only to fields
return keys;
}
/**
* If decorators are ignored but we don't want the extraneous values, then we use the
* metadata to decide which property is needed, but doesn't apply the decorator effect.
*/
if (this.options.ignoreDecorators && this.options.excludeExtraneousValues && target) {
const exposedProperties = defaultMetadataStorage.getExposedProperties(target, this.transformationType);
const excludedProperties = defaultMetadataStorage.getExcludedProperties(target, this.transformationType);
keys = [...exposedProperties, ...excludedProperties];
}
if (!this.options.ignoreDecorators && target) {
// add all exposed to list of keys
let exposedProperties = defaultMetadataStorage.getExposedProperties(target, this.transformationType);
if (this.transformationType === TransformationType.PLAIN_TO_CLASS) {
exposedProperties = exposedProperties.map(key => {
const exposeMetadata = defaultMetadataStorage.findExposeMetadata(target, key);
if (exposeMetadata && exposeMetadata.options && exposeMetadata.options.name) {
return exposeMetadata.options.name;
}
return key;
});
}
if (this.options.excludeExtraneousValues) {
keys = exposedProperties;
}
else {
keys = keys.concat(exposedProperties);
}
// exclude excluded properties
const excludedProperties = defaultMetadataStorage.getExcludedProperties(target, this.transformationType);
if (excludedProperties.length > 0) {
keys = keys.filter(key => {
return !excludedProperties.includes(key);
});
}
// apply versioning options
if (this.options.version !== undefined) {
keys = keys.filter(key => {
const exposeMetadata = defaultMetadataStorage.findExposeMetadata(target, key);
if (!exposeMetadata || !exposeMetadata.options)
return true;
return this.checkVersion(exposeMetadata.options.since, exposeMetadata.options.until);
});
}
// apply grouping options
if (this.options.groups && this.options.groups.length) {
keys = keys.filter(key => {
const exposeMetadata = defaultMetadataStorage.findExposeMetadata(target, key);
if (!exposeMetadata || !exposeMetadata.options)
return true;
return this.checkGroups(exposeMetadata.options.groups);
});
}
else {
keys = keys.filter(key => {
const exposeMetadata = defaultMetadataStorage.findExposeMetadata(target, key);
return (!exposeMetadata ||
!exposeMetadata.options ||
!exposeMetadata.options.groups ||
!exposeMetadata.options.groups.length);
});
}
}
// exclude prefixed properties
if (this.options.excludePrefixes && this.options.excludePrefixes.length) {
keys = keys.filter(key => this.options.excludePrefixes.every(prefix => {
return key.substr(0, prefix.length) !== prefix;
}));
}
// make sure we have unique keys
keys = keys.filter((key, index, self) => {
return self.indexOf(key) === index;
});
return keys;
}
checkVersion(since, until) {
let decision = true;
if (decision && since)
decision = this.options.version >= since;
if (decision && until)
decision = this.options.version < until;
return decision;
}
checkGroups(groups) {
if (!groups)
return true;
return this.options.groups.some(optionGroup => groups.includes(optionGroup));
}
}
//# sourceMappingURL=TransformOperationExecutor.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,17 @@
/**
* These are the default options used by any transformation operation.
*/
export const defaultOptions = {
enableCircularCheck: false,
enableImplicitConversion: false,
excludeExtraneousValues: false,
excludePrefixes: undefined,
exposeDefaultValues: false,
exposeUnsetFields: true,
groups: undefined,
ignoreDecorators: false,
strategy: undefined,
targetMaps: undefined,
version: undefined,
};
//# sourceMappingURL=default-options.constant.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"default-options.constant.js","sourceRoot":"","sources":["../../../src/constants/default-options.constant.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAmC;IAC5D,mBAAmB,EAAE,KAAK;IAC1B,wBAAwB,EAAE,KAAK;IAC/B,uBAAuB,EAAE,KAAK;IAC9B,eAAe,EAAE,SAAS;IAC1B,mBAAmB,EAAE,KAAK;IAC1B,iBAAiB,EAAE,IAAI;IACvB,MAAM,EAAE,SAAS;IACjB,gBAAgB,EAAE,KAAK;IACvB,QAAQ,EAAE,SAAS;IACnB,UAAU,EAAE,SAAS;IACrB,OAAO,EAAE,SAAS;CACnB,CAAC","sourcesContent":["import { ClassTransformOptions } from '../interfaces/class-transformer-options.interface';\n\n/**\n * These are the default options used by any transformation operation.\n */\nexport const defaultOptions: Partial<ClassTransformOptions> = {\n enableCircularCheck: false,\n enableImplicitConversion: false,\n excludeExtraneousValues: false,\n excludePrefixes: undefined,\n exposeDefaultValues: false,\n exposeUnsetFields: true,\n groups: undefined,\n ignoreDecorators: false,\n strategy: undefined,\n targetMaps: undefined,\n version: undefined,\n};\n"]}

View File

@@ -0,0 +1,24 @@
import { defaultMetadataStorage } from '../storage';
/**
* Marks the given class or property as excluded. By default the property is excluded in both
* constructorToPlain and plainToConstructor transformations. It can be limited to only one direction
* via using the `toPlainOnly` or `toClassOnly` option.
*
* Can be applied to class definitions and properties.
*/
export function Exclude(options = {}) {
/**
* NOTE: The `propertyName` property must be marked as optional because
* this decorator used both as a class and a property decorator and the
* Typescript compiler will freak out if we make it mandatory as a class
* decorator only receives one parameter.
*/
return function (object, propertyName) {
defaultMetadataStorage.addExcludeMetadata({
target: object instanceof Function ? object : object.constructor,
propertyName: propertyName,
options,
});
};
}
//# sourceMappingURL=exclude.decorator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"exclude.decorator.js","sourceRoot":"","sources":["../../../src/decorators/exclude.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAGpD;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,UAA0B,EAAE;IAClD;;;;;OAKG;IACH,OAAO,UAAU,MAAW,EAAE,YAA8B;QAC1D,sBAAsB,CAAC,kBAAkB,CAAC;YACxC,MAAM,EAAE,MAAM,YAAY,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW;YAChE,YAAY,EAAE,YAAsB;YACpC,OAAO;SACR,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { defaultMetadataStorage } from '../storage';\nimport { ExcludeOptions } from '../interfaces';\n\n/**\n * Marks the given class or property as excluded. By default the property is excluded in both\n * constructorToPlain and plainToConstructor transformations. It can be limited to only one direction\n * via using the `toPlainOnly` or `toClassOnly` option.\n *\n * Can be applied to class definitions and properties.\n */\nexport function Exclude(options: ExcludeOptions = {}): PropertyDecorator & ClassDecorator {\n /**\n * NOTE: The `propertyName` property must be marked as optional because\n * this decorator used both as a class and a property decorator and the\n * Typescript compiler will freak out if we make it mandatory as a class\n * decorator only receives one parameter.\n */\n return function (object: any, propertyName?: string | Symbol): void {\n defaultMetadataStorage.addExcludeMetadata({\n target: object instanceof Function ? object : object.constructor,\n propertyName: propertyName as string,\n options,\n });\n };\n}\n"]}

View File

@@ -0,0 +1,24 @@
import { defaultMetadataStorage } from '../storage';
/**
* Marks the given class or property as included. By default the property is included in both
* constructorToPlain and plainToConstructor transformations. It can be limited to only one direction
* via using the `toPlainOnly` or `toClassOnly` option.
*
* Can be applied to class definitions and properties.
*/
export function Expose(options = {}) {
/**
* NOTE: The `propertyName` property must be marked as optional because
* this decorator used both as a class and a property decorator and the
* Typescript compiler will freak out if we make it mandatory as a class
* decorator only receives one parameter.
*/
return function (object, propertyName) {
defaultMetadataStorage.addExposeMetadata({
target: object instanceof Function ? object : object.constructor,
propertyName: propertyName,
options,
});
};
}
//# sourceMappingURL=expose.decorator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"expose.decorator.js","sourceRoot":"","sources":["../../../src/decorators/expose.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAGpD;;;;;;GAMG;AACH,MAAM,UAAU,MAAM,CAAC,UAAyB,EAAE;IAChD;;;;;OAKG;IACH,OAAO,UAAU,MAAW,EAAE,YAA8B;QAC1D,sBAAsB,CAAC,iBAAiB,CAAC;YACvC,MAAM,EAAE,MAAM,YAAY,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW;YAChE,YAAY,EAAE,YAAsB;YACpC,OAAO;SACR,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { defaultMetadataStorage } from '../storage';\nimport { ExposeOptions } from '../interfaces';\n\n/**\n * Marks the given class or property as included. By default the property is included in both\n * constructorToPlain and plainToConstructor transformations. It can be limited to only one direction\n * via using the `toPlainOnly` or `toClassOnly` option.\n *\n * Can be applied to class definitions and properties.\n */\nexport function Expose(options: ExposeOptions = {}): PropertyDecorator & ClassDecorator {\n /**\n * NOTE: The `propertyName` property must be marked as optional because\n * this decorator used both as a class and a property decorator and the\n * Typescript compiler will freak out if we make it mandatory as a class\n * decorator only receives one parameter.\n */\n return function (object: any, propertyName?: string | Symbol): void {\n defaultMetadataStorage.addExposeMetadata({\n target: object instanceof Function ? object : object.constructor,\n propertyName: propertyName as string,\n options,\n });\n };\n}\n"]}

View File

@@ -0,0 +1,8 @@
export * from './exclude.decorator';
export * from './expose.decorator';
export * from './transform-instance-to-instance.decorator';
export * from './transform-instance-to-plain.decorator';
export * from './transform-plain-to-instance.decorator';
export * from './transform.decorator';
export * from './type.decorator';
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/decorators/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4CAA4C,CAAC;AAC3D,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC","sourcesContent":["export * from './exclude.decorator';\nexport * from './expose.decorator';\nexport * from './transform-instance-to-instance.decorator';\nexport * from './transform-instance-to-plain.decorator';\nexport * from './transform-plain-to-instance.decorator';\nexport * from './transform.decorator';\nexport * from './type.decorator';\n"]}

View File

@@ -0,0 +1,20 @@
import { ClassTransformer } from '../ClassTransformer';
/**
* Return the class instance only with the exposed properties.
*
* Can be applied to functions and getters/setters only.
*/
export function TransformInstanceToInstance(params) {
return function (target, propertyKey, descriptor) {
const classTransformer = new ClassTransformer();
const originalMethod = descriptor.value;
descriptor.value = function (...args) {
const result = originalMethod.apply(this, args);
const isPromise = !!result && (typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function';
return isPromise
? result.then((data) => classTransformer.instanceToInstance(data, params))
: classTransformer.instanceToInstance(result, params);
};
};
}
//# sourceMappingURL=transform-instance-to-instance.decorator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"transform-instance-to-instance.decorator.js","sourceRoot":"","sources":["../../../src/decorators/transform-instance-to-instance.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGvD;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAAC,MAA8B;IACxE,OAAO,UAAU,MAA2B,EAAE,WAA4B,EAAE,UAA8B;QACxG,MAAM,gBAAgB,GAAqB,IAAI,gBAAgB,EAAE,CAAC;QAClE,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC;QAExC,UAAU,CAAC,KAAK,GAAG,UAAU,GAAG,IAAW;YACzC,MAAM,MAAM,GAAQ,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACrD,MAAM,SAAS,GACb,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,UAAU,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC;YAChH,OAAO,SAAS;gBACd,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAC/E,CAAC,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1D,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { ClassTransformer } from '../ClassTransformer';\nimport { ClassTransformOptions } from '../interfaces';\n\n/**\n * Return the class instance only with the exposed properties.\n *\n * Can be applied to functions and getters/setters only.\n */\nexport function TransformInstanceToInstance(params?: ClassTransformOptions): MethodDecorator {\n return function (target: Record<string, any>, propertyKey: string | Symbol, descriptor: PropertyDescriptor): void {\n const classTransformer: ClassTransformer = new ClassTransformer();\n const originalMethod = descriptor.value;\n\n descriptor.value = function (...args: any[]): Record<string, any> {\n const result: any = originalMethod.apply(this, args);\n const isPromise =\n !!result && (typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function';\n return isPromise\n ? result.then((data: any) => classTransformer.instanceToInstance(data, params))\n : classTransformer.instanceToInstance(result, params);\n };\n };\n}\n"]}

View File

@@ -0,0 +1,20 @@
import { ClassTransformer } from '../ClassTransformer';
/**
* Transform the object from class to plain object and return only with the exposed properties.
*
* Can be applied to functions and getters/setters only.
*/
export function TransformInstanceToPlain(params) {
return function (target, propertyKey, descriptor) {
const classTransformer = new ClassTransformer();
const originalMethod = descriptor.value;
descriptor.value = function (...args) {
const result = originalMethod.apply(this, args);
const isPromise = !!result && (typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function';
return isPromise
? result.then((data) => classTransformer.instanceToPlain(data, params))
: classTransformer.instanceToPlain(result, params);
};
};
}
//# sourceMappingURL=transform-instance-to-plain.decorator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"transform-instance-to-plain.decorator.js","sourceRoot":"","sources":["../../../src/decorators/transform-instance-to-plain.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGvD;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAA8B;IACrE,OAAO,UAAU,MAA2B,EAAE,WAA4B,EAAE,UAA8B;QACxG,MAAM,gBAAgB,GAAqB,IAAI,gBAAgB,EAAE,CAAC;QAClE,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC;QAExC,UAAU,CAAC,KAAK,GAAG,UAAU,GAAG,IAAW;YACzC,MAAM,MAAM,GAAQ,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACrD,MAAM,SAAS,GACb,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,UAAU,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC;YAChH,OAAO,SAAS;gBACd,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,gBAAgB,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAC5E,CAAC,CAAC,gBAAgB,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvD,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { ClassTransformer } from '../ClassTransformer';\nimport { ClassTransformOptions } from '../interfaces';\n\n/**\n * Transform the object from class to plain object and return only with the exposed properties.\n *\n * Can be applied to functions and getters/setters only.\n */\nexport function TransformInstanceToPlain(params?: ClassTransformOptions): MethodDecorator {\n return function (target: Record<string, any>, propertyKey: string | Symbol, descriptor: PropertyDescriptor): void {\n const classTransformer: ClassTransformer = new ClassTransformer();\n const originalMethod = descriptor.value;\n\n descriptor.value = function (...args: any[]): Record<string, any> {\n const result: any = originalMethod.apply(this, args);\n const isPromise =\n !!result && (typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function';\n return isPromise\n ? result.then((data: any) => classTransformer.instanceToPlain(data, params))\n : classTransformer.instanceToPlain(result, params);\n };\n };\n}\n"]}

View File

@@ -0,0 +1,20 @@
import { ClassTransformer } from '../ClassTransformer';
/**
* Return the class instance only with the exposed properties.
*
* Can be applied to functions and getters/setters only.
*/
export function TransformPlainToInstance(classType, params) {
return function (target, propertyKey, descriptor) {
const classTransformer = new ClassTransformer();
const originalMethod = descriptor.value;
descriptor.value = function (...args) {
const result = originalMethod.apply(this, args);
const isPromise = !!result && (typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function';
return isPromise
? result.then((data) => classTransformer.plainToInstance(classType, data, params))
: classTransformer.plainToInstance(classType, result, params);
};
};
}
//# sourceMappingURL=transform-plain-to-instance.decorator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"transform-plain-to-instance.decorator.js","sourceRoot":"","sources":["../../../src/decorators/transform-plain-to-instance.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGvD;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CACtC,SAAgC,EAChC,MAA8B;IAE9B,OAAO,UAAU,MAA2B,EAAE,WAA4B,EAAE,UAA8B;QACxG,MAAM,gBAAgB,GAAqB,IAAI,gBAAgB,EAAE,CAAC;QAClE,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC;QAExC,UAAU,CAAC,KAAK,GAAG,UAAU,GAAG,IAAW;YACzC,MAAM,MAAM,GAAQ,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACrD,MAAM,SAAS,GACb,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,UAAU,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC;YAChH,OAAO,SAAS;gBACd,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,gBAAgB,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;gBACvF,CAAC,CAAC,gBAAgB,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAClE,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { ClassTransformer } from '../ClassTransformer';\nimport { ClassTransformOptions, ClassConstructor } from '../interfaces';\n\n/**\n * Return the class instance only with the exposed properties.\n *\n * Can be applied to functions and getters/setters only.\n */\nexport function TransformPlainToInstance(\n classType: ClassConstructor<any>,\n params?: ClassTransformOptions\n): MethodDecorator {\n return function (target: Record<string, any>, propertyKey: string | Symbol, descriptor: PropertyDescriptor): void {\n const classTransformer: ClassTransformer = new ClassTransformer();\n const originalMethod = descriptor.value;\n\n descriptor.value = function (...args: any[]): Record<string, any> {\n const result: any = originalMethod.apply(this, args);\n const isPromise =\n !!result && (typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function';\n return isPromise\n ? result.then((data: any) => classTransformer.plainToInstance(classType, data, params))\n : classTransformer.plainToInstance(classType, result, params);\n };\n };\n}\n"]}

View File

@@ -0,0 +1,17 @@
import { defaultMetadataStorage } from '../storage';
/**
* Defines a custom logic for value transformation.
*
* Can be applied to properties only.
*/
export function Transform(transformFn, options = {}) {
return function (target, propertyName) {
defaultMetadataStorage.addTransformMetadata({
target: target.constructor,
propertyName: propertyName,
transformFn,
options,
});
};
}
//# sourceMappingURL=transform.decorator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"transform.decorator.js","sourceRoot":"","sources":["../../../src/decorators/transform.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAGpD;;;;GAIG;AACH,MAAM,UAAU,SAAS,CACvB,WAA+C,EAC/C,UAA4B,EAAE;IAE9B,OAAO,UAAU,MAAW,EAAE,YAA6B;QACzD,sBAAsB,CAAC,oBAAoB,CAAC;YAC1C,MAAM,EAAE,MAAM,CAAC,WAAW;YAC1B,YAAY,EAAE,YAAsB;YACpC,WAAW;YACX,OAAO;SACR,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { defaultMetadataStorage } from '../storage';\nimport { TransformFnParams, TransformOptions } from '../interfaces';\n\n/**\n * Defines a custom logic for value transformation.\n *\n * Can be applied to properties only.\n */\nexport function Transform(\n transformFn: (params: TransformFnParams) => any,\n options: TransformOptions = {}\n): PropertyDecorator {\n return function (target: any, propertyName: string | Symbol): void {\n defaultMetadataStorage.addTransformMetadata({\n target: target.constructor,\n propertyName: propertyName as string,\n transformFn,\n options,\n });\n };\n}\n"]}

View File

@@ -0,0 +1,20 @@
import { defaultMetadataStorage } from '../storage';
/**
* Specifies a type of the property.
* The given TypeFunction can return a constructor. A discriminator can be given in the options.
*
* Can be applied to properties only.
*/
export function Type(typeFunction, options = {}) {
return function (target, propertyName) {
const reflectedType = Reflect.getMetadata('design:type', target, propertyName);
defaultMetadataStorage.addTypeMetadata({
target: target.constructor,
propertyName: propertyName,
reflectedType,
typeFunction,
options,
});
};
}
//# sourceMappingURL=type.decorator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"type.decorator.js","sourceRoot":"","sources":["../../../src/decorators/type.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAGpD;;;;;GAKG;AACH,MAAM,UAAU,IAAI,CAClB,YAAmD,EACnD,UAAuB,EAAE;IAEzB,OAAO,UAAU,MAAW,EAAE,YAA6B;QACzD,MAAM,aAAa,GAAI,OAAe,CAAC,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;QACxF,sBAAsB,CAAC,eAAe,CAAC;YACrC,MAAM,EAAE,MAAM,CAAC,WAAW;YAC1B,YAAY,EAAE,YAAsB;YACpC,aAAa;YACb,YAAY;YACZ,OAAO;SACR,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { defaultMetadataStorage } from '../storage';\nimport { TypeHelpOptions, TypeOptions } from '../interfaces';\n\n/**\n * Specifies a type of the property.\n * The given TypeFunction can return a constructor. A discriminator can be given in the options.\n *\n * Can be applied to properties only.\n */\nexport function Type(\n typeFunction?: (type?: TypeHelpOptions) => Function,\n options: TypeOptions = {}\n): PropertyDecorator {\n return function (target: any, propertyName: string | Symbol): void {\n const reflectedType = (Reflect as any).getMetadata('design:type', target, propertyName);\n defaultMetadataStorage.addTypeMetadata({\n target: target.constructor,\n propertyName: propertyName as string,\n reflectedType,\n typeFunction,\n options,\n });\n };\n}\n"]}

Some files were not shown because too many files have changed in this diff Show More