first commit
This commit is contained in:
3
json-mapper-class/.gitignore
vendored
Normal file
3
json-mapper-class/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
node_modules/
|
||||
test.ts
|
||||
src/
|
||||
1
json-mapper-class/.pydio
Normal file
1
json-mapper-class/.pydio
Normal file
@@ -0,0 +1 @@
|
||||
8df5a678-3cf4-4606-9f91-a723a276c56c
|
||||
489
json-mapper-class/README.md
Normal file
489
json-mapper-class/README.md
Normal file
@@ -0,0 +1,489 @@
|
||||
# json-mapper-class
|
||||
|
||||
`json-mapper-class` 是类似flutter Json序列化的 **web前端 优雅 解决方案**,用来将接口 json 数据映射到 class 的工具,之后在我们的`TypeScript`项目中,可以通过 **类来为接口返回数据标注类型**,通过修改类属性达到不需要后端修改接口数据字段的情况下,前端来任意定义接口返回字段的效果,解决了实际项目中接口数据与页面深度耦合的过程,并提供其逆过程。
|
||||
|
||||
`json-mapper-class` 是一个独立的插件,可以与任何的 `TypeScript` 项目进行深度的集成(最好是class语法),同时提供了众多的装饰器,让你更加**优雅**的去编写 `TypeScript`,请仔细阅读文档。
|
||||
|
||||
同时为了方便 `json-mapper-class` 的方法 `toClass` 第二个参数的生成,也是为了避免手动编写`json-mapper-class` **标准类 模版代码** 的过程,本人开发第二个插件简化了过程,插件地址(请自信阅读文档):
|
||||
|
||||
> [json-class-interface](https://www.npmjs.com/package/json-class-interface)
|
||||
|
||||
|
||||
下面是一个案例:
|
||||
|
||||
```ts
|
||||
import { property, toClass } from 'json-mapper-class';
|
||||
|
||||
class UserModel {
|
||||
@property('i')
|
||||
id: number;
|
||||
|
||||
@property()
|
||||
name: string;
|
||||
}
|
||||
|
||||
const userRaw = {
|
||||
i: 1234,
|
||||
name: 'name',
|
||||
};
|
||||
|
||||
// 使用 toClass 将 json 转换成 class
|
||||
const userModel = toClass(userRaw, UserModel);
|
||||
// 你将获得如下数据
|
||||
{
|
||||
id: 1234,
|
||||
name: 'name',
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
# 如何安装
|
||||
|
||||
```bash
|
||||
npm i json-mapper-class --save
|
||||
```
|
||||
|
||||
# 使用例子
|
||||
|
||||
## 聚合对象或数组
|
||||
|
||||
如果你想转换一个聚合对象,需要提供目标类。如果该对象的某个属性值是数组,则会递归该数组的所有元素(不管层级有多深),自动转换为目标类的实例。
|
||||
|
||||
列子:
|
||||
|
||||
```ts
|
||||
class NestedModel {
|
||||
@property('e', UserModel)
|
||||
employees: UserModel[];
|
||||
|
||||
@typed(UserModel)
|
||||
@property('u')
|
||||
user: UserModel;
|
||||
}
|
||||
|
||||
const model = toClass(
|
||||
{
|
||||
e: [
|
||||
{ i: 1, n: 'n1' },
|
||||
{ i: 2, n: 'n2' },
|
||||
],
|
||||
u: {
|
||||
i: 1,
|
||||
n: 'name',
|
||||
}
|
||||
},
|
||||
NestedModel,
|
||||
);
|
||||
// you will get like this
|
||||
{
|
||||
employees: [
|
||||
{ id: 1, name: 'n1' },
|
||||
{ id: 2, name: 'n2' },
|
||||
],
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'name'
|
||||
}
|
||||
}
|
||||
|
||||
const model = toPlain(
|
||||
{
|
||||
employees: [
|
||||
{ id: 1, name: 'n1' },
|
||||
{ id: 2, name: 'n2' },
|
||||
],
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'name'
|
||||
}
|
||||
},
|
||||
NestedModel,
|
||||
);
|
||||
// you will get like this
|
||||
{
|
||||
e: [
|
||||
{ i: 1, n: 'n1' },
|
||||
{ i: 2, n: 'n2' },
|
||||
],
|
||||
u: {
|
||||
i: 1,
|
||||
n: 'name'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 其他数据类型转换
|
||||
|
||||
```ts
|
||||
import * as moment from 'moment';
|
||||
|
||||
export class EduModel {
|
||||
@property('i')
|
||||
id: number;
|
||||
|
||||
@property('crt')
|
||||
@deserialize(value => moment(value).format('YYYY-MM-DD HH:mm:ss'))
|
||||
createTime: string;
|
||||
}
|
||||
```
|
||||
|
||||
## 依赖于其他属性值
|
||||
|
||||
```ts
|
||||
class EmailModel {
|
||||
@property('s')
|
||||
site: string;
|
||||
|
||||
@property('e')
|
||||
@deserialize((value, _instance, origin) => `${value}@${origin.s}`)
|
||||
email: string;
|
||||
}
|
||||
```
|
||||
|
||||
# 方法
|
||||
|
||||
## toClass(raw, clazzType, options?) / toClasses(raws, clazzType, options?)
|
||||
|
||||
将一个 json 对象映射成一个类实例
|
||||
|
||||
- `raw` / `raws` `<Object|Array<Object>>` 一个 josn 对象或者 json 对象数据
|
||||
- `clazzType` `<Class>` 类的构造函数
|
||||
- `options?` `<Object>` 配置
|
||||
- `ignoreDeserializer` `<Boolean>` 当设置为 true 时,不会调用使用 @deserialize 装饰器配置的方法
|
||||
- `ignoreBeforeDeserializer` `<Boolean>` 当设置为 true 时,不会调用使用 @beforeDeserialize 装饰器配置的方法
|
||||
- `distinguishNullAndUndefined` `<Boolean>` 当设置为 true 时,区分 null 和 undefined
|
||||
|
||||
示例:
|
||||
|
||||
```ts
|
||||
const userRaw = {
|
||||
i: 1234,
|
||||
name: 'name',
|
||||
};
|
||||
const userRaws = [
|
||||
{
|
||||
i: 1000,
|
||||
name: 'name1',
|
||||
},
|
||||
{
|
||||
i: 2000,
|
||||
name: 'name2',
|
||||
},
|
||||
];
|
||||
const userModel = toClass(userRaw, UserModel);
|
||||
const userModels = toClasses(userRaws, UserModel);
|
||||
```
|
||||
|
||||
## toPlain(instance, clazzType, options?) / toPlains(instances, clazzType, options?)
|
||||
|
||||
将一个类实例或者 json 对象映射成另外一个 json 对象
|
||||
|
||||
- `instance` / `instances` `<Object|Array<Object>>` 一个 json 或类实例,或者一个json或类实例组成的数组
|
||||
- `clazzType` `<Class>` Constructor of the target class
|
||||
- `options?` `<Object>` 类的构造函数
|
||||
- `ignoreSerializer` `<Boolean>` 当设置为 true 时,不会调用使用 @serialize 装饰器配置的方法
|
||||
- `ignoreAfterSerializer` `<Boolean>` 当设置为 true 时,不会调用使用 @afterSerialize 装饰器配置的方法
|
||||
- `distinguishNullAndUndefined` `<Boolean>` 当设置为 true 时,区分 null 和 undefined
|
||||
|
||||
示例:
|
||||
|
||||
```ts
|
||||
const userModel = {
|
||||
id: 1234,
|
||||
name: 'name',
|
||||
};
|
||||
const userModels = [
|
||||
{
|
||||
id: 1000,
|
||||
name: 'name1',
|
||||
},
|
||||
{
|
||||
id: 2000,
|
||||
name: 'name2',
|
||||
},
|
||||
];
|
||||
const userRaw = toPlain(userModel, UserModel);
|
||||
const userRaws = toPlains(userModels, UserModel);
|
||||
```
|
||||
|
||||
# 属性装饰器
|
||||
|
||||
调用不同的方法时,这些装饰器的执行顺序:
|
||||
|
||||
- `toClass/toClasses`: beforeDeserializer => typed(映射成一个类实例) => deserializer
|
||||
- `toPlain/toPlains`: serializer => typed(映射成一个对象) => afterSerializer
|
||||
|
||||
## property(originalKey?, clazzType?, optional = false)
|
||||
|
||||
将一个 key 映射到另外一个 key,如 `n => name`
|
||||
|
||||
- `originalKey` `<string>` 被映射的数据 key, 如果不传则默认同名
|
||||
- `clazzType` `<Class>` 自动将该属性的值映射到一个类实例,相当于调用了 `toClass` 方法
|
||||
- `optional` `<Boolean>` 是否可选
|
||||
|
||||
示例:
|
||||
|
||||
```ts
|
||||
class PropertyModel {
|
||||
@property('i')
|
||||
id: number;
|
||||
|
||||
@property()
|
||||
name: string;
|
||||
|
||||
@property('u', UserModel)
|
||||
user: UserModel;
|
||||
|
||||
@property('t', null, true)
|
||||
timeStamp: number;
|
||||
}
|
||||
|
||||
const model = toClass({ i: 234, name: 'property', u: { i: 123, n: 'name' } }, PropertyModel);
|
||||
// 你将获得如下数据
|
||||
{
|
||||
id: 234,
|
||||
name: 'property',
|
||||
user: {
|
||||
id: 123,
|
||||
name: 'name'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## typed(clazzType)
|
||||
|
||||
设置一个目标类的构造器,相当于 property 装饰器的第二个参数
|
||||
|
||||
- `clazzType` `<Class>` 自动将该属性的值映射到一个类实例,相当于调用了 `toClass` 方法
|
||||
|
||||
示例:
|
||||
|
||||
```ts
|
||||
// 与此设置一致 @property('n', UserModel)
|
||||
class TypedModel {
|
||||
@typed(UserModel)
|
||||
@property('u')
|
||||
user: UserModel;
|
||||
}
|
||||
|
||||
const model = toClass({ u: { i: 123, n: 'name' } }, TypedModel);
|
||||
// 你将获得如下数据
|
||||
{
|
||||
user: {
|
||||
id: 123,
|
||||
name: 'name'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## optional()
|
||||
|
||||
设置一个属性为可选,相当于 property 装饰器的第三个参数
|
||||
|
||||
示例:
|
||||
|
||||
```ts
|
||||
// 与此设置一致 @property('n', null, true)
|
||||
class OptionalModel {
|
||||
@optional()
|
||||
@property('n')
|
||||
name: string;
|
||||
}
|
||||
|
||||
const model = toClass({}, OptionalModel);
|
||||
// 你将获得如下数据
|
||||
{
|
||||
}
|
||||
|
||||
const model = toClass({ n: 'name' }, OptionalModel);
|
||||
// 你将获得如下数据
|
||||
{
|
||||
name: 'name';
|
||||
}
|
||||
```
|
||||
|
||||
## defaultVal(val)
|
||||
|
||||
给当前属性设置默认值
|
||||
|
||||
- `val` `<Any>` 要设置的默认值
|
||||
|
||||
示例:
|
||||
|
||||
```ts
|
||||
class DefaultValModel {
|
||||
@defaultVal(0)
|
||||
@property('i')
|
||||
id: number;
|
||||
}
|
||||
|
||||
const model = toClass({}, DefaultValModel);
|
||||
// 你将获得如下数据
|
||||
{
|
||||
id: 0;
|
||||
}
|
||||
|
||||
const raw = toPLain({}, DefaultValModel);
|
||||
// 你将获得如下数据
|
||||
{
|
||||
i: 0;
|
||||
}
|
||||
```
|
||||
|
||||
## serializeTarget()
|
||||
|
||||
当调 `toPlain` 进行序列化时,用使用当前数据作为基准
|
||||
|
||||
示例:
|
||||
|
||||
```ts
|
||||
class SerializeTargetModel {
|
||||
@serializeTarget()
|
||||
@property('n')
|
||||
name: string;
|
||||
|
||||
@property('n')
|
||||
nick: string;
|
||||
}
|
||||
|
||||
const raw = toPlain(
|
||||
{
|
||||
name: 'name',
|
||||
nick: 'nick',
|
||||
},
|
||||
SerializeTargetModel,
|
||||
);
|
||||
|
||||
// 你将获得如下数据
|
||||
{
|
||||
n: 'name';
|
||||
}
|
||||
```
|
||||
|
||||
## beforeDeserialize(beforeDeserializer, disallowIgnoreBeforeDeserializer = false)
|
||||
|
||||
在 `@typed` 调用之前调用
|
||||
|
||||
- `beforeDeserializer` `<(value: any, instance: any, origin: any) => any>`
|
||||
- `value` `<Any>` 该属性在原始对象中的值
|
||||
- `instance` `<Instance>` 类实例(未完成解析)
|
||||
- `origin` `<Object>` 原始对象
|
||||
- `disallowIgnoreBeforeDeserializer` `<Boolean>` 默认为 false,如果设置为 true,则当调用 `toClass` 时,将强制调用 `@beforeDeserialize` 配置的方法
|
||||
|
||||
示例:
|
||||
|
||||
```ts
|
||||
class BeforeDeserializeModel {
|
||||
@beforeDeserialize((value: any) => JSON.parse(value))
|
||||
@property('m')
|
||||
mail: object;
|
||||
}
|
||||
|
||||
toClass(
|
||||
{
|
||||
m: '{"id":123}',
|
||||
},
|
||||
BeforeDeserializeModel,
|
||||
);
|
||||
|
||||
// 你将获得如下数据
|
||||
{
|
||||
mail: { id: 123 },
|
||||
};
|
||||
```
|
||||
|
||||
## deserialize(deserializer, disallowIgnoreDeserializer =false)
|
||||
|
||||
将原始对象序列化成自定义的数组格式,仅在调用 `toClass/toClasses` 时可用
|
||||
|
||||
- `deserializer` `(value: any, instance: any, origin: any) => any`
|
||||
- `value` `<Any>` 该属性的值经过 `@beforeDeserialize` 和 `@typed` 调用后的结果
|
||||
- `instance` `<Instance>` 类实例(未完成解析)
|
||||
- `origin` `<Object>` A raw object
|
||||
- `disallowIgnoreDeserializer` `<Boolean>` 默认为 false,如果设置为 true,则当调用 `toClass` 时,将强制调用 `@deserialize` 配置的方法
|
||||
|
||||
示例:
|
||||
|
||||
```ts
|
||||
class DeserializeModel {
|
||||
@deserialize((value: string) => `${value}@xxx.com`)
|
||||
@property('m')
|
||||
mail: string;
|
||||
}
|
||||
|
||||
toClass(
|
||||
{
|
||||
m: 'mail',
|
||||
},
|
||||
DeserializeModel,
|
||||
);
|
||||
|
||||
// 你将获得如下数据
|
||||
{
|
||||
mail: 'mail@xxx.com',
|
||||
};
|
||||
```
|
||||
|
||||
## serialize(serializer, disallowIgnoreSerializer = false)
|
||||
|
||||
自定义属性值的序列化方式,仅当调用 `toPlain/toPlains` 时可用
|
||||
|
||||
- `serializer` `(value: any, instance: any, origin: any) => any`
|
||||
- `value` `<Any>` 该属性在类实例中的值
|
||||
- `instance` `<Instance>` 当前类实例
|
||||
- `origin` `<Object>` 一个json对象(未完成序列化)
|
||||
- `disallowIgnoreSerializer` `<Boolean>` 默认为 false,如果设置为 true,则当调用 `toClass` 时,将强制调用 `@serialize` 配置的方法
|
||||
|
||||
Example:
|
||||
|
||||
```ts
|
||||
class SerializeModel {
|
||||
@serialize((mail: string) => mail.replace('@xxx.com', ''))
|
||||
@property('e')
|
||||
mail: string;
|
||||
}
|
||||
|
||||
toPlain(
|
||||
{
|
||||
mail: 'mail@xxx.com',
|
||||
},
|
||||
SerializeModel,
|
||||
);
|
||||
|
||||
// 你将获得如下数据
|
||||
{
|
||||
e: 'mail@xxx.com',
|
||||
}
|
||||
```
|
||||
|
||||
## afterSerialize(afterSerializer, disallowIgnoreAfterSerializer = false)
|
||||
|
||||
Convert a key/value in instance to a target form data, it happened after serializer only
|
||||
|
||||
- `afterSerializer` `(value: any, instance: any, origin: any) => any`
|
||||
- `value` `<Any>` 该属性的值经过 `@serializer` 和 `@typed` 调用后的结果
|
||||
- `instance` `<Instance>` 当前类实例
|
||||
- `origin` `<Object>` 一个json对象(未完成序列化)
|
||||
- `disallowIgnoreAfterSerializer` `<Boolean>` 默认为 false,如果设置为 true,则当调用 `toClass` 时,将强制调用 `@afterSerialize` 配置的方法
|
||||
|
||||
示例:
|
||||
|
||||
```ts
|
||||
class AfterSerializeModel {
|
||||
@afterSerialize((mail: string) => JSON.stringify(mail))
|
||||
@property('e')
|
||||
mail: string;
|
||||
}
|
||||
|
||||
toPlain(
|
||||
{
|
||||
mail: { id: 1000 },
|
||||
},
|
||||
SerializeModel,
|
||||
);
|
||||
|
||||
// 你将获得如下数据
|
||||
{
|
||||
e: '{"id":1000}',
|
||||
};
|
||||
```
|
||||
1
json-mapper-class/dist/.pydio
vendored
Normal file
1
json-mapper-class/dist/.pydio
vendored
Normal file
@@ -0,0 +1 @@
|
||||
391e708b-cc22-49c3-8788-a0be45dd3948
|
||||
10
json-mapper-class/dist/decorators.d.ts
vendored
Normal file
10
json-mapper-class/dist/decorators.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import { StoreItemType } from './typing';
|
||||
export declare function serialize(serializer: StoreItemType['serializer'], disallowIgnore?: boolean): (target: any, propertyKey: string) => void;
|
||||
export declare function deserialize(deserializer: StoreItemType['deserializer'], disallowIgnore?: boolean): (target: any, propertyKey: string) => void;
|
||||
export declare function beforeDeserialize(beforeDeserializer: StoreItemType['beforeDeserializer'], disallowIgnore?: boolean): (target: any, propertyKey: string) => void;
|
||||
export declare function afterSerialize(afterSerializer: StoreItemType['afterSerializer'], disallowIgnore?: boolean): (target: any, propertyKey: string) => void;
|
||||
export declare function serializeTarget(): (target: any, propertyKey: string) => void;
|
||||
export declare function property(originalKey?: string, targetClass?: StoreItemType['targetClass'], isOptional?: boolean): (target: any, propertyKey: string) => void;
|
||||
export declare function typed(targetClass: StoreItemType['targetClass']): (target: any, propertyKey: string) => void;
|
||||
export declare function optional(): (target: any, propertyKey: string) => void;
|
||||
export declare function defaultVal(value: any): (target: any, propertyKey: string) => void;
|
||||
96
json-mapper-class/dist/decorators.js
vendored
Normal file
96
json-mapper-class/dist/decorators.js
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.defaultVal = exports.optional = exports.typed = exports.property = exports.serializeTarget = exports.afterSerialize = exports.beforeDeserialize = exports.deserialize = exports.serialize = void 0;
|
||||
const store_1 = require("./store");
|
||||
function serialize(serializer, disallowIgnore = false) {
|
||||
return (target, propertyKey) => {
|
||||
store_1.setStore(target, {
|
||||
key: propertyKey,
|
||||
serializer,
|
||||
disallowIgnoreSerializer: disallowIgnore,
|
||||
});
|
||||
};
|
||||
}
|
||||
exports.serialize = serialize;
|
||||
function deserialize(deserializer, disallowIgnore = false) {
|
||||
return (target, propertyKey) => {
|
||||
store_1.setStore(target, {
|
||||
key: propertyKey,
|
||||
deserializer,
|
||||
disallowIgnoreDeserializer: disallowIgnore,
|
||||
});
|
||||
};
|
||||
}
|
||||
exports.deserialize = deserialize;
|
||||
function beforeDeserialize(beforeDeserializer, disallowIgnore = false) {
|
||||
return (target, propertyKey) => {
|
||||
store_1.setStore(target, {
|
||||
key: propertyKey,
|
||||
beforeDeserializer,
|
||||
disallowIgnoreBeforeDeserializer: disallowIgnore,
|
||||
});
|
||||
};
|
||||
}
|
||||
exports.beforeDeserialize = beforeDeserialize;
|
||||
function afterSerialize(afterSerializer, disallowIgnore = false) {
|
||||
return (target, propertyKey) => {
|
||||
store_1.setStore(target, {
|
||||
key: propertyKey,
|
||||
afterSerializer,
|
||||
disallowIgnoreAfterSerializer: disallowIgnore,
|
||||
});
|
||||
};
|
||||
}
|
||||
exports.afterSerialize = afterSerialize;
|
||||
function serializeTarget() {
|
||||
return (target, propertyKey) => {
|
||||
store_1.setStore(target, {
|
||||
key: propertyKey,
|
||||
serializeTarget: true,
|
||||
});
|
||||
};
|
||||
}
|
||||
exports.serializeTarget = serializeTarget;
|
||||
function property(originalKey, targetClass, isOptional = false) {
|
||||
return (target, propertyKey) => {
|
||||
const config = {
|
||||
originalKey: originalKey || propertyKey,
|
||||
key: propertyKey,
|
||||
};
|
||||
if (targetClass) {
|
||||
config.targetClass = targetClass.prototype.constructor;
|
||||
}
|
||||
if (isOptional) {
|
||||
config.optional = isOptional;
|
||||
}
|
||||
store_1.setStore(target, config);
|
||||
};
|
||||
}
|
||||
exports.property = property;
|
||||
function typed(targetClass) {
|
||||
return (target, propertyKey) => {
|
||||
store_1.setStore(target, {
|
||||
key: propertyKey,
|
||||
targetClass,
|
||||
});
|
||||
};
|
||||
}
|
||||
exports.typed = typed;
|
||||
function optional() {
|
||||
return (target, propertyKey) => {
|
||||
store_1.setStore(target, {
|
||||
key: propertyKey,
|
||||
optional: true,
|
||||
});
|
||||
};
|
||||
}
|
||||
exports.optional = optional;
|
||||
function defaultVal(value) {
|
||||
return (target, propertyKey) => {
|
||||
store_1.setStore(target, {
|
||||
key: propertyKey,
|
||||
default: value,
|
||||
});
|
||||
};
|
||||
}
|
||||
exports.defaultVal = defaultVal;
|
||||
1
json-mapper-class/dist/decorators.js.map
vendored
Normal file
1
json-mapper-class/dist/decorators.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"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"}
|
||||
4
json-mapper-class/dist/index.d.ts
vendored
Normal file
4
json-mapper-class/dist/index.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './to-class';
|
||||
export * from './to-plain';
|
||||
export * from './decorators';
|
||||
export * from './typing';
|
||||
16
json-mapper-class/dist/index.js
vendored
Normal file
16
json-mapper-class/dist/index.js
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
"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" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("./to-class"), exports);
|
||||
__exportStar(require("./to-plain"), exports);
|
||||
__exportStar(require("./decorators"), exports);
|
||||
__exportStar(require("./typing"), exports);
|
||||
1
json-mapper-class/dist/index.js.map
vendored
Normal file
1
json-mapper-class/dist/index.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6CAA2B;AAC3B,6CAA2B;AAC3B,+CAA6B;AAC7B,2CAAyB"}
|
||||
6
json-mapper-class/dist/store.d.ts
vendored
Normal file
6
json-mapper-class/dist/store.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import { StoreItemOptions, StoreItemType } from './typing';
|
||||
declare const store: Map<Function, Map<string, StoreItemType>>;
|
||||
export declare const originalKeyStores: Map<Function, Map<string, StoreItemOptions[]>>;
|
||||
export declare const keyStores: Map<Function, Map<string, StoreItemType>>;
|
||||
export declare const setStore: (target: Function, options: StoreItemOptions) => void;
|
||||
export default store;
|
||||
19
json-mapper-class/dist/store.js
vendored
Normal file
19
json-mapper-class/dist/store.js
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.setStore = exports.keyStores = exports.originalKeyStores = void 0;
|
||||
const store = new Map();
|
||||
exports.originalKeyStores = new Map();
|
||||
exports.keyStores = new Map();
|
||||
exports.setStore = (target, options) => {
|
||||
const { key, ...rest } = options;
|
||||
const storeKey = target.constructor;
|
||||
const targetStore = store.has(storeKey) ? store.get(storeKey) : new Map();
|
||||
let value = targetStore.has(key) ? targetStore.get(key) : {};
|
||||
value = {
|
||||
...value,
|
||||
...rest,
|
||||
};
|
||||
targetStore.set(key, value);
|
||||
store.set(storeKey, targetStore);
|
||||
};
|
||||
exports.default = store;
|
||||
1
json-mapper-class/dist/store.js.map
vendored
Normal file
1
json-mapper-class/dist/store.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":";;;AAEA,MAAM,KAAK,GAAG,IAAI,GAAG,EAAwC,CAAC;AAEjD,QAAA,iBAAiB,GAAG,IAAI,GAAG,EAA6C,CAAC;AACzE,QAAA,SAAS,GAAG,IAAI,GAAG,EAAwC,CAAC;AAE5D,QAAA,QAAQ,GAAG,CAAC,MAAgB,EAAE,OAAyB,EAAE,EAAE;IACtE,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IACjC,oCAAoC;IACpC,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC;IACpC,sDAAsD;IACtD,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAyB,CAAC;IAEjG,iEAAiE;IACjE,IAAI,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7D,KAAK,GAAG;QACN,GAAG,KAAK;QACR,GAAG,IAAI;KACR,CAAC;IAEF,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC5B,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AACnC,CAAC,CAAC;AAEF,kBAAe,KAAK,CAAC"}
|
||||
4
json-mapper-class/dist/to-class.d.ts
vendored
Normal file
4
json-mapper-class/dist/to-class.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { JosnType, BasicClass, ToClassOptions } from './typing';
|
||||
export declare const arrayItemToClass: <T>(arrayVal: any[], Clazz: BasicClass<T>, options: ToClassOptions) => any;
|
||||
export declare const toClasses: <T>(rawJson: JosnType[], Clazz: BasicClass<T>, options?: ToClassOptions) => T[];
|
||||
export declare const toClass: <T>(rawJson: JosnType, Clazz: BasicClass<T>, options?: ToClassOptions) => T;
|
||||
61
json-mapper-class/dist/to-class.js
vendored
Normal file
61
json-mapper-class/dist/to-class.js
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.toClass = exports.toClasses = exports.arrayItemToClass = void 0;
|
||||
const isarray_1 = __importDefault(require("isarray"));
|
||||
const utils_1 = require("./utils");
|
||||
exports.arrayItemToClass = (arrayVal, Clazz, options) => {
|
||||
return arrayVal.map((v) => isarray_1.default(v) ? exports.arrayItemToClass(v, Clazz, options) : objectToClass(v, Clazz, options));
|
||||
};
|
||||
const objectToClass = (jsonObj, Clazz, options) => {
|
||||
const instance = new Clazz();
|
||||
const originalKeyStore = utils_1.getOriginalKeyStore(Clazz);
|
||||
originalKeyStore.forEach((propertiesOptions, originalKey) => {
|
||||
const originalValue = jsonObj[originalKey];
|
||||
propertiesOptions.forEach((storeItemoptions) => {
|
||||
const { key, beforeDeserializer, deserializer, targetClass, optional } = storeItemoptions;
|
||||
const disallowIgnoreDeserializer = storeItemoptions.disallowIgnoreDeserializer || !options.ignoreDeserializer;
|
||||
const disallowIgnoreBeforeDeserializer = storeItemoptions.disallowIgnoreBeforeDeserializer || !options.ignoreBeforeDeserializer;
|
||||
const isValueNotExist = options.distinguishNullAndUndefined ? utils_1.isUndefined : utils_1.isNullOrUndefined;
|
||||
let value = originalValue;
|
||||
if (isValueNotExist(value)) {
|
||||
if (!isValueNotExist(storeItemoptions.default)) {
|
||||
instance[key] = storeItemoptions.default;
|
||||
return;
|
||||
}
|
||||
if (!optional) {
|
||||
throw new Error(`Can't map '${originalKey}' to ${Clazz.name}.${key}, property '${originalKey}' not found`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
value =
|
||||
beforeDeserializer && disallowIgnoreBeforeDeserializer
|
||||
? beforeDeserializer(value, instance, jsonObj, options)
|
||||
: value;
|
||||
if (value && targetClass) {
|
||||
if (isarray_1.default(value)) {
|
||||
value = exports.arrayItemToClass(value, targetClass, options);
|
||||
}
|
||||
else {
|
||||
value = exports.toClass(value, targetClass, options);
|
||||
}
|
||||
}
|
||||
instance[key] =
|
||||
deserializer && disallowIgnoreDeserializer ? deserializer(value, instance, jsonObj, options) : value;
|
||||
});
|
||||
});
|
||||
return instance;
|
||||
};
|
||||
exports.toClasses = (rawJson, Clazz, options = {}) => {
|
||||
if (!isarray_1.default(rawJson)) {
|
||||
throw new Error(`rawJson ${rawJson} must be an array`);
|
||||
}
|
||||
const { constructor } = Clazz.prototype;
|
||||
return rawJson.map((item) => objectToClass(item, constructor, options));
|
||||
};
|
||||
exports.toClass = (rawJson, Clazz, options = {}) => {
|
||||
const { constructor } = Clazz.prototype;
|
||||
return objectToClass(rawJson, constructor, options);
|
||||
};
|
||||
1
json-mapper-class/dist/to-class.js.map
vendored
Normal file
1
json-mapper-class/dist/to-class.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"to-class.js","sourceRoot":"","sources":["../src/to-class.ts"],"names":[],"mappings":"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"}
|
||||
4
json-mapper-class/dist/to-plain.d.ts
vendored
Normal file
4
json-mapper-class/dist/to-plain.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { JosnType, BasicClass, ToPlainOptions } from './typing';
|
||||
export declare const arrayItemToObject: <T>(arrayVal: any[], Clazz: BasicClass<T>, options: ToPlainOptions) => any;
|
||||
export declare const toPlains: <T>(instances: (JosnType | T)[], Clazz: BasicClass<T>, options?: ToPlainOptions) => any[];
|
||||
export declare const toPlain: <T>(instance: JosnType | T, Clazz: BasicClass<T>, options?: ToPlainOptions) => any;
|
||||
49
json-mapper-class/dist/to-plain.js
vendored
Normal file
49
json-mapper-class/dist/to-plain.js
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.toPlain = exports.toPlains = exports.arrayItemToObject = void 0;
|
||||
const isarray_1 = __importDefault(require("isarray"));
|
||||
const utils_1 = require("./utils");
|
||||
exports.arrayItemToObject = (arrayVal, Clazz, options) => {
|
||||
return arrayVal.map((v) => isarray_1.default(v) ? exports.arrayItemToObject(v, Clazz, options) : classToObject(v, Clazz, options));
|
||||
};
|
||||
const classToObject = (instance, Clazz, options) => {
|
||||
const obj = {};
|
||||
const keyStore = utils_1.getKeyStore(Clazz);
|
||||
keyStore.forEach((propertiesOption, key) => {
|
||||
const isValueNotExist = options.distinguishNullAndUndefined ? utils_1.isUndefined : utils_1.isNullOrUndefined;
|
||||
const instanceValue = isValueNotExist(instance[key]) ? propertiesOption.default : instance[key];
|
||||
const { originalKey, afterSerializer, serializer, targetClass, optional } = propertiesOption;
|
||||
const disallowIgnoreSerializer = propertiesOption.disallowIgnoreSerializer || !options.ignoreSerializer;
|
||||
const disallowIgnoreAfterSerializer = propertiesOption.disallowIgnoreAfterSerializer || !options.ignoreAfterSerializer;
|
||||
if (isValueNotExist(instanceValue)) {
|
||||
if (!optional) {
|
||||
throw new Error(`Property '${Clazz.name}.${key}' not found`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
let value = serializer && disallowIgnoreSerializer ? serializer(instanceValue, instance, obj, options) : instanceValue;
|
||||
if (value && targetClass) {
|
||||
if (isarray_1.default(value)) {
|
||||
value = exports.arrayItemToObject(value, targetClass, options);
|
||||
}
|
||||
else {
|
||||
value = exports.toPlain(value, targetClass, options);
|
||||
}
|
||||
}
|
||||
obj[originalKey] =
|
||||
afterSerializer && disallowIgnoreAfterSerializer ? afterSerializer(value, instance, obj, options) : value;
|
||||
});
|
||||
return obj;
|
||||
};
|
||||
exports.toPlains = (instances, Clazz, options = {}) => {
|
||||
if (!isarray_1.default(instances)) {
|
||||
throw new Error(`${Clazz} instances must be an array`);
|
||||
}
|
||||
return instances.map((item) => classToObject(item, Clazz, options));
|
||||
};
|
||||
exports.toPlain = (instance, Clazz, options = {}) => {
|
||||
return classToObject(instance, Clazz, options);
|
||||
};
|
||||
1
json-mapper-class/dist/to-plain.js.map
vendored
Normal file
1
json-mapper-class/dist/to-plain.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"to-plain.js","sourceRoot":"","sources":["../src/to-plain.ts"],"names":[],"mappings":";;;;;;AAAA,sDAA8B;AAC9B,mCAAsE;AAGzD,QAAA,iBAAiB,GAAG,CAAI,QAAe,EAAE,KAAoB,EAAE,OAAuB,EAAO,EAAE;IAC1G,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE;IAC7B,mEAAmE;IACnE,iBAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,yBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CACrF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAI,QAAkB,EAAE,KAAoB,EAAE,OAAuB,EAAY,EAAE;IACvG,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,QAAQ,GAAG,mBAAW,CAAC,KAAK,CAAC,CAAC;IACpC,QAAQ,CAAC,OAAO,CAAC,CAAC,gBAA+B,EAAE,GAAmB,EAAE,EAAE;QACxE,MAAM,eAAe,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC,CAAC,mBAAW,CAAC,CAAC,CAAC,yBAAiB,CAAC;QAC9F,MAAM,aAAa,GAAG,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAChG,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,gBAAgB,CAAC;QAC7F,MAAM,wBAAwB,GAAG,gBAAgB,CAAC,wBAAwB,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC;QACxG,MAAM,6BAA6B,GACjC,gBAAgB,CAAC,6BAA6B,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC;QAEnF,IAAI,eAAe,CAAC,aAAa,CAAC,EAAE;YAClC,IAAI,CAAC,QAAQ,EAAE;gBACb,MAAM,IAAI,KAAK,CAAC,aAAa,KAAK,CAAC,IAAI,IAAI,GAAG,aAAa,CAAC,CAAC;aAC9D;YACD,OAAO;SACR;QACD,IAAI,KAAK,GACP,UAAU,IAAI,wBAAwB,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;QAC7G,IAAI,KAAK,IAAI,WAAW,EAAE;YACxB,IAAI,iBAAO,CAAC,KAAK,CAAC,EAAE;gBAClB,KAAK,GAAG,yBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;aACxD;iBAAM;gBACL,mEAAmE;gBACnE,KAAK,GAAG,eAAO,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;aAC9C;SACF;QACD,GAAG,CAAC,WAAW,CAAC;YACd,eAAe,IAAI,6BAA6B,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC9G,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEW,QAAA,QAAQ,GAAG,CAAI,SAA2B,EAAE,KAAoB,EAAE,UAA0B,EAAE,EAAS,EAAE;IACpH,IAAI,CAAC,iBAAO,CAAC,SAAS,CAAC,EAAE;QACvB,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,6BAA6B,CAAC,CAAC;KACxD;IACD,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,IAAc,EAAE,EAAE,CAAC,aAAa,CAAI,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;AACnF,CAAC,CAAC;AAEW,QAAA,OAAO,GAAG,CAAI,QAAsB,EAAE,KAAoB,EAAE,UAA0B,EAAE,EAAO,EAAE;IAC5G,OAAO,aAAa,CAAI,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC,CAAC"}
|
||||
35
json-mapper-class/dist/typing.d.ts
vendored
Normal file
35
json-mapper-class/dist/typing.d.ts
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
export declare type StoreItemType = {
|
||||
originalKey?: string;
|
||||
targetClass?: BasicClass;
|
||||
serializer?: (value: any, instance: any, origin: any, options: ToPlainOptions) => any;
|
||||
disallowIgnoreSerializer?: boolean;
|
||||
afterSerializer?: (value: any, instance: any, origin: any, options: ToPlainOptions) => any;
|
||||
disallowIgnoreAfterSerializer?: boolean;
|
||||
deserializer?: (value: any, instance: any, origin: any, options: ToClassOptions) => any;
|
||||
disallowIgnoreDeserializer?: boolean;
|
||||
beforeDeserializer?: (value: any, instance: any, origin: any, options: ToClassOptions) => any;
|
||||
disallowIgnoreBeforeDeserializer?: boolean;
|
||||
default?: any;
|
||||
autoTypeDetection?: boolean;
|
||||
optional?: boolean;
|
||||
serializeTarget?: boolean;
|
||||
};
|
||||
export declare type StoreItemOptions = StoreItemType & {
|
||||
key: string;
|
||||
};
|
||||
export declare type BasicClass<T = any> = {
|
||||
new (...args: any[]): T;
|
||||
};
|
||||
export declare type JosnType = {
|
||||
[key: string]: any;
|
||||
};
|
||||
export interface ToClassOptions {
|
||||
ignoreDeserializer?: boolean;
|
||||
ignoreBeforeDeserializer?: boolean;
|
||||
distinguishNullAndUndefined?: boolean;
|
||||
}
|
||||
export interface ToPlainOptions {
|
||||
ignoreSerializer?: boolean;
|
||||
ignoreAfterSerializer?: boolean;
|
||||
distinguishNullAndUndefined?: boolean;
|
||||
}
|
||||
2
json-mapper-class/dist/typing.js
vendored
Normal file
2
json-mapper-class/dist/typing.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
1
json-mapper-class/dist/typing.js.map
vendored
Normal file
1
json-mapper-class/dist/typing.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"typing.js","sourceRoot":"","sources":["../src/typing.ts"],"names":[],"mappings":""}
|
||||
6
json-mapper-class/dist/utils.d.ts
vendored
Normal file
6
json-mapper-class/dist/utils.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import { StoreItemOptions, StoreItemType, BasicClass } from './typing';
|
||||
export declare const isNull: (val: any) => boolean;
|
||||
export declare const isUndefined: (val: any) => boolean;
|
||||
export declare const isNullOrUndefined: (val: any) => boolean;
|
||||
export declare const getOriginalKeyStore: <T>(Clazz: BasicClass<T>) => Map<string, StoreItemOptions[]>;
|
||||
export declare const getKeyStore: <T>(Clazz: BasicClass<T>) => Map<string, StoreItemType>;
|
||||
82
json-mapper-class/dist/utils.js
vendored
Normal file
82
json-mapper-class/dist/utils.js
vendored
Normal 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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getKeyStore = exports.getOriginalKeyStore = exports.isNullOrUndefined = exports.isUndefined = exports.isNull = void 0;
|
||||
const store_1 = __importStar(require("./store"));
|
||||
exports.isNull = (val) => val === null;
|
||||
exports.isUndefined = (val) => val === undefined;
|
||||
exports.isNullOrUndefined = (val) => exports.isNull(val) || exports.isUndefined(val);
|
||||
exports.getOriginalKeyStore = (Clazz) => {
|
||||
let curLayer = Clazz;
|
||||
const cacheOriginalKeyStore = store_1.originalKeyStores.get(curLayer);
|
||||
if (cacheOriginalKeyStore) {
|
||||
return cacheOriginalKeyStore;
|
||||
}
|
||||
const originalKeyStore = new Map();
|
||||
while (curLayer.name && curLayer.prototype) {
|
||||
const { constructor } = curLayer.prototype;
|
||||
const targetStore = store_1.default.get(constructor);
|
||||
if (targetStore) {
|
||||
targetStore.forEach((storeItem, key) => {
|
||||
const item = {
|
||||
key,
|
||||
...storeItem,
|
||||
};
|
||||
if (!originalKeyStore.has(storeItem.originalKey)) {
|
||||
originalKeyStore.set(storeItem.originalKey, [item]);
|
||||
}
|
||||
else {
|
||||
const exists = originalKeyStore.get(storeItem.originalKey);
|
||||
if (!exists.find((exist) => exist.key === key)) {
|
||||
originalKeyStore.set(storeItem.originalKey, [...originalKeyStore.get(storeItem.originalKey), item]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
curLayer = Object.getPrototypeOf(constructor);
|
||||
}
|
||||
store_1.originalKeyStores.set(Clazz, originalKeyStore);
|
||||
return originalKeyStore;
|
||||
};
|
||||
exports.getKeyStore = (Clazz) => {
|
||||
const cacheKeyStore = store_1.keyStores.get(Clazz);
|
||||
if (cacheKeyStore) {
|
||||
return cacheKeyStore;
|
||||
}
|
||||
const keyStore = new Map();
|
||||
const originalKeyStore = exports.getOriginalKeyStore(Clazz);
|
||||
originalKeyStore.forEach(storeItems => {
|
||||
const [firstStoreItem] = storeItems;
|
||||
if (storeItems.length === 1) {
|
||||
keyStore.set(firstStoreItem.key, firstStoreItem);
|
||||
}
|
||||
else {
|
||||
const hasStoreItems = storeItems.filter(storeItem => storeItem.serializeTarget);
|
||||
if (hasStoreItems.length !== 1) {
|
||||
throw new Error(`Only one of keys(${storeItems.map(storeItem => storeItem.key).join(', ')}) in ${Clazz.name} can contain a serializeTarget when use toPlain`);
|
||||
}
|
||||
const hasStoreItem = hasStoreItems[0];
|
||||
keyStore.set(hasStoreItem.key, hasStoreItem);
|
||||
}
|
||||
});
|
||||
store_1.keyStores.set(Clazz, keyStore);
|
||||
return keyStore;
|
||||
};
|
||||
1
json-mapper-class/dist/utils.js.map
vendored
Normal file
1
json-mapper-class/dist/utils.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
||||
27
json-mapper-class/package.json
Normal file
27
json-mapper-class/package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "json-mapper-class",
|
||||
"version": "1.0.2",
|
||||
"description": "Json Mapper To Class",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"dev": "ts-node test.ts",
|
||||
"publish": "npm publish"
|
||||
},
|
||||
"keywords": [
|
||||
"class",
|
||||
"json",
|
||||
"mapper",
|
||||
"typescript"
|
||||
],
|
||||
"dependencies": {
|
||||
"isarray": "^2.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/isarray": "^2.0.0",
|
||||
"@types/node": "^12.12.50",
|
||||
"moment": "^2.27.0",
|
||||
"ts-node": "^8.10.2",
|
||||
"typescript": "^3.9.7"
|
||||
}
|
||||
}
|
||||
19
json-mapper-class/tsconfig.json
Normal file
19
json-mapper-class/tsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "commonjs",
|
||||
"resolveJsonModule": true,
|
||||
"moduleResolution": "node",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"esModuleInterop": true,
|
||||
"sourceMap": false,
|
||||
"noImplicitAny": true,
|
||||
"removeComments": true,
|
||||
"declaration": true,
|
||||
"outDir": "./dist",
|
||||
"lib": ["es6"]
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
Reference in New Issue
Block a user