@smartsoft001/models 2.44.0 → 2.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.json CHANGED
@@ -15,16 +15,9 @@
15
15
  "rules": {}
16
16
  },
17
17
  {
18
- "files": ["*.json"],
18
+ "files": "package.json",
19
19
  "parser": "jsonc-eslint-parser",
20
- "rules": {
21
- "@nx/dependency-checks": [
22
- "error",
23
- {
24
- "ignoredFiles": ["{projectRoot}/esbuild.config.{js,ts,mjs,mts}"]
25
- }
26
- ]
27
- }
20
+ "rules": {}
28
21
  }
29
22
  ]
30
23
  }
package/README.md CHANGED
@@ -1,11 +1,28 @@
1
- # models
1
+ ## Decorators
2
+ ### @Model Decorator
3
+ Used to annotate a class as a "model," adding metadata and a custom toJSON method. This method serializes the instance
4
+ into JSON format, including fields marked with specific metadata. Associates the model with metadata (IModelOptions)
5
+ using reflection, allowing for dynamic handling of models at runtime.
2
6
 
3
- This library was generated with [Nx](https://nx.dev).
7
+ ### @Field Decorator
8
+ Used to annotate properties of a model class, providing additional metadata (IFieldOptions) such as field type,
9
+ requirements, and custom behavior for serialization or validation. Defines how properties should be accessed, mutated,
10
+ and serialized, including special handling for arrays and specific types.
4
11
 
5
- ## Building
12
+ ## Utility Functions
13
+ ### Metadata Retrieval
14
+ Functions like **getModelFieldKeys**, **getModelFieldOptions**, **getModelFieldsWithOptions**, and **getModelOptions**
15
+ are used to retrieve metadata about models and their fields. This enables dynamic inspection and manipulation of models.
6
16
 
7
- Run `nx build models` to build the library.
17
+ ### Model Validation
18
+ **getInvalidFields** - Checks for fields that have invalid values based on specified rules
19
+ (such as being required during "create" or "update" operations) and permissions. This is useful for form validation or
20
+ API input validation.
8
21
 
9
- ## Running unit tests
22
+ ### Model Casting
23
+ **castModel** - Adjusts an instance of a model by removing fields that do not conform to the specified mode
24
+ ("create", "update") or the provided permissions. This ensures the instance is valid and adheres to the constraints
25
+ defined by the model's metadata.
10
26
 
11
- Run `nx test models` to execute the unit tests via [Jest](https://jestjs.io).
27
+ ### Model Check
28
+ **isModel** - Determines if an object is a model decorated with the @Model decorator.
package/package.json CHANGED
@@ -4,9 +4,9 @@
4
4
  "dependencies": {
5
5
  "reflect-metadata": "^0.2.1",
6
6
  "rxjs": "^7.8.1",
7
- "@smartsoft001/utils": "^2.44.0"
7
+ "@smartsoft001/utils": "^2.46.0"
8
8
  },
9
- "version": "2.44.0",
9
+ "version": "2.46.0",
10
10
  "main": "./src/index.js",
11
11
  "typings": "./src/index.d.ts"
12
12
  }
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- export * from "./lib/symbols";
1
+ export * from './lib/symbols';
2
2
  export * from './lib/interfaces';
3
3
  export * from './lib/decorators';
4
4
 
@@ -1,55 +1,57 @@
1
1
  import 'reflect-metadata';
2
2
 
3
- import {ObjectService} from "@smartsoft001/utils";
3
+ import { ObjectService } from '@smartsoft001/utils';
4
4
 
5
- import * as symbols from "../../symbols";
6
- import {FieldType, IFieldOptions} from "../../interfaces";
5
+ import { FieldType, IFieldOptions } from '../../interfaces';
6
+ import * as symbols from '../../symbols';
7
7
 
8
8
  export const Field = FieldDecorator;
9
9
  export function FieldDecorator(options?: IFieldOptions) {
10
- return <T>(target: T, key: string) => {
11
-
12
- options = options ? { ...options } : {};
13
-
14
- if (!(target as any).constructor['__fields']) {
15
- (target as any).constructor['__fields'] = {};
16
- }
17
-
18
- (target as any).constructor['__fields'][key] = true;
19
-
20
- if (!options.type && key === 'password') {
21
- options.type = FieldType.password;
22
- } else if (!options.type) {
23
- options.type = FieldType.text;
24
- }
25
-
26
- if (options.classType) {
27
- (target as any)['_' + key] = (target as any)[key];
28
- delete (target as any)[key];
29
-
30
- Object.defineProperty(target, key, {
31
- get: function () {
32
- if (!this['_' + key] && options?.type === FieldType.array) {
33
- this['_' + key] = [];
34
- }
35
- return this['_' + key];
36
- },
37
- set: function (v: any) {
38
- this['_' + key] = options?.type === FieldType.array && v ?
39
- v.map((i: any) => ObjectService.createByType(i, options?.classType))
40
- : ObjectService.createByType(v, options?.classType);
41
- },
42
- enumerable: true,
43
- configurable: true
44
- });
45
-
46
- if (!(target as any).constructor['__properties']) {
47
- (target as any).constructor['__properties'] = {};
48
- }
49
-
50
- (target as any).constructor['__properties'][key] = true;
51
- }
52
-
53
- Reflect.defineMetadata(symbols.SYMBOL_FIELD, options, target as any, key);
10
+ return <T>(target: T, key: string) => {
11
+ options = options ? { ...options } : {};
12
+
13
+ if (!(target as any).constructor['__fields']) {
14
+ (target as any).constructor['__fields'] = {};
15
+ }
16
+
17
+ (target as any).constructor['__fields'][key] = true;
18
+
19
+ if (!options.type && key === 'password') {
20
+ options.type = FieldType.password;
21
+ } else if (!options.type) {
22
+ options.type = FieldType.text;
54
23
  }
24
+
25
+ if (options.classType) {
26
+ (target as any)['_' + key] = (target as any)[key];
27
+ delete (target as any)[key];
28
+
29
+ Object.defineProperty(target, key, {
30
+ get: function () {
31
+ if (!this['_' + key] && options?.type === FieldType.array) {
32
+ this['_' + key] = [];
33
+ }
34
+ return this['_' + key];
35
+ },
36
+ set: function (v: any) {
37
+ this['_' + key] =
38
+ options?.type === FieldType.array && v
39
+ ? v.map((i: any) =>
40
+ ObjectService.createByType(i, options?.classType),
41
+ )
42
+ : ObjectService.createByType(v, options?.classType);
43
+ },
44
+ enumerable: true,
45
+ configurable: true,
46
+ });
47
+
48
+ if (!(target as any).constructor['__properties']) {
49
+ (target as any).constructor['__properties'] = {};
50
+ }
51
+
52
+ (target as any).constructor['__properties'][key] = true;
53
+ }
54
+
55
+ Reflect.defineMetadata(symbols.SYMBOL_FIELD, options, target as any, key);
56
+ };
55
57
  }
@@ -1,11 +1,11 @@
1
1
  import 'reflect-metadata';
2
2
 
3
- import * as symbols from "../../symbols";
4
- import {IModelOptions} from "../../interfaces";
3
+ import { IModelOptions } from '../../interfaces';
4
+ import * as symbols from '../../symbols';
5
5
 
6
6
  export const Model = ModelDecorator;
7
7
  export function ModelDecorator(options?: IModelOptions) {
8
- return function<T>(target: any) {
8
+ return function <T>(target: any) {
9
9
  options = options ? { ...options } : {};
10
10
 
11
11
  Reflect.defineMetadata(symbols.SYMBOL_MODEL, options, target);
@@ -14,12 +14,12 @@ export function ModelDecorator(options?: IModelOptions) {
14
14
  const result = { ...this };
15
15
 
16
16
  if (this.constructor['__properties']) {
17
- Object.keys(this.constructor['__properties']).forEach(protoKey => {
17
+ Object.keys(this.constructor['__properties']).forEach((protoKey) => {
18
18
  result[protoKey] = this['_' + protoKey];
19
19
  });
20
20
  }
21
21
 
22
22
  return result;
23
23
  };
24
- }
24
+ };
25
25
  }
@@ -1,152 +1,154 @@
1
- import {Observable} from "rxjs";
1
+ import { Observable } from 'rxjs';
2
2
 
3
3
  export enum FieldTypeDef {
4
- address = "address",
5
- currency = "currency",
6
- date = "date",
7
- dateTime = "dateTime",
8
- dateWithEdit = "dateWithEdit",
9
- email = "email",
10
- enum = "enum",
11
- file = "file",
12
- flag = "flag",
13
- int = "int",
14
- nip = "nip",
15
- object = "object",
16
- array = "array",
17
- password = "password",
18
- radio = "radio",
19
- text = "text",
20
- strings = "strings",
21
- ints = "ints",
22
- longText = "longText",
23
- color = "color",
24
- logo = "logo",
25
- check = "check",
26
- phoneNumber = "phoneNumber",
27
- phoneNumberPl = "phoneNumberPl",
28
- pesel = "pesel",
29
- pdf = "pdf",
30
- video = "video",
31
- attachment = "attachment",
32
- dateRange = "dateRange",
33
- image = "image",
34
- float = "float"
4
+ address = 'address',
5
+ currency = 'currency',
6
+ date = 'date',
7
+ dateTime = 'dateTime',
8
+ dateWithEdit = 'dateWithEdit',
9
+ email = 'email',
10
+ enum = 'enum',
11
+ file = 'file',
12
+ flag = 'flag',
13
+ int = 'int',
14
+ nip = 'nip',
15
+ object = 'object',
16
+ array = 'array',
17
+ password = 'password',
18
+ radio = 'radio',
19
+ text = 'text',
20
+ strings = 'strings',
21
+ ints = 'ints',
22
+ longText = 'longText',
23
+ color = 'color',
24
+ logo = 'logo',
25
+ check = 'check',
26
+ phoneNumber = 'phoneNumber',
27
+ phoneNumberPl = 'phoneNumberPl',
28
+ pesel = 'pesel',
29
+ pdf = 'pdf',
30
+ video = 'video',
31
+ attachment = 'attachment',
32
+ dateRange = 'dateRange',
33
+ image = 'image',
34
+ float = 'float',
35
35
  }
36
36
  export const FieldType: typeof FieldTypeDef = FieldTypeDef;
37
37
 
38
38
  export interface ISpecification {
39
- readonly criteria: any;
39
+ readonly criteria: any;
40
40
  }
41
41
 
42
42
  export interface IModelFilter {
43
- label?: string;
44
- fieldType?: FieldTypeDef;
45
- key: string;
46
- type: '=' | '!=' | '>=' | '<=' | '<' | '>' | '~=';
47
- possibilities$?: Observable<{ id: any, text: string }[]>;
43
+ label?: string;
44
+ fieldType?: FieldTypeDef;
45
+ key: string;
46
+ type: '=' | '!=' | '>=' | '<=' | '<' | '>' | '~=';
47
+ possibilities$?: Observable<{ id: any; text: string }[]>;
48
48
  }
49
49
 
50
50
  export interface IModelStep {
51
- number: number;
52
- name: string;
51
+ number: number;
52
+ name: string;
53
53
  }
54
54
 
55
55
  export interface IModelMetadata {
56
- titleKey?: string;
57
- permissions?: Array<string>;
58
- filters?: Array<IModelFilter>;
56
+ titleKey?: string;
57
+ permissions?: Array<string>;
58
+ filters?: Array<IModelFilter>;
59
59
  }
60
60
 
61
61
  export interface IFieldMetadata extends IFieldModifyMetadata {
62
- type?: FieldTypeDef;
63
- classType?: any;
64
- possibilities?: Array<any> | any;
62
+ type?: FieldTypeDef;
63
+ classType?: any;
64
+ possibilities?: Array<any> | any;
65
65
  }
66
66
 
67
67
  export interface IFieldModifyMetadata {
68
- required?: boolean;
69
- focused?: boolean;
70
- confirm?: boolean;
71
- permissions?: Array<string>;
72
- unique?: boolean | IFieldUniqueMetadata;
73
- defaltValue?: () => any;
74
- enabled?: ISpecification;
75
- hide?: boolean;
76
- /**
77
- * @desc - Model step configuration
78
- */
79
- step?: IModelStep;
68
+ required?: boolean;
69
+ focused?: boolean;
70
+ confirm?: boolean;
71
+ permissions?: Array<string>;
72
+ unique?: boolean | IFieldUniqueMetadata;
73
+ defaltValue?: () => any;
74
+ enabled?: ISpecification;
75
+ hide?: boolean;
76
+ /**
77
+ * @desc - Model step configuration
78
+ */
79
+ step?: IModelStep;
80
80
  }
81
81
 
82
82
  export interface IFieldEditMetadata extends IFieldModifyMetadata {
83
- multi?: boolean;
83
+ multi?: boolean;
84
84
  }
85
85
 
86
86
  export interface IFieldListMetadata {
87
- order?: number;
88
- filter?: boolean;
89
- permissions?: Array<string>;
90
- /**
91
- * Configuration for dynamic list table data
92
- * @param {string} dynamic.headerKey - column header object key
93
- * @param {string} dynamic.rowKey - column row value object key
94
- */
95
- dynamic?: { headerKey: string, rowKey: string }
87
+ order?: number;
88
+ filter?: boolean;
89
+ permissions?: Array<string>;
90
+ /**
91
+ * Configuration for dynamic list table data
92
+ * @param {string} dynamic.headerKey - column header object key
93
+ * @param {string} dynamic.rowKey - column row value object key
94
+ */
95
+ dynamic?: { headerKey: string; rowKey: string };
96
96
  }
97
97
 
98
98
  export interface IFieldDetailsMetadata {
99
- order?: number;
100
- permissions?: Array<string>;
101
- enabled?: ISpecification;
99
+ order?: number;
100
+ permissions?: Array<string>;
101
+ enabled?: ISpecification;
102
102
  }
103
103
 
104
104
  export interface IModelOptions {
105
- titleKey?: string;
106
- filters?: Array<IModelFilter>;
107
- create?: IModelModeOptions;
108
- update?: IModelModeOptions;
109
- list?: IModelModeOptions;
110
- details?: IModelModeOptions;
111
- remove?: IModelModeOptions;
112
- customs?: Array<IModelModeOptionsCustom>;
113
- /**
114
- * @desc - Allow export field data
115
- */
116
- export?: boolean;
117
- /**
118
- * @desc - Allow import field data
119
- */
120
- import?: boolean;
105
+ titleKey?: string;
106
+ filters?: Array<IModelFilter>;
107
+ create?: IModelModeOptions;
108
+ update?: IModelModeOptions;
109
+ list?: IModelModeOptions;
110
+ details?: IModelModeOptions;
111
+ remove?: IModelModeOptions;
112
+ customs?: Array<IModelModeOptionsCustom>;
113
+ /**
114
+ * @desc - Allow export field data
115
+ */
116
+ export?: boolean;
117
+ /**
118
+ * @desc - Allow import field data
119
+ */
120
+ import?: boolean;
121
121
  }
122
122
 
123
123
  export interface IModelModeOptions {
124
- permissions?: Array<string>;
125
- enabled?: ISpecification;
124
+ permissions?: Array<string>;
125
+ enabled?: ISpecification;
126
126
  }
127
127
 
128
128
  export interface IModelModeOptionsCustom extends IModelModeOptions {
129
- mode: string;
129
+ mode: string;
130
130
  }
131
131
 
132
132
  export interface IFieldOptions extends IFieldMetadata {
133
- create?: IFieldModifyMetadata | boolean;
134
- update?: IFieldEditMetadata | boolean;
135
- list?: IFieldListMetadata | boolean;
136
- details?: IFieldDetailsMetadata | boolean;
137
- customs?: Array<IModelMetadataCustom>;
138
- search?: boolean;
139
- info?: string;
133
+ create?: IFieldModifyMetadata | boolean;
134
+ update?: IFieldEditMetadata | boolean;
135
+ list?: IFieldListMetadata | boolean;
136
+ details?: IFieldDetailsMetadata | boolean;
137
+ customs?: Array<IModelMetadataCustom>;
138
+ search?: boolean;
139
+ info?: string;
140
140
  }
141
141
 
142
142
  export interface IModelMetadataCustom extends IModelMetadata {
143
- mode: string
143
+ mode: string;
144
144
  }
145
145
 
146
146
  export interface IFieldUniqueMetadata {
147
- withFields?: Array<string>;
147
+ withFields?: Array<string>;
148
148
  }
149
149
 
150
- export interface IFieldCustomMetadata extends IFieldModifyMetadata, IFieldListMetadata {
151
- mode: string;
150
+ export interface IFieldCustomMetadata
151
+ extends IFieldModifyMetadata,
152
+ IFieldListMetadata {
153
+ mode: string;
152
154
  }
@@ -1,137 +1,151 @@
1
- import {Model} from "./decorators/model/model.decorator";
2
- import {Field} from "./decorators/field/field.decorator";
3
- import {castModel, getInvalidFields, getModelFieldKeys, getModelFieldOptions, isModel} from "./utils";
4
- import {FieldType} from "./interfaces";
1
+ import { Field } from './decorators/field/field.decorator';
2
+ import { Model } from './decorators/model/model.decorator';
3
+ import { FieldType } from './interfaces';
4
+ import {
5
+ castModel,
6
+ getInvalidFields,
7
+ getModelFieldKeys,
8
+ getModelFieldOptions,
9
+ isModel,
10
+ } from './utils';
5
11
 
6
12
  describe('shared-models: utils', () => {
7
- describe('getModelFieldKeys()', () => {
8
- it('should return empty array when fields is not defined', () => {
9
- @Model({})
10
- class Test {
11
- }
13
+ describe('getModelFieldKeys()', () => {
14
+ it('should return empty array when fields is not defined', () => {
15
+ @Model({})
16
+ class Test {}
12
17
 
13
- const result = getModelFieldKeys(Test);
18
+ const result = getModelFieldKeys(Test);
14
19
 
15
- expect(result).toStrictEqual([ ]);
16
- });
20
+ expect(result).toStrictEqual([]);
21
+ });
17
22
 
18
- it('should return field keys array', () => {
19
- @Model({})
20
- class Test {
21
- @Field({}) test1!: any;
22
- @Field({}) test2!: any;
23
- @Field({}) test3!: any;
24
- }
23
+ it('should return field keys array', () => {
24
+ @Model({})
25
+ class Test {
26
+ @Field({}) test1!: any;
27
+ @Field({}) test2!: any;
28
+ @Field({}) test3!: any;
29
+ }
25
30
 
26
- const result = getModelFieldKeys(Test);
31
+ const result = getModelFieldKeys(Test);
27
32
 
28
- expect(result).toStrictEqual([ 'test1', 'test2', 'test3' ]);
29
- });
33
+ expect(result).toStrictEqual(['test1', 'test2', 'test3']);
30
34
  });
35
+ });
31
36
 
32
- describe('getModelFieldOptions', () => {
33
- it('should return options', () => {
34
- const options = { required: true, type: FieldType.password };
37
+ describe('getModelFieldOptions', () => {
38
+ it('should return options', () => {
39
+ const options = { required: true, type: FieldType.password };
35
40
 
36
- @Model({})
37
- class Test {
38
- @Field(options) test!: string;
39
- }
41
+ @Model({})
42
+ class Test {
43
+ @Field(options) test!: string;
44
+ }
40
45
 
41
- expect(getModelFieldOptions(new Test(), 'test')).toStrictEqual(options);
42
- });
46
+ expect(getModelFieldOptions(new Test(), 'test')).toStrictEqual(options);
43
47
  });
48
+ });
44
49
 
45
- describe('isModel', () => {
46
- it('should return true when model type', () => {
47
- @Model({})
48
- class Test {
49
- @Field({}) test!: string;
50
- }
50
+ describe('isModel', () => {
51
+ it('should return true when model type', () => {
52
+ @Model({})
53
+ class Test {
54
+ @Field({}) test!: string;
55
+ }
51
56
 
52
- expect(isModel(new Test())).toBe(true);
53
- });
57
+ expect(isModel(new Test())).toBe(true);
58
+ });
54
59
 
55
- it('should return false when other type', () => {
56
- expect(isModel(new Date())).toBe(false);
57
- });
60
+ it('should return false when other type', () => {
61
+ expect(isModel(new Date())).toBe(false);
62
+ });
63
+ });
64
+
65
+ describe('getInvalidFields', () => {
66
+ it('should return empty array when correct', () => {
67
+ @Model({})
68
+ class Test {
69
+ @Field({}) test!: string;
70
+ @Field({
71
+ required: true,
72
+ })
73
+ test2!: string;
74
+ @Field({
75
+ create: {
76
+ required: true,
77
+ },
78
+ })
79
+ test3!: string;
80
+ @Field({
81
+ create: {
82
+ required: false,
83
+ },
84
+ })
85
+ test4!: string;
86
+ }
87
+
88
+ const instance = new Test();
89
+ instance.test2 = '12';
90
+ instance.test3 = '21';
91
+
92
+ expect(getInvalidFields(instance, 'create', null as any).length).toBe(0);
58
93
  });
59
94
 
60
- describe('getInvalidFields', () => {
61
- it('should return empty array when correct', () => {
62
- @Model({})
63
- class Test {
64
- @Field({}) test!: string;
65
- @Field({
66
- required: true
67
- }) test2!: string;
68
- @Field({
69
- create: {
70
- required: true
71
- }
72
- }) test3!: string;
73
- @Field({
74
- create: {
75
- required: false
76
- }
77
- }) test4!: string;
78
- }
79
-
80
- const instance = new Test();
81
- instance.test2 = "12";
82
- instance.test3 = "21";
83
-
84
- expect(getInvalidFields(instance, 'create', null as any).length).toBe(0);
85
- });
86
-
87
- it('should return array when incorrect', () => {
88
- @Model({})
89
- class Test {
90
- @Field({}) test!: string;
91
- @Field({
92
- required: true
93
- }) test2!: string;
94
- @Field({
95
- create: {
96
- required: true
97
- }
98
- }) test3!: string;
99
- @Field({
100
- create: {
101
- required: false
102
- }
103
- }) test4!: string;
104
- }
105
-
106
- const instance = new Test();
107
- instance.test2 = "12";
108
-
109
- expect(getInvalidFields(instance, 'create', null as any).length).toBe(1);
110
- });
111
-
112
- it('should return empty array when not model', () => {
113
- expect(getInvalidFields(new Date(), 'create', null as any).length).toBe(0);
114
- });
95
+ it('should return array when incorrect', () => {
96
+ @Model({})
97
+ class Test {
98
+ @Field({}) test!: string;
99
+ @Field({
100
+ required: true,
101
+ })
102
+ test2!: string;
103
+ @Field({
104
+ create: {
105
+ required: true,
106
+ },
107
+ })
108
+ test3!: string;
109
+ @Field({
110
+ create: {
111
+ required: false,
112
+ },
113
+ })
114
+ test4!: string;
115
+ }
116
+
117
+ const instance = new Test();
118
+ instance.test2 = '12';
119
+
120
+ expect(getInvalidFields(instance, 'create', null as any).length).toBe(1);
115
121
  });
116
122
 
117
- describe('castModel', () => {
118
- it('should remove unused fields', () => {
119
- @Model({})
120
- class Test {
121
- @Field({}) test!: string;
122
- @Field({
123
- create: true
124
- }) test2!: string;
125
- }
126
-
127
- const instance = new Test();
128
- instance.test = "asd";
129
- instance.test2 = "aaa";
130
-
131
- castModel(instance, 'create', null as any);
132
-
133
- expect(instance.test).not.toBeDefined();
134
- expect(instance.test2).toBeDefined();
135
- });
123
+ it('should return empty array when not model', () => {
124
+ expect(getInvalidFields(new Date(), 'create', null as any).length).toBe(
125
+ 0,
126
+ );
127
+ });
128
+ });
129
+
130
+ describe('castModel', () => {
131
+ it('should remove unused fields', () => {
132
+ @Model({})
133
+ class Test {
134
+ @Field({}) test!: string;
135
+ @Field({
136
+ create: true,
137
+ })
138
+ test2!: string;
139
+ }
140
+
141
+ const instance = new Test();
142
+ instance.test = 'asd';
143
+ instance.test2 = 'aaa';
144
+
145
+ castModel(instance, 'create', null as any);
146
+
147
+ expect(instance.test).not.toBeDefined();
148
+ expect(instance.test2).toBeDefined();
136
149
  });
150
+ });
137
151
  });
package/src/lib/utils.ts CHANGED
@@ -1,20 +1,20 @@
1
- import { IFieldOptions, IModelOptions } from "./interfaces";
2
- import { SYMBOL_FIELD, SYMBOL_MODEL } from "./symbols";
1
+ import { IFieldOptions, IModelOptions } from './interfaces';
2
+ import { SYMBOL_FIELD, SYMBOL_MODEL } from './symbols';
3
3
 
4
4
  export function getModelFieldKeys<T>(type: T): Array<string> {
5
- if (!(type as any)["__fields"]) return [];
6
- return Object.keys((type as any)["__fields"]);
5
+ if (!(type as any)['__fields']) return [];
6
+ return Object.keys((type as any)['__fields']);
7
7
  }
8
8
 
9
9
  export function getModelFieldOptions<T>(
10
10
  instance: T,
11
- fieldKey: string
11
+ fieldKey: string,
12
12
  ): IFieldOptions {
13
13
  return Reflect.getMetadata(SYMBOL_FIELD, instance as any, fieldKey);
14
14
  }
15
15
 
16
16
  export function getModelFieldsWithOptions<T>(
17
- instance: T
17
+ instance: T,
18
18
  ): Array<{ key: string; options: IFieldOptions }> {
19
19
  const keys = getModelFieldKeys((instance as any).constructor);
20
20
 
@@ -37,8 +37,8 @@ export function isModel<T>(instance: T): boolean {
37
37
 
38
38
  export function getInvalidFields<T>(
39
39
  instance: T,
40
- mode: "create" | "update" | string,
41
- permissions: Array<string>
40
+ mode: 'create' | 'update' | string,
41
+ permissions: Array<string>,
42
42
  ): Array<string> {
43
43
  const result: any[] = [];
44
44
 
@@ -46,7 +46,7 @@ export function getInvalidFields<T>(
46
46
  let required = options.required;
47
47
 
48
48
  if (
49
- (mode === "create" || mode === "update") &&
49
+ (mode === 'create' || mode === 'update') &&
50
50
  options[mode] &&
51
51
  options[mode]?.constructor
52
52
  ) {
@@ -58,15 +58,18 @@ export function getInvalidFields<T>(
58
58
  (options[mode] as IFieldOptions).permissions
59
59
  ) {
60
60
  required = (options[mode] as IFieldOptions)?.permissions?.some((op) =>
61
- permissions.some((p) => p === op)
61
+ permissions.some((p) => p === op),
62
62
  );
63
63
  }
64
64
  }
65
65
 
66
66
  if (
67
- required
68
- && ((instance as any)[key] === null || (instance as any)[key] === undefined || (instance as any)[key] === '')
69
- ) result.push(key);
67
+ required &&
68
+ ((instance as any)[key] === null ||
69
+ (instance as any)[key] === undefined ||
70
+ (instance as any)[key] === '')
71
+ )
72
+ result.push(key);
70
73
  });
71
74
 
72
75
  return result;
@@ -74,18 +77,17 @@ export function getInvalidFields<T>(
74
77
 
75
78
  export function castModel<T>(
76
79
  instance: T,
77
- mode: "create" | "update" | string,
78
- permissions: Array<string>
80
+ mode: 'create' | 'update' | string,
81
+ permissions: Array<string>,
79
82
  ): void {
80
83
  if (!isModel(instance)) return;
81
84
 
82
85
  const fieldsWithOptions = getModelFieldsWithOptions(instance);
83
86
 
84
87
  Object.keys(instance as any)
85
- .filter((key) => key !== "id")
88
+ .filter((key) => key !== 'id')
86
89
  .forEach((key) => {
87
- const fieldWidthOptions =
88
- fieldsWithOptions.find((f) => f.key === key);
90
+ const fieldWidthOptions = fieldsWithOptions.find((f) => f.key === key);
89
91
 
90
92
  if (!fieldWidthOptions) {
91
93
  delete (instance as any)[key];
@@ -93,21 +95,19 @@ export function castModel<T>(
93
95
  }
94
96
 
95
97
  if (
96
- (mode === "create" || mode === "update") &&
98
+ (mode === 'create' || mode === 'update') &&
97
99
  (!fieldWidthOptions.options[mode] ||
98
100
  (permissions &&
99
101
  (fieldWidthOptions.options[mode] as IFieldOptions).permissions &&
100
- !(fieldWidthOptions.options[
101
- mode
102
- ] as IFieldOptions)?.permissions?.some((op) =>
103
- permissions.some((p) => op === p)
104
- )))
102
+ !(
103
+ fieldWidthOptions.options[mode] as IFieldOptions
104
+ )?.permissions?.some((op) => permissions.some((p) => op === p))))
105
105
  ) {
106
106
  delete (instance as any)[key];
107
107
  return;
108
108
  } else if (
109
- mode !== "create" &&
110
- mode !== "update" &&
109
+ mode !== 'create' &&
110
+ mode !== 'update' &&
111
111
  (!fieldWidthOptions.options.customs ||
112
112
  !fieldWidthOptions.options.customs.some((c) => c.mode === mode))
113
113
  ) {