@opra/common 0.24.2 → 0.25.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/browser.js +368 -314
- package/cjs/document/data-type/complex-type-class.js +151 -0
- package/cjs/document/data-type/complex-type.js +13 -168
- package/cjs/document/data-type/data-type.js +4 -0
- package/cjs/document/data-type/enum-type-class.js +32 -0
- package/cjs/document/data-type/enum-type.js +24 -49
- package/cjs/document/data-type/field-class.js +34 -0
- package/cjs/document/data-type/field-decorator.js +45 -0
- package/cjs/document/data-type/field.js +25 -0
- package/cjs/document/data-type/mapped-type-class.js +48 -0
- package/cjs/document/data-type/mapped-type.js +18 -58
- package/cjs/document/data-type/simple-type-class.js +29 -0
- package/cjs/document/data-type/simple-type.js +12 -43
- package/cjs/document/data-type/union-type-class.js +36 -0
- package/cjs/document/data-type/union-type.js +3 -31
- package/cjs/document/{resource → decorators}/collection-decorator.js +2 -24
- package/cjs/document/decorators/complex-type.decorator.js +23 -0
- package/cjs/document/decorators/resource.decorator.js +38 -0
- package/cjs/document/decorators/simple-type.decorator.js +20 -0
- package/cjs/document/{resource/singleton-decorator.js → decorators/singleton.decorator.js} +2 -19
- package/cjs/document/{resource/storage-decorator.js → decorators/storage.decorator.js} +2 -18
- package/cjs/document/index.js +1 -1
- package/cjs/document/resource/collection.js +4 -3
- package/cjs/document/resource/endpoint.js +44 -0
- package/cjs/document/resource/resource.js +9 -10
- package/cjs/document/resource/singleton.js +5 -1
- package/cjs/document/resource/storage.js +5 -1
- package/cjs/schema/opra-schema.ns.js +1 -0
- package/cjs/schema/resource/endpoint.interface.js +2 -0
- package/esm/document/data-type/complex-type-class.js +147 -0
- package/esm/document/data-type/complex-type.js +13 -168
- package/esm/document/data-type/data-type.js +4 -0
- package/esm/document/data-type/enum-type-class.js +27 -0
- package/esm/document/data-type/enum-type.js +22 -47
- package/esm/document/data-type/field-class.js +30 -0
- package/esm/document/data-type/field-decorator.js +41 -0
- package/esm/document/data-type/field.js +21 -0
- package/esm/document/data-type/mapped-type-class.js +43 -0
- package/esm/document/data-type/mapped-type.js +13 -53
- package/esm/document/data-type/simple-type-class.js +24 -0
- package/esm/document/data-type/simple-type.js +12 -43
- package/esm/document/data-type/union-type-class.js +32 -0
- package/esm/document/data-type/union-type.js +2 -30
- package/esm/document/{resource → decorators}/collection-decorator.js +2 -23
- package/esm/document/decorators/complex-type.decorator.js +18 -0
- package/esm/document/decorators/resource.decorator.js +33 -0
- package/esm/document/decorators/simple-type.decorator.js +15 -0
- package/esm/document/{resource/singleton-decorator.js → decorators/singleton.decorator.js} +2 -18
- package/esm/document/{resource/storage-decorator.js → decorators/storage.decorator.js} +2 -17
- package/esm/document/index.js +1 -1
- package/esm/document/resource/collection.js +4 -3
- package/esm/document/resource/endpoint.js +40 -0
- package/esm/document/resource/resource.js +9 -10
- package/esm/document/resource/singleton.js +5 -1
- package/esm/document/resource/storage.js +5 -1
- package/esm/schema/opra-schema.ns.js +1 -0
- package/esm/schema/resource/endpoint.interface.js +1 -0
- package/package.json +3 -11
- package/types/document/data-type/complex-type-class.d.ts +33 -0
- package/types/document/data-type/complex-type.d.ts +18 -43
- package/types/document/data-type/data-type.d.ts +17 -13
- package/types/document/data-type/enum-type-class.d.ts +17 -0
- package/types/document/data-type/enum-type.d.ts +11 -24
- package/types/document/data-type/field-class.d.ts +20 -0
- package/types/document/data-type/field-decorator.d.ts +5 -0
- package/types/document/data-type/{api-field.d.ts → field.d.ts} +20 -20
- package/types/document/data-type/mapped-type-class.d.ts +21 -0
- package/types/document/data-type/mapped-type.d.ts +24 -39
- package/types/document/data-type/simple-type-class.d.ts +17 -0
- package/types/document/data-type/simple-type.d.ts +21 -31
- package/types/document/data-type/union-type-class.d.ts +18 -0
- package/types/document/data-type/union-type.d.ts +15 -27
- package/types/document/{resource → decorators}/collection-decorator.d.ts +14 -14
- package/types/document/decorators/complex-type.decorator.d.ts +2 -0
- package/types/document/decorators/resource.decorator.d.ts +9 -0
- package/types/document/decorators/simple-type.decorator.d.ts +2 -0
- package/types/document/{resource/singleton-decorator.d.ts → decorators/singleton.decorator.d.ts} +11 -11
- package/types/document/{resource/storage-decorator.d.ts → decorators/storage.decorator.d.ts} +10 -10
- package/types/document/factory/import-type-class.d.ts +1 -1
- package/types/document/index.d.ts +1 -1
- package/types/document/resource/collection.d.ts +16 -12
- package/types/document/resource/endpoint.d.ts +29 -0
- package/types/document/resource/resource.d.ts +15 -14
- package/types/document/resource/singleton.d.ts +15 -8
- package/types/document/resource/storage-class.d.ts +0 -2
- package/types/document/resource/storage.d.ts +12 -8
- package/types/filter/ast/terms/qualified-identifier.d.ts +1 -1
- package/types/schema/opra-schema.ns.d.ts +1 -0
- package/types/schema/resource/collection.interface.d.ts +2 -1
- package/types/schema/resource/endpoint.interface.d.ts +12 -0
- package/types/schema/resource/resource.interface.d.ts +3 -15
- package/types/schema/resource/storage.interface.d.ts +2 -1
- package/cjs/document/data-type/api-field.js +0 -83
- package/cjs/document/resource/action.js +0 -12
- package/cjs/document/resource/resource-decorator.js +0 -16
- package/esm/document/data-type/api-field.js +0 -80
- package/esm/document/resource/action.js +0 -8
- package/esm/document/resource/resource-decorator.js +0 -13
- package/types/document/resource/action.d.ts +0 -11
- package/types/document/resource/resource-decorator.d.ts +0 -5
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { omitUndefined, ResponsiveMap } from '../../helpers/index.js';
|
|
2
|
+
import { translate } from '../../i18n/index.js';
|
|
3
|
+
import { OpraSchema } from '../../schema/index.js';
|
|
4
|
+
import { DataType } from './data-type.js';
|
|
5
|
+
import { ApiField } from './field.js';
|
|
6
|
+
/**
|
|
7
|
+
* @class ComplexType
|
|
8
|
+
*/
|
|
9
|
+
export class ComplexTypeClass extends DataType {
|
|
10
|
+
constructor(document, init) {
|
|
11
|
+
super(document, init);
|
|
12
|
+
this.kind = OpraSchema.ComplexType.Kind;
|
|
13
|
+
const own = this.own = {};
|
|
14
|
+
own.ctor = init?.ctor || init?.base?.ctor;
|
|
15
|
+
own.abstract = init?.abstract;
|
|
16
|
+
own.additionalFields = init?.additionalFields;
|
|
17
|
+
own.fields = new ResponsiveMap();
|
|
18
|
+
this.kind = OpraSchema.ComplexType.Kind;
|
|
19
|
+
this.base = init?.base;
|
|
20
|
+
this.ctor = own.ctor || Object;
|
|
21
|
+
this.abstract = own.abstract;
|
|
22
|
+
this.additionalFields = own.additionalFields;
|
|
23
|
+
this.fields = new ResponsiveMap();
|
|
24
|
+
if (this.base) {
|
|
25
|
+
if (this.additionalFields == null)
|
|
26
|
+
this.additionalFields = this.base.additionalFields;
|
|
27
|
+
if (this.base.fields)
|
|
28
|
+
for (const [k, el] of this.base.fields.entries()) {
|
|
29
|
+
const newEl = new ApiField(this, el);
|
|
30
|
+
this.fields.set(k, newEl);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
addField(init) {
|
|
35
|
+
const field = new ApiField(this, init);
|
|
36
|
+
this.own.fields.set(field.name, field);
|
|
37
|
+
this.fields.set(field.name, field);
|
|
38
|
+
return field;
|
|
39
|
+
}
|
|
40
|
+
findField(nameOrPath) {
|
|
41
|
+
let field;
|
|
42
|
+
if (nameOrPath.includes('.')) {
|
|
43
|
+
for (const [, f] of this.iteratePath(nameOrPath, true)) {
|
|
44
|
+
if (!f)
|
|
45
|
+
return;
|
|
46
|
+
field = f;
|
|
47
|
+
}
|
|
48
|
+
return field;
|
|
49
|
+
}
|
|
50
|
+
return this.fields.get(nameOrPath);
|
|
51
|
+
}
|
|
52
|
+
getField(nameOrPath) {
|
|
53
|
+
let field;
|
|
54
|
+
if (nameOrPath.includes('.')) {
|
|
55
|
+
for (const [, f] of this.iteratePath(nameOrPath)) {
|
|
56
|
+
field = f;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else
|
|
60
|
+
field = this.fields.get(nameOrPath);
|
|
61
|
+
if (!field)
|
|
62
|
+
throw new Error(translate('error:UNKNOWN_FIELD', { field: nameOrPath }));
|
|
63
|
+
return field;
|
|
64
|
+
}
|
|
65
|
+
iteratePath(path, silent) {
|
|
66
|
+
const arr = path.split('.');
|
|
67
|
+
const len = arr.length;
|
|
68
|
+
let dataType = this;
|
|
69
|
+
let field;
|
|
70
|
+
let curPath = '';
|
|
71
|
+
let s;
|
|
72
|
+
let i = -1;
|
|
73
|
+
const ComplexType = Object.getPrototypeOf(this).constructor;
|
|
74
|
+
return {
|
|
75
|
+
[Symbol.iterator]() {
|
|
76
|
+
return this;
|
|
77
|
+
},
|
|
78
|
+
next() {
|
|
79
|
+
i++;
|
|
80
|
+
if (i < len) {
|
|
81
|
+
s = arr[i];
|
|
82
|
+
if (dataType && !(dataType instanceof ComplexType)) {
|
|
83
|
+
if (silent)
|
|
84
|
+
return { done: true, value: [] };
|
|
85
|
+
throw new TypeError(`"${curPath}" field is not a complex type and has no child fields`);
|
|
86
|
+
}
|
|
87
|
+
field = dataType?.fields.get(s);
|
|
88
|
+
if (field) {
|
|
89
|
+
curPath += (curPath ? '.' : '') + field.name;
|
|
90
|
+
dataType = field.type;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
curPath += (curPath ? '.' : '') + s;
|
|
94
|
+
if (dataType && !dataType.additionalFields) {
|
|
95
|
+
if (silent)
|
|
96
|
+
return { done: true, value: [] };
|
|
97
|
+
throw new Error(translate('error:UNKNOWN_FIELD', { field: curPath }));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
done: i >= len,
|
|
103
|
+
value: [field?.name || s, field, curPath]
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
normalizeFieldPath(fieldPaths) {
|
|
109
|
+
const array = (Array.isArray(fieldPaths) ? fieldPaths : [fieldPaths])
|
|
110
|
+
.map(s => {
|
|
111
|
+
let curPath = '';
|
|
112
|
+
for (const [, , p] of this.iteratePath(s)) {
|
|
113
|
+
curPath = p;
|
|
114
|
+
}
|
|
115
|
+
return curPath;
|
|
116
|
+
}).flat();
|
|
117
|
+
return array.length ? array : undefined;
|
|
118
|
+
}
|
|
119
|
+
exportSchema() {
|
|
120
|
+
const out = super.exportSchema();
|
|
121
|
+
Object.assign(out, omitUndefined({
|
|
122
|
+
base: this.base ?
|
|
123
|
+
(this.base.name ? this.base.name : this.base.exportSchema()) : undefined,
|
|
124
|
+
abstract: this.own.abstract,
|
|
125
|
+
additionalFields: this.own.additionalFields
|
|
126
|
+
}));
|
|
127
|
+
if (this.own.fields.size) {
|
|
128
|
+
const fields = out.fields = {};
|
|
129
|
+
for (const field of this.own.fields.values()) {
|
|
130
|
+
fields[field.name] = field.exportSchema();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return omitUndefined(out);
|
|
134
|
+
}
|
|
135
|
+
isTypeOf(t) {
|
|
136
|
+
return t === this.own.ctor;
|
|
137
|
+
}
|
|
138
|
+
extendsFrom(t) {
|
|
139
|
+
const base = t instanceof DataType ? t : this.document.getDataType(t);
|
|
140
|
+
if (this.base) {
|
|
141
|
+
if (this.base === base)
|
|
142
|
+
return true;
|
|
143
|
+
return this.base.extendsFrom(base);
|
|
144
|
+
}
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
@@ -1,177 +1,22 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
|
-
import omit from 'lodash.omit';
|
|
3
2
|
import merge from 'putil-merge';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { DATATYPE_METADATA, TYPENAME_PATTERN } from '../constants.js';
|
|
8
|
-
import { ApiField } from './api-field.js';
|
|
9
|
-
import { DataType } from './data-type.js';
|
|
10
|
-
/**
|
|
11
|
-
* @class ComplexType
|
|
12
|
-
*/
|
|
13
|
-
class ComplexTypeClass extends DataType {
|
|
14
|
-
constructor(document, init) {
|
|
15
|
-
super(document, init);
|
|
16
|
-
this.kind = OpraSchema.ComplexType.Kind;
|
|
17
|
-
const own = this.own = {};
|
|
18
|
-
own.ctor = init?.ctor || init?.base?.ctor;
|
|
19
|
-
own.abstract = init?.abstract;
|
|
20
|
-
own.additionalFields = init?.additionalFields;
|
|
21
|
-
own.fields = new ResponsiveMap();
|
|
22
|
-
this.kind = OpraSchema.ComplexType.Kind;
|
|
23
|
-
this.base = init?.base;
|
|
24
|
-
this.ctor = own.ctor || Object;
|
|
25
|
-
this.abstract = own.abstract;
|
|
26
|
-
this.additionalFields = own.additionalFields;
|
|
27
|
-
this.fields = new ResponsiveMap();
|
|
28
|
-
if (this.base) {
|
|
29
|
-
if (this.additionalFields == null)
|
|
30
|
-
this.additionalFields = this.base.additionalFields;
|
|
31
|
-
if (this.base.fields)
|
|
32
|
-
for (const [k, el] of this.base.fields.entries()) {
|
|
33
|
-
const newEl = new ApiField(this, el);
|
|
34
|
-
this.fields.set(k, newEl);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
addField(init) {
|
|
39
|
-
const field = new ApiField(this, init);
|
|
40
|
-
this.own.fields.set(field.name, field);
|
|
41
|
-
this.fields.set(field.name, field);
|
|
42
|
-
return field;
|
|
43
|
-
}
|
|
44
|
-
findField(nameOrPath) {
|
|
45
|
-
let field;
|
|
46
|
-
if (nameOrPath.includes('.')) {
|
|
47
|
-
for (const [, f] of this.iteratePath(nameOrPath, true)) {
|
|
48
|
-
if (!f)
|
|
49
|
-
return;
|
|
50
|
-
field = f;
|
|
51
|
-
}
|
|
52
|
-
return field;
|
|
53
|
-
}
|
|
54
|
-
return this.fields.get(nameOrPath);
|
|
55
|
-
}
|
|
56
|
-
getField(nameOrPath) {
|
|
57
|
-
let field;
|
|
58
|
-
if (nameOrPath.includes('.')) {
|
|
59
|
-
for (const [, f] of this.iteratePath(nameOrPath)) {
|
|
60
|
-
field = f;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
else
|
|
64
|
-
field = this.fields.get(nameOrPath);
|
|
65
|
-
if (!field)
|
|
66
|
-
throw new Error(translate('error:UNKNOWN_FIELD', { field: nameOrPath }));
|
|
67
|
-
return field;
|
|
68
|
-
}
|
|
69
|
-
iteratePath(path, silent) {
|
|
70
|
-
const arr = path.split('.');
|
|
71
|
-
const len = arr.length;
|
|
72
|
-
let dataType = this;
|
|
73
|
-
let field;
|
|
74
|
-
let curPath = '';
|
|
75
|
-
let s;
|
|
76
|
-
let i = -1;
|
|
77
|
-
return {
|
|
78
|
-
[Symbol.iterator]() {
|
|
79
|
-
return this;
|
|
80
|
-
},
|
|
81
|
-
next() {
|
|
82
|
-
i++;
|
|
83
|
-
if (i < len) {
|
|
84
|
-
s = arr[i];
|
|
85
|
-
if (dataType && !(dataType instanceof ComplexType)) {
|
|
86
|
-
if (silent)
|
|
87
|
-
return { done: true, value: [] };
|
|
88
|
-
throw new TypeError(`"${curPath}" field is not a complex type and has no child fields`);
|
|
89
|
-
}
|
|
90
|
-
field = dataType?.fields.get(s);
|
|
91
|
-
if (field) {
|
|
92
|
-
curPath += (curPath ? '.' : '') + field.name;
|
|
93
|
-
dataType = field.type;
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
curPath += (curPath ? '.' : '') + s;
|
|
97
|
-
if (dataType && !dataType.additionalFields) {
|
|
98
|
-
if (silent)
|
|
99
|
-
return { done: true, value: [] };
|
|
100
|
-
throw new Error(translate('error:UNKNOWN_FIELD', { field: curPath }));
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
return {
|
|
105
|
-
done: i >= len,
|
|
106
|
-
value: [field?.name || s, field, curPath]
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
normalizeFieldPath(fieldPaths) {
|
|
112
|
-
const array = (Array.isArray(fieldPaths) ? fieldPaths : [fieldPaths])
|
|
113
|
-
.map(s => {
|
|
114
|
-
let curPath = '';
|
|
115
|
-
for (const [, , p] of this.iteratePath(s)) {
|
|
116
|
-
curPath = p;
|
|
117
|
-
}
|
|
118
|
-
return curPath;
|
|
119
|
-
}).flat();
|
|
120
|
-
return array.length ? array : undefined;
|
|
121
|
-
}
|
|
122
|
-
exportSchema() {
|
|
123
|
-
const out = super.exportSchema();
|
|
124
|
-
Object.assign(out, omitUndefined({
|
|
125
|
-
base: this.base ?
|
|
126
|
-
(this.base.name ? this.base.name : this.base.exportSchema()) : undefined,
|
|
127
|
-
abstract: this.own.abstract,
|
|
128
|
-
additionalFields: this.own.additionalFields
|
|
129
|
-
}));
|
|
130
|
-
if (this.own.fields.size) {
|
|
131
|
-
const fields = out.fields = {};
|
|
132
|
-
for (const field of this.own.fields.values()) {
|
|
133
|
-
fields[field.name] = field.exportSchema();
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return omitUndefined(out);
|
|
137
|
-
}
|
|
138
|
-
isTypeOf(t) {
|
|
139
|
-
return t === this.own.ctor;
|
|
140
|
-
}
|
|
141
|
-
extendsFrom(t) {
|
|
142
|
-
const base = t instanceof DataType ? t : this.document.getDataType(t);
|
|
143
|
-
if (this.base) {
|
|
144
|
-
if (this.base === base)
|
|
145
|
-
return true;
|
|
146
|
-
return this.base.extendsFrom(base);
|
|
147
|
-
}
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
3
|
+
import { DECORATOR } from '../constants.js';
|
|
4
|
+
import { ComplexTypeDecorator } from '../decorators/complex-type.decorator.js';
|
|
5
|
+
import { ComplexTypeClass } from './complex-type-class.js';
|
|
151
6
|
/**
|
|
152
7
|
* @class ComplexType
|
|
8
|
+
* @decorator ComplexType
|
|
153
9
|
*/
|
|
154
10
|
export const ComplexType = function (...args) {
|
|
155
|
-
//
|
|
156
|
-
if (this) {
|
|
157
|
-
const [
|
|
158
|
-
|
|
159
|
-
return;
|
|
11
|
+
// Decorator
|
|
12
|
+
if (!this) {
|
|
13
|
+
const [options] = args;
|
|
14
|
+
return ComplexType[DECORATOR](options);
|
|
160
15
|
}
|
|
161
|
-
//
|
|
162
|
-
const [
|
|
163
|
-
|
|
164
|
-
const name = options?.name || target.name.match(TYPENAME_PATTERN)?.[1] || target.name;
|
|
165
|
-
let metadata = Reflect.getOwnMetadata(DATATYPE_METADATA, target);
|
|
166
|
-
if (!metadata) {
|
|
167
|
-
metadata = {};
|
|
168
|
-
Reflect.defineMetadata(DATATYPE_METADATA, metadata, target);
|
|
169
|
-
}
|
|
170
|
-
metadata.kind = OpraSchema.ComplexType.Kind;
|
|
171
|
-
metadata.name = name;
|
|
172
|
-
// Merge options
|
|
173
|
-
if (options)
|
|
174
|
-
Object.assign(metadata, omit(options, ['kind', 'name', 'base', 'fields']));
|
|
175
|
-
};
|
|
16
|
+
// Constructor
|
|
17
|
+
const [document, init] = args;
|
|
18
|
+
merge(this, new ComplexTypeClass(document, init), { descriptor: true });
|
|
176
19
|
};
|
|
177
20
|
ComplexType.prototype = ComplexTypeClass.prototype;
|
|
21
|
+
Object.assign(ComplexType, ComplexTypeDecorator);
|
|
22
|
+
ComplexType[DECORATOR] = ComplexTypeDecorator;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { omitUndefined } from '../../helpers/index.js';
|
|
2
2
|
import { colorFgMagenta, colorFgYellow, colorReset, nodeInspectCustom } from '../utils/inspect.util.js';
|
|
3
|
+
/**
|
|
4
|
+
* @class DataType
|
|
5
|
+
* @abstract
|
|
6
|
+
*/
|
|
3
7
|
export class DataType {
|
|
4
8
|
constructor(document, init) {
|
|
5
9
|
this.document = document;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as vg from 'valgen';
|
|
2
|
+
import { omitUndefined } from '../../helpers/index.js';
|
|
3
|
+
import { OpraSchema } from '../../schema/index.js';
|
|
4
|
+
import { DataType } from './data-type.js';
|
|
5
|
+
export class EnumTypeClass extends DataType {
|
|
6
|
+
constructor(document, init) {
|
|
7
|
+
super(document, init);
|
|
8
|
+
this.kind = OpraSchema.EnumType.Kind;
|
|
9
|
+
this.base = init.base;
|
|
10
|
+
this.ownValues = init.values;
|
|
11
|
+
this.ownMeanings = init.meanings || {};
|
|
12
|
+
this.values = { ...this.base?.values, ...this.ownValues };
|
|
13
|
+
this.meanings = { ...this.base?.meanings, ...this.ownMeanings };
|
|
14
|
+
this.decode = vg.isEnum(Object.values(this.values));
|
|
15
|
+
this.encode = vg.isEnum(Object.values(this.values));
|
|
16
|
+
}
|
|
17
|
+
exportSchema() {
|
|
18
|
+
const out = DataType.prototype.exportSchema.call(this);
|
|
19
|
+
Object.assign(out, omitUndefined({
|
|
20
|
+
base: this.base ?
|
|
21
|
+
(this.base.name ? this.base.name : this.base.exportSchema()) : undefined,
|
|
22
|
+
values: this.ownValues,
|
|
23
|
+
meanings: this.ownMeanings
|
|
24
|
+
}));
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -1,59 +1,34 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
2
|
import omit from 'lodash.omit';
|
|
3
3
|
import merge from 'putil-merge';
|
|
4
|
-
import * as vg from 'valgen';
|
|
5
|
-
import { omitUndefined } from '../../helpers/index.js';
|
|
6
4
|
import { OpraSchema } from '../../schema/index.js';
|
|
7
5
|
import { DATATYPE_METADATA } from '../constants.js';
|
|
8
|
-
import {
|
|
9
|
-
class EnumTypeClass extends DataType {
|
|
10
|
-
constructor(document, init) {
|
|
11
|
-
super(document, init);
|
|
12
|
-
this.kind = OpraSchema.EnumType.Kind;
|
|
13
|
-
this.base = init.base;
|
|
14
|
-
this.ownValues = init.values;
|
|
15
|
-
this.ownMeanings = init.meanings || {};
|
|
16
|
-
this.values = { ...this.base?.values, ...this.ownValues };
|
|
17
|
-
this.meanings = { ...this.base?.meanings, ...this.ownMeanings };
|
|
18
|
-
this.decode = vg.isEnum(Object.values(this.values));
|
|
19
|
-
this.encode = vg.isEnum(Object.values(this.values));
|
|
20
|
-
}
|
|
21
|
-
exportSchema() {
|
|
22
|
-
const out = DataType.prototype.exportSchema.call(this);
|
|
23
|
-
Object.assign(out, omitUndefined({
|
|
24
|
-
base: this.base ?
|
|
25
|
-
(this.base.name ? this.base.name : this.base.exportSchema()) : undefined,
|
|
26
|
-
values: this.ownValues,
|
|
27
|
-
meanings: this.ownMeanings
|
|
28
|
-
}));
|
|
29
|
-
return out;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
6
|
+
import { EnumTypeClass } from './enum-type-class.js';
|
|
32
7
|
/**
|
|
33
8
|
* @class EnumType
|
|
34
9
|
*/
|
|
35
10
|
export const EnumType = function (...args) {
|
|
36
|
-
if (this) {
|
|
37
|
-
// Constructor
|
|
38
|
-
const [document, init] = args;
|
|
39
|
-
merge(this, new EnumTypeClass(document, init), { descriptor: true });
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
11
|
// Injector
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
obj
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
12
|
+
if (!this) {
|
|
13
|
+
const [enumSource, options] = args;
|
|
14
|
+
const values = Array.isArray(enumSource)
|
|
15
|
+
? enumSource.reduce((obj, v) => {
|
|
16
|
+
obj[v] = v;
|
|
17
|
+
return obj;
|
|
18
|
+
}, {})
|
|
19
|
+
: enumSource;
|
|
20
|
+
const metadata = {
|
|
21
|
+
kind: OpraSchema.EnumType.Kind,
|
|
22
|
+
values
|
|
23
|
+
};
|
|
24
|
+
if (options)
|
|
25
|
+
Object.assign(metadata, omit(options, ['kind', 'values']));
|
|
26
|
+
Reflect.defineMetadata(DATATYPE_METADATA, metadata, enumSource);
|
|
27
|
+
return values;
|
|
28
|
+
}
|
|
29
|
+
// Constructor
|
|
30
|
+
const [document, init] = args;
|
|
31
|
+
merge(this, new EnumTypeClass(document, init), { descriptor: true });
|
|
32
|
+
return;
|
|
58
33
|
};
|
|
59
34
|
EnumType.prototype = EnumTypeClass.prototype;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { omitUndefined } from '../../helpers/index.js';
|
|
2
|
+
export class FieldClass {
|
|
3
|
+
constructor(owner, init) {
|
|
4
|
+
this.owner = owner;
|
|
5
|
+
this.name = init.name;
|
|
6
|
+
this.origin = init.origin || owner;
|
|
7
|
+
this.type = init.type;
|
|
8
|
+
this.description = init.description;
|
|
9
|
+
this.isArray = init.isArray;
|
|
10
|
+
this.default = init.default;
|
|
11
|
+
this.fixed = init.fixed;
|
|
12
|
+
this.required = init.required;
|
|
13
|
+
this.exclusive = init.exclusive;
|
|
14
|
+
this.deprecated = init.deprecated;
|
|
15
|
+
this.examples = init.examples;
|
|
16
|
+
}
|
|
17
|
+
exportSchema() {
|
|
18
|
+
return omitUndefined({
|
|
19
|
+
type: this.type.name ? this.type.name : this.type.exportSchema(),
|
|
20
|
+
description: this.description,
|
|
21
|
+
isArray: this.isArray,
|
|
22
|
+
default: this.default,
|
|
23
|
+
fixed: this.fixed,
|
|
24
|
+
required: this.required,
|
|
25
|
+
exclusive: this.exclusive,
|
|
26
|
+
deprecated: this.deprecated,
|
|
27
|
+
examples: this.examples
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { omitUndefined } from '../../helpers/index.js';
|
|
2
|
+
import { OpraSchema } from '../../schema/index.js';
|
|
3
|
+
import { DATATYPE_METADATA } from '../constants.js';
|
|
4
|
+
import { EnumType } from './enum-type.js';
|
|
5
|
+
export function FieldDecorator(options) {
|
|
6
|
+
return function (target, propertyKey) {
|
|
7
|
+
if (typeof propertyKey !== 'string')
|
|
8
|
+
throw new TypeError(`Symbol properties can't be used as a field`);
|
|
9
|
+
const metadata = Reflect.getOwnMetadata(DATATYPE_METADATA, target.constructor) || {};
|
|
10
|
+
metadata.kind = OpraSchema.ComplexType.Kind;
|
|
11
|
+
metadata.fields = metadata.fields || {};
|
|
12
|
+
const designType = Reflect.getMetadata('design:type', target, propertyKey);
|
|
13
|
+
const elemMeta = metadata.fields[propertyKey] = {
|
|
14
|
+
...options,
|
|
15
|
+
enum: undefined,
|
|
16
|
+
designType
|
|
17
|
+
};
|
|
18
|
+
if (designType === Array) {
|
|
19
|
+
elemMeta.isArray = true;
|
|
20
|
+
delete elemMeta.designType;
|
|
21
|
+
}
|
|
22
|
+
if (options?.enum) {
|
|
23
|
+
elemMeta.type = undefined;
|
|
24
|
+
if (Array.isArray(options.enum)) {
|
|
25
|
+
const enumObj = options.enum.reduce((o, v) => {
|
|
26
|
+
o[v] = v;
|
|
27
|
+
return o;
|
|
28
|
+
}, {});
|
|
29
|
+
EnumType(enumObj);
|
|
30
|
+
elemMeta.enum = enumObj;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const m = Reflect.getOwnMetadata(DATATYPE_METADATA, options?.enum);
|
|
34
|
+
if (!OpraSchema.isEnumType(m))
|
|
35
|
+
throw new TypeError(`Invalid "enum" value. Did you forget to set metadata using EnumType() method?`);
|
|
36
|
+
elemMeta.enum = options.enum;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
Reflect.defineMetadata(DATATYPE_METADATA, omitUndefined(metadata), target.constructor);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import merge from 'putil-merge';
|
|
2
|
+
import { DECORATOR } from '../constants.js';
|
|
3
|
+
import { FieldClass } from './field-class.js';
|
|
4
|
+
import { FieldDecorator } from './field-decorator.js';
|
|
5
|
+
/**
|
|
6
|
+
* @class ApiField
|
|
7
|
+
* @decorator ApiField
|
|
8
|
+
*/
|
|
9
|
+
export const ApiField = function (...args) {
|
|
10
|
+
// Decorator
|
|
11
|
+
if (!this) {
|
|
12
|
+
const [options] = args;
|
|
13
|
+
return ApiField[DECORATOR](options);
|
|
14
|
+
}
|
|
15
|
+
// Constructor
|
|
16
|
+
const [owner, init] = args;
|
|
17
|
+
merge(this, new FieldClass(owner, init), { descriptor: true });
|
|
18
|
+
};
|
|
19
|
+
ApiField.prototype = FieldClass.prototype;
|
|
20
|
+
Object.assign(ApiField, FieldDecorator);
|
|
21
|
+
ApiField[DECORATOR] = FieldDecorator;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { omitUndefined, ResponsiveMap } from '../../helpers/index.js';
|
|
2
|
+
import { OpraSchema } from '../../schema/index.js';
|
|
3
|
+
import { DataType } from './data-type.js';
|
|
4
|
+
export class MappedTypeClass extends DataType {
|
|
5
|
+
constructor(document, init) {
|
|
6
|
+
super(document, init);
|
|
7
|
+
this.kind = OpraSchema.MappedType.Kind;
|
|
8
|
+
const own = this.own;
|
|
9
|
+
own.pick = init.pick;
|
|
10
|
+
own.omit = init.omit;
|
|
11
|
+
this.kind = OpraSchema.MappedType.Kind;
|
|
12
|
+
this.type = init.type;
|
|
13
|
+
this.pick = own.pick;
|
|
14
|
+
this.omit = own.omit;
|
|
15
|
+
this.fields = new ResponsiveMap();
|
|
16
|
+
this.additionalFields = this.type.additionalFields;
|
|
17
|
+
const isInheritedPredicate = getIsInheritedPredicateFn(init.pick, init.omit);
|
|
18
|
+
for (const [elemName, elem] of this.type.fields.entries()) {
|
|
19
|
+
if (isInheritedPredicate(elemName))
|
|
20
|
+
this.fields.set(elemName, elem);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exportSchema() {
|
|
24
|
+
const out = DataType.prototype.exportSchema.call(this);
|
|
25
|
+
Object.assign(out, omitUndefined({
|
|
26
|
+
type: this.type.name ? this.type.name : this.type.exportSchema(),
|
|
27
|
+
pick: this.own.pick,
|
|
28
|
+
omit: this.own.omit,
|
|
29
|
+
}));
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function getIsInheritedPredicateFn(pick, omit) {
|
|
34
|
+
const pickKeys = pick?.map(x => String(x).toLowerCase());
|
|
35
|
+
const omitKeys = omit?.map(x => String(x).toLowerCase());
|
|
36
|
+
return (propertyName) => {
|
|
37
|
+
if (omitKeys && omitKeys.includes(propertyName.toLowerCase()))
|
|
38
|
+
return false;
|
|
39
|
+
if (pickKeys)
|
|
40
|
+
return pickKeys.includes(propertyName.toLowerCase());
|
|
41
|
+
return true;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -1,37 +1,20 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
2
|
import merge from 'putil-merge';
|
|
3
|
-
import { inheritPropertyInitializers, mergePrototype
|
|
3
|
+
import { inheritPropertyInitializers, mergePrototype } from '../../helpers/index.js';
|
|
4
4
|
import { OpraSchema } from '../../schema/index.js';
|
|
5
5
|
import { DATATYPE_METADATA } from '../constants.js';
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
this.fields = new ResponsiveMap();
|
|
19
|
-
this.additionalFields = this.type.additionalFields;
|
|
20
|
-
const isInheritedPredicate = getIsInheritedPredicateFn(init.pick, init.omit);
|
|
21
|
-
for (const [elemName, elem] of this.type.fields.entries()) {
|
|
22
|
-
if (isInheritedPredicate(elemName))
|
|
23
|
-
this.fields.set(elemName, elem);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
exportSchema() {
|
|
27
|
-
const out = DataType.prototype.exportSchema.call(this);
|
|
28
|
-
Object.assign(out, omitUndefined({
|
|
29
|
-
type: this.type.name ? this.type.name : this.type.exportSchema(),
|
|
30
|
-
pick: this.own.pick,
|
|
31
|
-
omit: this.own.omit,
|
|
32
|
-
}));
|
|
33
|
-
return out;
|
|
34
|
-
}
|
|
6
|
+
import { getIsInheritedPredicateFn, MappedTypeClass } from './mapped-type-class.js';
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
export function PickType(classRef, keys) {
|
|
11
|
+
return MappedType(classRef, { pick: keys });
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
export function OmitType(classRef, keys) {
|
|
17
|
+
return MappedType(classRef, { omit: keys });
|
|
35
18
|
}
|
|
36
19
|
/**
|
|
37
20
|
* @class MappedType
|
|
@@ -75,26 +58,3 @@ export const MappedType = function (...args) {
|
|
|
75
58
|
};
|
|
76
59
|
MappedType.prototype = MappedTypeClass.prototype;
|
|
77
60
|
MappedType._applyMixin = () => void 0;
|
|
78
|
-
function getIsInheritedPredicateFn(pick, omit) {
|
|
79
|
-
const pickKeys = pick?.map(x => String(x).toLowerCase());
|
|
80
|
-
const omitKeys = omit?.map(x => String(x).toLowerCase());
|
|
81
|
-
return (propertyName) => {
|
|
82
|
-
if (omitKeys && omitKeys.includes(propertyName.toLowerCase()))
|
|
83
|
-
return false;
|
|
84
|
-
if (pickKeys)
|
|
85
|
-
return pickKeys.includes(propertyName.toLowerCase());
|
|
86
|
-
return true;
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
*
|
|
91
|
-
*/
|
|
92
|
-
export function PickType(classRef, keys) {
|
|
93
|
-
return MappedType(classRef, { pick: keys });
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
*
|
|
97
|
-
*/
|
|
98
|
-
export function OmitType(classRef, keys) {
|
|
99
|
-
return MappedType(classRef, { omit: keys });
|
|
100
|
-
}
|