@opra/common 1.5.4 → 1.5.6
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/index.cjs +4 -4
- package/browser/index.mjs +4 -4
- package/cjs/document/common/document-node.js +2 -2
- package/cjs/document/data-type/api-field.js +32 -0
- package/cjs/document/data-type/complex-type-base.js +16 -13
- package/cjs/document/data-type/complex-type.js +1 -1
- package/cjs/document/data-type/mixin-type.js +1 -1
- package/cjs/document/decorators/api-field-decorator.js +17 -23
- package/cjs/document/factory/data-type.factory.js +1 -0
- package/cjs/document/utils/test-scope-match.js +1 -1
- package/esm/document/common/document-node.js +2 -2
- package/esm/document/data-type/api-field.js +32 -0
- package/esm/document/data-type/complex-type-base.js +16 -13
- package/esm/document/data-type/complex-type.js +1 -1
- package/esm/document/data-type/mixin-type.js +1 -1
- package/esm/document/decorators/api-field-decorator.js +17 -23
- package/esm/document/factory/data-type.factory.js +1 -0
- package/esm/document/utils/test-scope-match.js +1 -1
- package/package.json +1 -1
- package/types/document/common/document-node.d.ts +8 -8
- package/types/document/data-type/api-field.d.ts +6 -3
- package/types/document/data-type/complex-type-base.d.ts +2 -2
- package/types/document/data-type/data-type.d.ts +2 -3
- package/types/document/decorators/api-field-decorator.d.ts +11 -0
- package/types/document/factory/data-type.factory.d.ts +1 -1
- package/types/filter/filter-rules.d.ts +2 -2
|
@@ -36,8 +36,8 @@ class DocumentNode {
|
|
|
36
36
|
* Returns DataType instance by name or Constructor. Returns undefined if not found
|
|
37
37
|
*/
|
|
38
38
|
getDataType(nameOrCtor, scope) {
|
|
39
|
-
const dt = this.findDataType(nameOrCtor);
|
|
40
|
-
if (dt
|
|
39
|
+
const dt = this.findDataType(nameOrCtor, scope);
|
|
40
|
+
if (dt)
|
|
41
41
|
return dt;
|
|
42
42
|
let name = '';
|
|
43
43
|
if (typeof nameOrCtor === 'function') {
|
|
@@ -46,6 +46,7 @@ exports.ApiField = function (...args) {
|
|
|
46
46
|
_this.readonly = initArgs.readonly;
|
|
47
47
|
_this.writeonly = initArgs.writeonly;
|
|
48
48
|
_this.examples = initArgs.examples;
|
|
49
|
+
_this.override = initArgs.override;
|
|
49
50
|
};
|
|
50
51
|
/**
|
|
51
52
|
* The ApiFieldClass represents a descriptive metadata structure for API fields,
|
|
@@ -56,6 +57,37 @@ class ApiFieldClass extends document_element_js_1.DocumentElement {
|
|
|
56
57
|
inScope(scope) {
|
|
57
58
|
return (0, test_scope_match_js_1.testScopeMatch)(scope, this.scopePattern);
|
|
58
59
|
}
|
|
60
|
+
forScope(scope) {
|
|
61
|
+
if (!(scope && this.override))
|
|
62
|
+
return this;
|
|
63
|
+
this._overrideCache = this._overrideCache || {};
|
|
64
|
+
let field = this._overrideCache[scope];
|
|
65
|
+
if (field)
|
|
66
|
+
return field;
|
|
67
|
+
if (scope !== '*') {
|
|
68
|
+
for (const o of this.override) {
|
|
69
|
+
if ((0, test_scope_match_js_1.testScopeMatch)(scope, o.scopePattern)) {
|
|
70
|
+
field = (0, objects_1.omitUndefined)({
|
|
71
|
+
...o,
|
|
72
|
+
id: undefined,
|
|
73
|
+
owner: undefined,
|
|
74
|
+
node: undefined,
|
|
75
|
+
origin: undefined,
|
|
76
|
+
name: undefined,
|
|
77
|
+
type: undefined,
|
|
78
|
+
override: undefined,
|
|
79
|
+
_overrideCache: undefined,
|
|
80
|
+
scopePattern: o.scopePattern,
|
|
81
|
+
});
|
|
82
|
+
Object.setPrototypeOf(field, this);
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
field = field || this;
|
|
88
|
+
this._overrideCache[scope] = field;
|
|
89
|
+
return field;
|
|
90
|
+
}
|
|
59
91
|
toJSON(options) {
|
|
60
92
|
const typeName = this.type
|
|
61
93
|
? this.node.getDataTypeNameWithNs(this.type)
|
|
@@ -24,7 +24,7 @@ exports.ComplexTypeBase = function (...args) {
|
|
|
24
24
|
*/
|
|
25
25
|
class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
26
26
|
fieldCount(scope) {
|
|
27
|
-
if (
|
|
27
|
+
if (scope === '*')
|
|
28
28
|
return this._fields.size;
|
|
29
29
|
let count = 0;
|
|
30
30
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -34,7 +34,7 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
|
34
34
|
}
|
|
35
35
|
fieldEntries(scope) {
|
|
36
36
|
let iterator = this._fields.entries();
|
|
37
|
-
if (
|
|
37
|
+
if (scope === '*')
|
|
38
38
|
return iterator;
|
|
39
39
|
let r;
|
|
40
40
|
return {
|
|
@@ -46,7 +46,12 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
|
46
46
|
if (r.value && r.value[1].inScope(scope))
|
|
47
47
|
break;
|
|
48
48
|
}
|
|
49
|
-
|
|
49
|
+
if (r.done)
|
|
50
|
+
return { done: r.done, value: undefined };
|
|
51
|
+
return {
|
|
52
|
+
done: r.done,
|
|
53
|
+
value: [r.value[0], r.value[1].forScope(scope)],
|
|
54
|
+
};
|
|
50
55
|
},
|
|
51
56
|
return(value) {
|
|
52
57
|
iterator = undefined;
|
|
@@ -58,8 +63,6 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
|
58
63
|
};
|
|
59
64
|
}
|
|
60
65
|
fields(scope) {
|
|
61
|
-
if (!scope)
|
|
62
|
-
return this._fields.values();
|
|
63
66
|
let iterator = this.fieldEntries(scope);
|
|
64
67
|
let r;
|
|
65
68
|
return {
|
|
@@ -67,7 +70,7 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
|
67
70
|
if (!iterator)
|
|
68
71
|
return { done: true, value: undefined };
|
|
69
72
|
r = iterator.next();
|
|
70
|
-
return { done: r.done, value: r.value[1] };
|
|
73
|
+
return { done: r.done, value: r.value?.[1] };
|
|
71
74
|
},
|
|
72
75
|
return(value) {
|
|
73
76
|
iterator = undefined;
|
|
@@ -79,7 +82,7 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
|
79
82
|
};
|
|
80
83
|
}
|
|
81
84
|
fieldNames(scope) {
|
|
82
|
-
if (
|
|
85
|
+
if (scope === '*')
|
|
83
86
|
return this._fields.keys();
|
|
84
87
|
let iterator = this.fieldEntries(scope);
|
|
85
88
|
let r;
|
|
@@ -88,7 +91,7 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
|
88
91
|
if (!iterator)
|
|
89
92
|
return { done: true, value: undefined };
|
|
90
93
|
r = iterator.next();
|
|
91
|
-
return { done: r.done, value: r.value[0] };
|
|
94
|
+
return { done: r.done, value: r.value?.[0] };
|
|
92
95
|
},
|
|
93
96
|
return(value) {
|
|
94
97
|
iterator = undefined;
|
|
@@ -112,19 +115,19 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
|
112
115
|
}
|
|
113
116
|
const field = this._fields.get(nameOrPath);
|
|
114
117
|
if (field && field.inScope(scope))
|
|
115
|
-
return field;
|
|
118
|
+
return field.forScope(scope);
|
|
116
119
|
}
|
|
117
120
|
/**
|
|
118
121
|
*
|
|
119
122
|
*/
|
|
120
123
|
getField(nameOrPath, scope) {
|
|
121
|
-
const field = this.findField(nameOrPath);
|
|
124
|
+
const field = this.findField(nameOrPath, '*');
|
|
122
125
|
if (field && !field.inScope(scope))
|
|
123
126
|
throw new Error(`Field "${nameOrPath}" does not exist in scope "${scope || 'null'}"`);
|
|
124
127
|
if (!field) {
|
|
125
128
|
throw new Error(`Field (${nameOrPath}) does not exist`);
|
|
126
129
|
}
|
|
127
|
-
return field;
|
|
130
|
+
return field.forScope(scope);
|
|
128
131
|
}
|
|
129
132
|
/**
|
|
130
133
|
*
|
|
@@ -154,7 +157,7 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
|
154
157
|
}
|
|
155
158
|
if (dataType) {
|
|
156
159
|
if (dataType instanceof exports.ComplexTypeBase) {
|
|
157
|
-
field = dataType.
|
|
160
|
+
field = dataType.findField(item.fieldName, options?.scope);
|
|
158
161
|
if (field) {
|
|
159
162
|
item.fieldName = field.name;
|
|
160
163
|
item.field = field;
|
|
@@ -233,7 +236,7 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
|
233
236
|
const pickList = !!(projection && Object.values(projection).find(p => !p.sign));
|
|
234
237
|
// Process fields
|
|
235
238
|
let fieldName;
|
|
236
|
-
for (const field of this.
|
|
239
|
+
for (const field of this.fields('*')) {
|
|
237
240
|
if (
|
|
238
241
|
/** Ignore field if required scope(s) do not match field scopes */
|
|
239
242
|
!field.inScope(context.scope) ||
|
|
@@ -34,7 +34,7 @@ exports.ComplexType = function (...args) {
|
|
|
34
34
|
_this.additionalFields = _this.base.additionalFields;
|
|
35
35
|
_this.keyField = _this.base.keyField;
|
|
36
36
|
/** Copy fields from base */
|
|
37
|
-
for (const v of _this.base.fields()) {
|
|
37
|
+
for (const v of _this.base.fields('*')) {
|
|
38
38
|
_this._fields.set(v.name, new api_field_js_1.ApiField(this, v));
|
|
39
39
|
}
|
|
40
40
|
});
|
|
@@ -30,7 +30,7 @@ exports.MixinType = function (...args) {
|
|
|
30
30
|
else if (!_this.additionalFields)
|
|
31
31
|
_this.additionalFields = base.additionalFields;
|
|
32
32
|
}
|
|
33
|
-
for (const v of base.fields()) {
|
|
33
|
+
for (const v of base.fields('*')) {
|
|
34
34
|
const field = new api_field_js_1.ApiField(this, v);
|
|
35
35
|
_this._fields.set(field.name, field);
|
|
36
36
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ApiFieldDecoratorFactory = ApiFieldDecoratorFactory;
|
|
4
|
-
|
|
5
|
-
// import { StrictOmit } from 'ts-gems';
|
|
4
|
+
const objects_1 = require("@jsopen/objects");
|
|
6
5
|
const index_js_1 = require("../../schema/index.js");
|
|
7
6
|
const constants_js_1 = require("../constants.js");
|
|
8
7
|
function ApiFieldDecoratorFactory(options) {
|
|
@@ -28,27 +27,22 @@ function ApiFieldDecoratorFactory(options) {
|
|
|
28
27
|
elemMeta.type = elemMeta.type || designType;
|
|
29
28
|
Reflect.defineMetadata(constants_js_1.DATATYPE_METADATA, metadata, target.constructor);
|
|
30
29
|
for (const fn of decoratorChain)
|
|
31
|
-
fn(
|
|
30
|
+
fn(elemMeta);
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
*/
|
|
35
|
+
decorator.Override = (scopes, opts) => {
|
|
36
|
+
decoratorChain.push((meta) => {
|
|
37
|
+
meta.override = meta.override || [];
|
|
38
|
+
meta.override.push((0, objects_1.omitUndefined)({
|
|
39
|
+
...opts,
|
|
40
|
+
scopePattern: Array.isArray(scopes) ? scopes : [scopes],
|
|
41
|
+
type: undefined,
|
|
42
|
+
isArray: undefined,
|
|
43
|
+
}));
|
|
44
|
+
});
|
|
45
|
+
return decorator;
|
|
32
46
|
};
|
|
33
|
-
// /**
|
|
34
|
-
// *
|
|
35
|
-
// */
|
|
36
|
-
// decorator.Override = (
|
|
37
|
-
// scopes: (string | RegExp) | (string | RegExp)[],
|
|
38
|
-
// opts: StrictOmit<ApiField.Options, 'isArray' | 'type' | 'scopePattern'>,
|
|
39
|
-
// ): any => {
|
|
40
|
-
// decoratorChain.push((meta: ApiField.Metadata): void => {
|
|
41
|
-
// meta.overrides = meta.overrides || [];
|
|
42
|
-
// meta.overrides.push(
|
|
43
|
-
// omitUndefined({
|
|
44
|
-
// ...opts,
|
|
45
|
-
// scopes: Array.isArray(scopes) ? scopes : [scopes],
|
|
46
|
-
// type: undefined,
|
|
47
|
-
// isArray: undefined,
|
|
48
|
-
// }),
|
|
49
|
-
// );
|
|
50
|
-
// });
|
|
51
|
-
// return decorator;
|
|
52
|
-
// };
|
|
53
47
|
return decorator;
|
|
54
48
|
}
|
|
@@ -283,6 +283,7 @@ class DataTypeFactory {
|
|
|
283
283
|
initArgs.description = metadata.description;
|
|
284
284
|
initArgs.abstract = metadata.abstract;
|
|
285
285
|
initArgs.examples = metadata.examples;
|
|
286
|
+
initArgs.scopePattern = metadata.scopePattern;
|
|
286
287
|
}
|
|
287
288
|
static async _prepareComplexTypeArgs(context, owner, initArgs, metadata) {
|
|
288
289
|
await this._prepareDataTypeArgs(context, initArgs, metadata);
|
|
@@ -33,8 +33,8 @@ export class DocumentNode {
|
|
|
33
33
|
* Returns DataType instance by name or Constructor. Returns undefined if not found
|
|
34
34
|
*/
|
|
35
35
|
getDataType(nameOrCtor, scope) {
|
|
36
|
-
const dt = this.findDataType(nameOrCtor);
|
|
37
|
-
if (dt
|
|
36
|
+
const dt = this.findDataType(nameOrCtor, scope);
|
|
37
|
+
if (dt)
|
|
38
38
|
return dt;
|
|
39
39
|
let name = '';
|
|
40
40
|
if (typeof nameOrCtor === 'function') {
|
|
@@ -43,6 +43,7 @@ export const ApiField = function (...args) {
|
|
|
43
43
|
_this.readonly = initArgs.readonly;
|
|
44
44
|
_this.writeonly = initArgs.writeonly;
|
|
45
45
|
_this.examples = initArgs.examples;
|
|
46
|
+
_this.override = initArgs.override;
|
|
46
47
|
};
|
|
47
48
|
/**
|
|
48
49
|
* The ApiFieldClass represents a descriptive metadata structure for API fields,
|
|
@@ -53,6 +54,37 @@ class ApiFieldClass extends DocumentElement {
|
|
|
53
54
|
inScope(scope) {
|
|
54
55
|
return testScopeMatch(scope, this.scopePattern);
|
|
55
56
|
}
|
|
57
|
+
forScope(scope) {
|
|
58
|
+
if (!(scope && this.override))
|
|
59
|
+
return this;
|
|
60
|
+
this._overrideCache = this._overrideCache || {};
|
|
61
|
+
let field = this._overrideCache[scope];
|
|
62
|
+
if (field)
|
|
63
|
+
return field;
|
|
64
|
+
if (scope !== '*') {
|
|
65
|
+
for (const o of this.override) {
|
|
66
|
+
if (testScopeMatch(scope, o.scopePattern)) {
|
|
67
|
+
field = omitUndefined({
|
|
68
|
+
...o,
|
|
69
|
+
id: undefined,
|
|
70
|
+
owner: undefined,
|
|
71
|
+
node: undefined,
|
|
72
|
+
origin: undefined,
|
|
73
|
+
name: undefined,
|
|
74
|
+
type: undefined,
|
|
75
|
+
override: undefined,
|
|
76
|
+
_overrideCache: undefined,
|
|
77
|
+
scopePattern: o.scopePattern,
|
|
78
|
+
});
|
|
79
|
+
Object.setPrototypeOf(field, this);
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
field = field || this;
|
|
85
|
+
this._overrideCache[scope] = field;
|
|
86
|
+
return field;
|
|
87
|
+
}
|
|
56
88
|
toJSON(options) {
|
|
57
89
|
const typeName = this.type
|
|
58
90
|
? this.node.getDataTypeNameWithNs(this.type)
|
|
@@ -21,7 +21,7 @@ export const ComplexTypeBase = function (...args) {
|
|
|
21
21
|
*/
|
|
22
22
|
class ComplexTypeBaseClass extends DataType {
|
|
23
23
|
fieldCount(scope) {
|
|
24
|
-
if (
|
|
24
|
+
if (scope === '*')
|
|
25
25
|
return this._fields.size;
|
|
26
26
|
let count = 0;
|
|
27
27
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -31,7 +31,7 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
31
31
|
}
|
|
32
32
|
fieldEntries(scope) {
|
|
33
33
|
let iterator = this._fields.entries();
|
|
34
|
-
if (
|
|
34
|
+
if (scope === '*')
|
|
35
35
|
return iterator;
|
|
36
36
|
let r;
|
|
37
37
|
return {
|
|
@@ -43,7 +43,12 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
43
43
|
if (r.value && r.value[1].inScope(scope))
|
|
44
44
|
break;
|
|
45
45
|
}
|
|
46
|
-
|
|
46
|
+
if (r.done)
|
|
47
|
+
return { done: r.done, value: undefined };
|
|
48
|
+
return {
|
|
49
|
+
done: r.done,
|
|
50
|
+
value: [r.value[0], r.value[1].forScope(scope)],
|
|
51
|
+
};
|
|
47
52
|
},
|
|
48
53
|
return(value) {
|
|
49
54
|
iterator = undefined;
|
|
@@ -55,8 +60,6 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
55
60
|
};
|
|
56
61
|
}
|
|
57
62
|
fields(scope) {
|
|
58
|
-
if (!scope)
|
|
59
|
-
return this._fields.values();
|
|
60
63
|
let iterator = this.fieldEntries(scope);
|
|
61
64
|
let r;
|
|
62
65
|
return {
|
|
@@ -64,7 +67,7 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
64
67
|
if (!iterator)
|
|
65
68
|
return { done: true, value: undefined };
|
|
66
69
|
r = iterator.next();
|
|
67
|
-
return { done: r.done, value: r.value[1] };
|
|
70
|
+
return { done: r.done, value: r.value?.[1] };
|
|
68
71
|
},
|
|
69
72
|
return(value) {
|
|
70
73
|
iterator = undefined;
|
|
@@ -76,7 +79,7 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
76
79
|
};
|
|
77
80
|
}
|
|
78
81
|
fieldNames(scope) {
|
|
79
|
-
if (
|
|
82
|
+
if (scope === '*')
|
|
80
83
|
return this._fields.keys();
|
|
81
84
|
let iterator = this.fieldEntries(scope);
|
|
82
85
|
let r;
|
|
@@ -85,7 +88,7 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
85
88
|
if (!iterator)
|
|
86
89
|
return { done: true, value: undefined };
|
|
87
90
|
r = iterator.next();
|
|
88
|
-
return { done: r.done, value: r.value[0] };
|
|
91
|
+
return { done: r.done, value: r.value?.[0] };
|
|
89
92
|
},
|
|
90
93
|
return(value) {
|
|
91
94
|
iterator = undefined;
|
|
@@ -109,19 +112,19 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
109
112
|
}
|
|
110
113
|
const field = this._fields.get(nameOrPath);
|
|
111
114
|
if (field && field.inScope(scope))
|
|
112
|
-
return field;
|
|
115
|
+
return field.forScope(scope);
|
|
113
116
|
}
|
|
114
117
|
/**
|
|
115
118
|
*
|
|
116
119
|
*/
|
|
117
120
|
getField(nameOrPath, scope) {
|
|
118
|
-
const field = this.findField(nameOrPath);
|
|
121
|
+
const field = this.findField(nameOrPath, '*');
|
|
119
122
|
if (field && !field.inScope(scope))
|
|
120
123
|
throw new Error(`Field "${nameOrPath}" does not exist in scope "${scope || 'null'}"`);
|
|
121
124
|
if (!field) {
|
|
122
125
|
throw new Error(`Field (${nameOrPath}) does not exist`);
|
|
123
126
|
}
|
|
124
|
-
return field;
|
|
127
|
+
return field.forScope(scope);
|
|
125
128
|
}
|
|
126
129
|
/**
|
|
127
130
|
*
|
|
@@ -151,7 +154,7 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
151
154
|
}
|
|
152
155
|
if (dataType) {
|
|
153
156
|
if (dataType instanceof ComplexTypeBase) {
|
|
154
|
-
field = dataType.
|
|
157
|
+
field = dataType.findField(item.fieldName, options?.scope);
|
|
155
158
|
if (field) {
|
|
156
159
|
item.fieldName = field.name;
|
|
157
160
|
item.field = field;
|
|
@@ -230,7 +233,7 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
230
233
|
const pickList = !!(projection && Object.values(projection).find(p => !p.sign));
|
|
231
234
|
// Process fields
|
|
232
235
|
let fieldName;
|
|
233
|
-
for (const field of this.
|
|
236
|
+
for (const field of this.fields('*')) {
|
|
234
237
|
if (
|
|
235
238
|
/** Ignore field if required scope(s) do not match field scopes */
|
|
236
239
|
!field.inScope(context.scope) ||
|
|
@@ -31,7 +31,7 @@ export const ComplexType = function (...args) {
|
|
|
31
31
|
_this.additionalFields = _this.base.additionalFields;
|
|
32
32
|
_this.keyField = _this.base.keyField;
|
|
33
33
|
/** Copy fields from base */
|
|
34
|
-
for (const v of _this.base.fields()) {
|
|
34
|
+
for (const v of _this.base.fields('*')) {
|
|
35
35
|
_this._fields.set(v.name, new ApiField(this, v));
|
|
36
36
|
}
|
|
37
37
|
});
|
|
@@ -27,7 +27,7 @@ export const MixinType = function (...args) {
|
|
|
27
27
|
else if (!_this.additionalFields)
|
|
28
28
|
_this.additionalFields = base.additionalFields;
|
|
29
29
|
}
|
|
30
|
-
for (const v of base.fields()) {
|
|
30
|
+
for (const v of base.fields('*')) {
|
|
31
31
|
const field = new ApiField(this, v);
|
|
32
32
|
_this._fields.set(field.name, field);
|
|
33
33
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// import { StrictOmit } from 'ts-gems';
|
|
1
|
+
import { omitUndefined } from '@jsopen/objects';
|
|
3
2
|
import { OpraSchema } from '../../schema/index.js';
|
|
4
3
|
import { DATATYPE_METADATA } from '../constants.js';
|
|
5
4
|
export function ApiFieldDecoratorFactory(options) {
|
|
@@ -25,27 +24,22 @@ export function ApiFieldDecoratorFactory(options) {
|
|
|
25
24
|
elemMeta.type = elemMeta.type || designType;
|
|
26
25
|
Reflect.defineMetadata(DATATYPE_METADATA, metadata, target.constructor);
|
|
27
26
|
for (const fn of decoratorChain)
|
|
28
|
-
fn(
|
|
27
|
+
fn(elemMeta);
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
*/
|
|
32
|
+
decorator.Override = (scopes, opts) => {
|
|
33
|
+
decoratorChain.push((meta) => {
|
|
34
|
+
meta.override = meta.override || [];
|
|
35
|
+
meta.override.push(omitUndefined({
|
|
36
|
+
...opts,
|
|
37
|
+
scopePattern: Array.isArray(scopes) ? scopes : [scopes],
|
|
38
|
+
type: undefined,
|
|
39
|
+
isArray: undefined,
|
|
40
|
+
}));
|
|
41
|
+
});
|
|
42
|
+
return decorator;
|
|
29
43
|
};
|
|
30
|
-
// /**
|
|
31
|
-
// *
|
|
32
|
-
// */
|
|
33
|
-
// decorator.Override = (
|
|
34
|
-
// scopes: (string | RegExp) | (string | RegExp)[],
|
|
35
|
-
// opts: StrictOmit<ApiField.Options, 'isArray' | 'type' | 'scopePattern'>,
|
|
36
|
-
// ): any => {
|
|
37
|
-
// decoratorChain.push((meta: ApiField.Metadata): void => {
|
|
38
|
-
// meta.overrides = meta.overrides || [];
|
|
39
|
-
// meta.overrides.push(
|
|
40
|
-
// omitUndefined({
|
|
41
|
-
// ...opts,
|
|
42
|
-
// scopes: Array.isArray(scopes) ? scopes : [scopes],
|
|
43
|
-
// type: undefined,
|
|
44
|
-
// isArray: undefined,
|
|
45
|
-
// }),
|
|
46
|
-
// );
|
|
47
|
-
// });
|
|
48
|
-
// return decorator;
|
|
49
|
-
// };
|
|
50
44
|
return decorator;
|
|
51
45
|
}
|
|
@@ -280,6 +280,7 @@ export class DataTypeFactory {
|
|
|
280
280
|
initArgs.description = metadata.description;
|
|
281
281
|
initArgs.abstract = metadata.abstract;
|
|
282
282
|
initArgs.examples = metadata.examples;
|
|
283
|
+
initArgs.scopePattern = metadata.scopePattern;
|
|
283
284
|
}
|
|
284
285
|
static async _prepareComplexTypeArgs(context, owner, initArgs, metadata) {
|
|
285
286
|
await this._prepareDataTypeArgs(context, initArgs, metadata);
|
package/package.json
CHANGED
|
@@ -19,41 +19,41 @@ export declare class DocumentNode {
|
|
|
19
19
|
readonly element: DocumentElement;
|
|
20
20
|
constructor(element: DocumentElement, parent?: DocumentNode);
|
|
21
21
|
getDocument(): ApiDocument;
|
|
22
|
-
hasDataType(nameOrCtor: string | Type | Function | object | any[], scope?: string): boolean;
|
|
23
|
-
findDataType(nameOrCtor: string | Type | Function | object | any[], scope?: string): DataType | undefined;
|
|
22
|
+
hasDataType(nameOrCtor: string | Type | Function | object | any[], scope?: string | '*'): boolean;
|
|
23
|
+
findDataType(nameOrCtor: string | Type | Function | object | any[], scope?: string | '*'): DataType | undefined;
|
|
24
24
|
/**
|
|
25
25
|
* Returns DataType instance by name or Constructor. Returns undefined if not found
|
|
26
26
|
*/
|
|
27
|
-
getDataType(nameOrCtor: string | Type | Function | object | any[], scope?: string): DataType;
|
|
27
|
+
getDataType(nameOrCtor: string | Type | Function | object | any[], scope?: string | '*'): DataType;
|
|
28
28
|
getDataTypeNameWithNs(dataType: DataType): string | undefined;
|
|
29
29
|
/**
|
|
30
30
|
* Returns ComplexType instance by name or Constructor.
|
|
31
31
|
* Returns undefined if not found
|
|
32
32
|
* Throws error if data type is not a ComplexType
|
|
33
33
|
*/
|
|
34
|
-
getComplexType(nameOrCtor: string | Type | Function, scope?: string): ComplexType;
|
|
34
|
+
getComplexType(nameOrCtor: string | Type | Function, scope?: string | '*'): ComplexType;
|
|
35
35
|
/**
|
|
36
36
|
* Returns SimpleType instance by name or Constructor.
|
|
37
37
|
* Returns undefined if not found
|
|
38
38
|
* Throws error if data type is not a SimpleType
|
|
39
39
|
*/
|
|
40
|
-
getSimpleType(nameOrCtor: string | Type, scope?: string): SimpleType;
|
|
40
|
+
getSimpleType(nameOrCtor: string | Type, scope?: string | '*'): SimpleType;
|
|
41
41
|
/**
|
|
42
42
|
* Returns EnumType instance by name or Constructor.
|
|
43
43
|
* Returns undefined if not found
|
|
44
44
|
* Throws error if data type is not a EnumType
|
|
45
45
|
*/
|
|
46
|
-
getEnumType(nameOrCtor: string | object | any[], scope?: string): EnumType;
|
|
46
|
+
getEnumType(nameOrCtor: string | object | any[], scope?: string | '*'): EnumType;
|
|
47
47
|
/**
|
|
48
48
|
* Returns EnumType instance by name or Constructor.
|
|
49
49
|
* Returns undefined if not found
|
|
50
50
|
* Throws error if data type is not a MappedType
|
|
51
51
|
*/
|
|
52
|
-
getMappedType(nameOrCtor: string | object | any[], scope?: string): MappedType;
|
|
52
|
+
getMappedType(nameOrCtor: string | object | any[], scope?: string | '*'): MappedType;
|
|
53
53
|
/**
|
|
54
54
|
* Returns EnumType instance by name or Constructor.
|
|
55
55
|
* Returns undefined if not found
|
|
56
56
|
* Throws error if data type is not a MixinType
|
|
57
57
|
*/
|
|
58
|
-
getMixinType(nameOrCtor: string | object | any[], scope?: string): MixinType;
|
|
58
|
+
getMixinType(nameOrCtor: string | object | any[], scope?: string | '*'): MixinType;
|
|
59
59
|
}
|
|
@@ -35,6 +35,7 @@ export declare const ApiField: ApiFieldConstructor;
|
|
|
35
35
|
* This class extends DocumentElement, inheriting base document structure capabilities.
|
|
36
36
|
*/
|
|
37
37
|
declare class ApiFieldClass extends DocumentElement {
|
|
38
|
+
protected _overrideCache?: Record<string, this>;
|
|
38
39
|
readonly owner: ComplexType | MappedType | MixinType;
|
|
39
40
|
readonly origin?: ComplexType | MappedType | MixinType;
|
|
40
41
|
readonly scopePattern?: (string | RegExp)[];
|
|
@@ -52,7 +53,9 @@ declare class ApiFieldClass extends DocumentElement {
|
|
|
52
53
|
readonly readonly?: boolean;
|
|
53
54
|
readonly writeonly?: boolean;
|
|
54
55
|
readonly examples?: any[] | Record<string, any>;
|
|
55
|
-
|
|
56
|
+
readonly override: ApiField.InitArguments['override'];
|
|
57
|
+
inScope(scope?: string | '*'): boolean;
|
|
58
|
+
forScope(scope?: string): this;
|
|
56
59
|
toJSON(options?: ApiDocument.ExportOptions): OpraSchema.Field;
|
|
57
60
|
}
|
|
58
61
|
/**
|
|
@@ -63,9 +66,9 @@ export declare namespace ApiField {
|
|
|
63
66
|
type?: string | OpraSchema.DataType | TypeThunkAsync | EnumType.EnumObject | EnumType.EnumArray | object;
|
|
64
67
|
}, OpraSchema.Field> {
|
|
65
68
|
scopePattern?: (string | RegExp) | (string | RegExp)[];
|
|
66
|
-
|
|
69
|
+
override?: StrictOmit<Metadata, 'override' | 'type' | 'isArray'>[];
|
|
67
70
|
}
|
|
68
|
-
interface Options extends Partial<StrictOmit<Metadata, '
|
|
71
|
+
interface Options extends Partial<StrictOmit<Metadata, 'override' | 'scopePattern'>> {
|
|
69
72
|
/**
|
|
70
73
|
* A variable that defines the pattern or patterns used to determine scope.
|
|
71
74
|
* This can either be a single string or regular expression, or an array containing multiple strings or regular expressions.
|
|
@@ -50,7 +50,7 @@ declare abstract class ComplexTypeBaseClass extends DataType {
|
|
|
50
50
|
/**
|
|
51
51
|
*
|
|
52
52
|
*/
|
|
53
|
-
findField(nameOrPath: string, scope?: string): ApiField | undefined;
|
|
53
|
+
findField(nameOrPath: string, scope?: string | '*'): ApiField | undefined;
|
|
54
54
|
/**
|
|
55
55
|
*
|
|
56
56
|
*/
|
|
@@ -60,7 +60,7 @@ declare abstract class ComplexTypeBaseClass extends DataType {
|
|
|
60
60
|
*/
|
|
61
61
|
parseFieldPath(fieldPath: string, options?: {
|
|
62
62
|
allowSigns?: 'first' | 'each';
|
|
63
|
-
scope?: string;
|
|
63
|
+
scope?: string | '*';
|
|
64
64
|
}): ComplexType.ParsedFieldPath[];
|
|
65
65
|
/**
|
|
66
66
|
*
|
|
@@ -13,13 +13,12 @@ import { nodeInspectCustom } from '../utils/inspect.util.js';
|
|
|
13
13
|
export declare namespace DataType {
|
|
14
14
|
interface Metadata extends DataTypeBase {
|
|
15
15
|
name?: string;
|
|
16
|
+
scopePattern?: (string | RegExp) | (string | RegExp)[];
|
|
16
17
|
}
|
|
17
18
|
interface Options extends Partial<StrictOmit<Metadata, 'kind' | 'examples'>> {
|
|
18
19
|
embedded?: boolean;
|
|
19
|
-
scopePattern?: (string | RegExp) | (string | RegExp)[];
|
|
20
20
|
}
|
|
21
21
|
interface InitArguments extends DataType.Metadata {
|
|
22
|
-
scopePattern?: (string | RegExp) | (string | RegExp)[];
|
|
23
22
|
}
|
|
24
23
|
interface GenerateCodecOptions extends ValidationOptions {
|
|
25
24
|
documentElement?: DocumentElement;
|
|
@@ -61,7 +60,7 @@ declare abstract class DataTypeClass extends DocumentElement {
|
|
|
61
60
|
abstract generateCodec(codec: 'encode' | 'decode', options?: DataType.GenerateCodecOptions): Validator;
|
|
62
61
|
get embedded(): any;
|
|
63
62
|
abstract extendsFrom(baseType: DataType | string | Type | object): boolean;
|
|
64
|
-
inScope(scope?: string): boolean;
|
|
63
|
+
inScope(scope?: string | '*'): boolean;
|
|
65
64
|
toJSON(options?: ApiDocument.ExportOptions): OpraSchema.DataType;
|
|
66
65
|
toString(): string;
|
|
67
66
|
protected abstract _locateBase(callback: (base: DataType) => boolean): DataType | undefined;
|
|
@@ -1,5 +1,16 @@
|
|
|
1
|
+
import { StrictOmit } from 'ts-gems';
|
|
1
2
|
import type { ApiField } from '../data-type/api-field.js';
|
|
2
3
|
export interface ApiFieldDecorator extends PropertyDecorator {
|
|
4
|
+
/**
|
|
5
|
+
* Overrides the default settings of an API field with specified options.
|
|
6
|
+
*
|
|
7
|
+
* @param {string | RegExp | (string | RegExp)[]} scopePattern - A pattern or array of patterns that defines the scope
|
|
8
|
+
* within which the override applies. Patterns can be strings or regular expressions.
|
|
9
|
+
* @param {StrictOmit<ApiField.Options, 'isArray' | 'type' | 'scopePattern'>} options - Configuration options to override
|
|
10
|
+
* the default API field behavior, excluding the properties 'isArray', 'type', and 'scopePattern'.
|
|
11
|
+
* @return {ApiFieldDecorator} The decorated API field after applying the override configuration.
|
|
12
|
+
*/
|
|
13
|
+
Override(scopePattern: (string | RegExp) | (string | RegExp)[], options: StrictOmit<ApiField.Options, 'isArray' | 'type' | 'scopePattern'>): ApiFieldDecorator;
|
|
3
14
|
}
|
|
4
15
|
export interface ApiFieldDecoratorFactory {
|
|
5
16
|
(options?: ApiField.Options): ApiFieldDecorator;
|