@opra/common 1.5.1 → 1.5.3
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/api-document.js +2 -2
- package/cjs/document/common/document-node.js +2 -2
- package/cjs/document/data-type/complex-type-base.js +84 -9
- package/cjs/document/data-type/complex-type.js +6 -7
- package/cjs/document/data-type/data-type.js +5 -7
- package/cjs/document/data-type/mapped-type.js +2 -2
- package/cjs/document/data-type/mixin-type.js +2 -2
- package/cjs/document/data-type/simple-type.js +8 -0
- package/cjs/document/utils/test-scope-match.js +3 -1
- package/esm/document/api-document.js +2 -2
- package/esm/document/common/document-node.js +2 -2
- package/esm/document/data-type/complex-type-base.js +84 -9
- package/esm/document/data-type/complex-type.js +6 -7
- package/esm/document/data-type/data-type.js +5 -7
- package/esm/document/data-type/mapped-type.js +2 -2
- package/esm/document/data-type/mixin-type.js +2 -2
- package/esm/document/data-type/simple-type.js +8 -0
- package/esm/document/utils/test-scope-match.js +3 -1
- package/package.json +1 -1
- package/types/document/data-type/api-field.d.ts +1 -1
- package/types/document/data-type/complex-type-base.d.ts +5 -1
- package/types/document/data-type/data-type.d.ts +1 -1
- package/types/document/data-type/simple-type.d.ts +1 -0
- package/types/document/factory/api-document.factory.d.ts +0 -1
- package/types/document/utils/test-scope-match.d.ts +1 -1
|
@@ -93,7 +93,7 @@ class ApiDocument extends document_element_js_1.DocumentElement {
|
|
|
93
93
|
if (this.types.size) {
|
|
94
94
|
out.types = {};
|
|
95
95
|
for (const v of this.types.values()) {
|
|
96
|
-
if (
|
|
96
|
+
if (!v.inScope(options?.scope))
|
|
97
97
|
continue;
|
|
98
98
|
out.types[v.name] = v.toJSON(options);
|
|
99
99
|
}
|
|
@@ -112,7 +112,7 @@ class ApiDocument extends document_element_js_1.DocumentElement {
|
|
|
112
112
|
}
|
|
113
113
|
_findDataType(nameOrCtor, scope, visitedRefs) {
|
|
114
114
|
let result = this.types.get(nameOrCtor);
|
|
115
|
-
if (result &&
|
|
115
|
+
if (result && result.inScope(scope))
|
|
116
116
|
return result;
|
|
117
117
|
if (!this.references.size)
|
|
118
118
|
return;
|
|
@@ -26,7 +26,7 @@ class DocumentNode {
|
|
|
26
26
|
}
|
|
27
27
|
findDataType(nameOrCtor, scope) {
|
|
28
28
|
const dt = this[constants_js_1.kDataTypeMap]?.get(nameOrCtor);
|
|
29
|
-
if (dt &&
|
|
29
|
+
if (dt && dt.inScope(scope))
|
|
30
30
|
return dt;
|
|
31
31
|
return this.parent
|
|
32
32
|
? this.parent.findDataType(nameOrCtor, scope)
|
|
@@ -37,7 +37,7 @@ class DocumentNode {
|
|
|
37
37
|
*/
|
|
38
38
|
getDataType(nameOrCtor, scope) {
|
|
39
39
|
const dt = this.findDataType(nameOrCtor);
|
|
40
|
-
if (dt &&
|
|
40
|
+
if (dt && dt.inScope(scope))
|
|
41
41
|
return dt;
|
|
42
42
|
let name = '';
|
|
43
43
|
if (typeof nameOrCtor === 'function') {
|
|
@@ -17,12 +17,88 @@ exports.ComplexTypeBase = function (...args) {
|
|
|
17
17
|
const [owner, initArgs, context] = args;
|
|
18
18
|
data_type_js_1.DataType.call(this, owner, initArgs, context);
|
|
19
19
|
const _this = (0, ts_gems_1.asMutable)(this);
|
|
20
|
-
_this.
|
|
20
|
+
_this._fields = new index_js_1.ResponsiveMap();
|
|
21
21
|
};
|
|
22
22
|
/**
|
|
23
23
|
*
|
|
24
24
|
*/
|
|
25
25
|
class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
26
|
+
fieldCount(scope) {
|
|
27
|
+
if (!scope)
|
|
28
|
+
return this._fields.size;
|
|
29
|
+
let count = 0;
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
31
|
+
for (const i of this.fields(scope))
|
|
32
|
+
count++;
|
|
33
|
+
return count;
|
|
34
|
+
}
|
|
35
|
+
fieldEntries(scope) {
|
|
36
|
+
let iterator = this._fields.entries();
|
|
37
|
+
if (!scope)
|
|
38
|
+
return iterator;
|
|
39
|
+
let r;
|
|
40
|
+
return {
|
|
41
|
+
next() {
|
|
42
|
+
while (iterator) {
|
|
43
|
+
r = iterator.next();
|
|
44
|
+
if (r.done)
|
|
45
|
+
break;
|
|
46
|
+
if (r.value && r.value[1].inScope(scope))
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
return r;
|
|
50
|
+
},
|
|
51
|
+
return(value) {
|
|
52
|
+
iterator = undefined;
|
|
53
|
+
return { done: true, value };
|
|
54
|
+
},
|
|
55
|
+
[Symbol.iterator]() {
|
|
56
|
+
return this;
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
fields(scope) {
|
|
61
|
+
if (!scope)
|
|
62
|
+
return this._fields.values();
|
|
63
|
+
let iterator = this.fieldEntries(scope);
|
|
64
|
+
let r;
|
|
65
|
+
return {
|
|
66
|
+
next() {
|
|
67
|
+
if (!iterator)
|
|
68
|
+
return { done: true, value: undefined };
|
|
69
|
+
r = iterator.next();
|
|
70
|
+
return { done: r.done, value: r.value[1] };
|
|
71
|
+
},
|
|
72
|
+
return(value) {
|
|
73
|
+
iterator = undefined;
|
|
74
|
+
return { done: true, value };
|
|
75
|
+
},
|
|
76
|
+
[Symbol.iterator]() {
|
|
77
|
+
return this;
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
fieldNames(scope) {
|
|
82
|
+
if (!scope)
|
|
83
|
+
return this._fields.keys();
|
|
84
|
+
let iterator = this.fieldEntries(scope);
|
|
85
|
+
let r;
|
|
86
|
+
return {
|
|
87
|
+
next() {
|
|
88
|
+
if (!iterator)
|
|
89
|
+
return { done: true, value: undefined };
|
|
90
|
+
r = iterator.next();
|
|
91
|
+
return { done: r.done, value: r.value[0] };
|
|
92
|
+
},
|
|
93
|
+
return(value) {
|
|
94
|
+
iterator = undefined;
|
|
95
|
+
return { done: true, value };
|
|
96
|
+
},
|
|
97
|
+
[Symbol.iterator]() {
|
|
98
|
+
return this;
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
26
102
|
/**
|
|
27
103
|
*
|
|
28
104
|
*/
|
|
@@ -34,18 +110,17 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
|
34
110
|
const lastItem = fieldPath.pop();
|
|
35
111
|
return lastItem?.field;
|
|
36
112
|
}
|
|
37
|
-
const field = this.
|
|
38
|
-
if (field &&
|
|
39
|
-
return;
|
|
40
|
-
return field;
|
|
113
|
+
const field = this._fields.get(nameOrPath);
|
|
114
|
+
if (field && field.inScope(scope))
|
|
115
|
+
return field;
|
|
41
116
|
}
|
|
42
117
|
/**
|
|
43
118
|
*
|
|
44
119
|
*/
|
|
45
120
|
getField(nameOrPath, scope) {
|
|
46
121
|
const field = this.findField(nameOrPath);
|
|
47
|
-
if (field &&
|
|
48
|
-
throw new Error(`Field "${nameOrPath}" does not exist in scope "${scope}"`);
|
|
122
|
+
if (field && !field.inScope(scope))
|
|
123
|
+
throw new Error(`Field "${nameOrPath}" does not exist in scope "${scope || 'null'}"`);
|
|
49
124
|
if (!field) {
|
|
50
125
|
throw new Error(`Field (${nameOrPath}) does not exist`);
|
|
51
126
|
}
|
|
@@ -158,10 +233,10 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
|
158
233
|
const pickList = !!(projection && Object.values(projection).find(p => !p.sign));
|
|
159
234
|
// Process fields
|
|
160
235
|
let fieldName;
|
|
161
|
-
for (const field of this.
|
|
236
|
+
for (const field of this._fields.values()) {
|
|
162
237
|
if (
|
|
163
238
|
/** Ignore field if required scope(s) do not match field scopes */
|
|
164
|
-
|
|
239
|
+
!field.inScope(context.scope) ||
|
|
165
240
|
/** Ignore field if readonly and ignoreReadonlyFields option true */
|
|
166
241
|
(context.ignoreReadonlyFields && field.readonly) ||
|
|
167
242
|
/** Ignore field if writeonly and ignoreWriteonlyFields option true */
|
|
@@ -34,8 +34,8 @@ 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
|
|
38
|
-
|
|
37
|
+
for (const v of _this.base.fields()) {
|
|
38
|
+
_this._fields.set(v.name, new api_field_js_1.ApiField(this, v));
|
|
39
39
|
}
|
|
40
40
|
});
|
|
41
41
|
}
|
|
@@ -52,7 +52,7 @@ exports.ComplexType = function (...args) {
|
|
|
52
52
|
...v,
|
|
53
53
|
name: k,
|
|
54
54
|
});
|
|
55
|
-
this.
|
|
55
|
+
this._fields.set(field.name, field);
|
|
56
56
|
}
|
|
57
57
|
});
|
|
58
58
|
}
|
|
@@ -95,12 +95,11 @@ class ComplexTypeClass extends complex_type_base_js_1.ComplexTypeBase {
|
|
|
95
95
|
else
|
|
96
96
|
out.additionalFields = this.additionalFields;
|
|
97
97
|
}
|
|
98
|
-
if (this.
|
|
98
|
+
if (this._fields.size) {
|
|
99
99
|
const fields = {};
|
|
100
100
|
let i = 0;
|
|
101
|
-
for (const field of this.
|
|
102
|
-
if (field.origin === this &&
|
|
103
|
-
(!options?.scope || field.inScope(options?.scope))) {
|
|
101
|
+
for (const field of this._fields.values()) {
|
|
102
|
+
if (field.origin === this && field.inScope(options?.scope)) {
|
|
104
103
|
fields[field.name] = field.toJSON(options);
|
|
105
104
|
i++;
|
|
106
105
|
}
|
|
@@ -39,13 +39,11 @@ class DataTypeClass extends document_element_js_1.DocumentElement {
|
|
|
39
39
|
return (0, test_scope_match_js_1.testScopeMatch)(scope, this.scopePattern);
|
|
40
40
|
}
|
|
41
41
|
toJSON(options) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
throw new TypeError(`"${baseName}" model is not available for "${options.scope}" scope`);
|
|
48
|
-
}
|
|
42
|
+
/** Locate base model which is not available for given scope */
|
|
43
|
+
const outOfScope = this._locateBase(dt => !dt.inScope(options?.scope));
|
|
44
|
+
if (outOfScope) {
|
|
45
|
+
const baseName = this.node.getDataTypeNameWithNs(outOfScope);
|
|
46
|
+
throw new TypeError(`"${baseName}" model is not available for "${options?.scope || 'null'}" scope`);
|
|
49
47
|
}
|
|
50
48
|
return (0, objects_1.omitUndefined)({
|
|
51
49
|
kind: this.kind,
|
|
@@ -49,7 +49,7 @@ exports.MappedType = function (...args) {
|
|
|
49
49
|
const required = Array.isArray(_this.required)
|
|
50
50
|
? _this.required.map(x => x.toLowerCase())
|
|
51
51
|
: _this.required;
|
|
52
|
-
for (const [k, v] of _this.base.
|
|
52
|
+
for (const [k, v] of _this.base.fieldEntries()) {
|
|
53
53
|
if (!isInheritedPredicate(k))
|
|
54
54
|
continue;
|
|
55
55
|
const meta = { ...v };
|
|
@@ -62,7 +62,7 @@ exports.MappedType = function (...args) {
|
|
|
62
62
|
meta.required = true;
|
|
63
63
|
}
|
|
64
64
|
const field = new api_field_js_1.ApiField(this, meta);
|
|
65
|
-
_this.
|
|
65
|
+
_this._fields.set(field.name, field);
|
|
66
66
|
}
|
|
67
67
|
if (!_this.pick ||
|
|
68
68
|
_this.base.additionalFields === false ||
|
|
@@ -30,9 +30,9 @@ 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
|
-
_this.
|
|
35
|
+
_this._fields.set(field.name, field);
|
|
36
36
|
}
|
|
37
37
|
_this.types.push(base);
|
|
38
38
|
if (base.keyField)
|
|
@@ -106,6 +106,14 @@ class SimpleTypeClass extends data_type_js_1.DataType {
|
|
|
106
106
|
out.nameMappings = { ...this.ownNameMappings };
|
|
107
107
|
return (0, objects_1.omitUndefined)(out, true);
|
|
108
108
|
}
|
|
109
|
+
_locateBase(callback) {
|
|
110
|
+
if (!this.base)
|
|
111
|
+
return;
|
|
112
|
+
if (callback(this.base))
|
|
113
|
+
return this.base;
|
|
114
|
+
if (this.base._locateBase)
|
|
115
|
+
return this.base._locateBase(callback);
|
|
116
|
+
}
|
|
109
117
|
}
|
|
110
118
|
exports.SimpleType.prototype = SimpleTypeClass.prototype;
|
|
111
119
|
Object.assign(exports.SimpleType, simple_type_decorator_js_1.SimpleTypeDecoratorFactory);
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.testScopeMatch = testScopeMatch;
|
|
4
4
|
function testScopeMatch(scope, pattern) {
|
|
5
|
-
if (!
|
|
5
|
+
if (!pattern)
|
|
6
6
|
return true;
|
|
7
|
+
if (!scope)
|
|
8
|
+
return false;
|
|
7
9
|
if (Array.isArray(pattern)) {
|
|
8
10
|
return pattern.some(x => {
|
|
9
11
|
return typeof x === 'string' ? scope === x : x.test(scope);
|
|
@@ -90,7 +90,7 @@ export class ApiDocument extends DocumentElement {
|
|
|
90
90
|
if (this.types.size) {
|
|
91
91
|
out.types = {};
|
|
92
92
|
for (const v of this.types.values()) {
|
|
93
|
-
if (
|
|
93
|
+
if (!v.inScope(options?.scope))
|
|
94
94
|
continue;
|
|
95
95
|
out.types[v.name] = v.toJSON(options);
|
|
96
96
|
}
|
|
@@ -109,7 +109,7 @@ export class ApiDocument extends DocumentElement {
|
|
|
109
109
|
}
|
|
110
110
|
_findDataType(nameOrCtor, scope, visitedRefs) {
|
|
111
111
|
let result = this.types.get(nameOrCtor);
|
|
112
|
-
if (result &&
|
|
112
|
+
if (result && result.inScope(scope))
|
|
113
113
|
return result;
|
|
114
114
|
if (!this.references.size)
|
|
115
115
|
return;
|
|
@@ -23,7 +23,7 @@ export class DocumentNode {
|
|
|
23
23
|
}
|
|
24
24
|
findDataType(nameOrCtor, scope) {
|
|
25
25
|
const dt = this[kDataTypeMap]?.get(nameOrCtor);
|
|
26
|
-
if (dt &&
|
|
26
|
+
if (dt && dt.inScope(scope))
|
|
27
27
|
return dt;
|
|
28
28
|
return this.parent
|
|
29
29
|
? this.parent.findDataType(nameOrCtor, scope)
|
|
@@ -34,7 +34,7 @@ export class DocumentNode {
|
|
|
34
34
|
*/
|
|
35
35
|
getDataType(nameOrCtor, scope) {
|
|
36
36
|
const dt = this.findDataType(nameOrCtor);
|
|
37
|
-
if (dt &&
|
|
37
|
+
if (dt && dt.inScope(scope))
|
|
38
38
|
return dt;
|
|
39
39
|
let name = '';
|
|
40
40
|
if (typeof nameOrCtor === 'function') {
|
|
@@ -14,12 +14,88 @@ export const ComplexTypeBase = function (...args) {
|
|
|
14
14
|
const [owner, initArgs, context] = args;
|
|
15
15
|
DataType.call(this, owner, initArgs, context);
|
|
16
16
|
const _this = asMutable(this);
|
|
17
|
-
_this.
|
|
17
|
+
_this._fields = new ResponsiveMap();
|
|
18
18
|
};
|
|
19
19
|
/**
|
|
20
20
|
*
|
|
21
21
|
*/
|
|
22
22
|
class ComplexTypeBaseClass extends DataType {
|
|
23
|
+
fieldCount(scope) {
|
|
24
|
+
if (!scope)
|
|
25
|
+
return this._fields.size;
|
|
26
|
+
let count = 0;
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
28
|
+
for (const i of this.fields(scope))
|
|
29
|
+
count++;
|
|
30
|
+
return count;
|
|
31
|
+
}
|
|
32
|
+
fieldEntries(scope) {
|
|
33
|
+
let iterator = this._fields.entries();
|
|
34
|
+
if (!scope)
|
|
35
|
+
return iterator;
|
|
36
|
+
let r;
|
|
37
|
+
return {
|
|
38
|
+
next() {
|
|
39
|
+
while (iterator) {
|
|
40
|
+
r = iterator.next();
|
|
41
|
+
if (r.done)
|
|
42
|
+
break;
|
|
43
|
+
if (r.value && r.value[1].inScope(scope))
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
return r;
|
|
47
|
+
},
|
|
48
|
+
return(value) {
|
|
49
|
+
iterator = undefined;
|
|
50
|
+
return { done: true, value };
|
|
51
|
+
},
|
|
52
|
+
[Symbol.iterator]() {
|
|
53
|
+
return this;
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
fields(scope) {
|
|
58
|
+
if (!scope)
|
|
59
|
+
return this._fields.values();
|
|
60
|
+
let iterator = this.fieldEntries(scope);
|
|
61
|
+
let r;
|
|
62
|
+
return {
|
|
63
|
+
next() {
|
|
64
|
+
if (!iterator)
|
|
65
|
+
return { done: true, value: undefined };
|
|
66
|
+
r = iterator.next();
|
|
67
|
+
return { done: r.done, value: r.value[1] };
|
|
68
|
+
},
|
|
69
|
+
return(value) {
|
|
70
|
+
iterator = undefined;
|
|
71
|
+
return { done: true, value };
|
|
72
|
+
},
|
|
73
|
+
[Symbol.iterator]() {
|
|
74
|
+
return this;
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
fieldNames(scope) {
|
|
79
|
+
if (!scope)
|
|
80
|
+
return this._fields.keys();
|
|
81
|
+
let iterator = this.fieldEntries(scope);
|
|
82
|
+
let r;
|
|
83
|
+
return {
|
|
84
|
+
next() {
|
|
85
|
+
if (!iterator)
|
|
86
|
+
return { done: true, value: undefined };
|
|
87
|
+
r = iterator.next();
|
|
88
|
+
return { done: r.done, value: r.value[0] };
|
|
89
|
+
},
|
|
90
|
+
return(value) {
|
|
91
|
+
iterator = undefined;
|
|
92
|
+
return { done: true, value };
|
|
93
|
+
},
|
|
94
|
+
[Symbol.iterator]() {
|
|
95
|
+
return this;
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
23
99
|
/**
|
|
24
100
|
*
|
|
25
101
|
*/
|
|
@@ -31,18 +107,17 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
31
107
|
const lastItem = fieldPath.pop();
|
|
32
108
|
return lastItem?.field;
|
|
33
109
|
}
|
|
34
|
-
const field = this.
|
|
35
|
-
if (field &&
|
|
36
|
-
return;
|
|
37
|
-
return field;
|
|
110
|
+
const field = this._fields.get(nameOrPath);
|
|
111
|
+
if (field && field.inScope(scope))
|
|
112
|
+
return field;
|
|
38
113
|
}
|
|
39
114
|
/**
|
|
40
115
|
*
|
|
41
116
|
*/
|
|
42
117
|
getField(nameOrPath, scope) {
|
|
43
118
|
const field = this.findField(nameOrPath);
|
|
44
|
-
if (field &&
|
|
45
|
-
throw new Error(`Field "${nameOrPath}" does not exist in scope "${scope}"`);
|
|
119
|
+
if (field && !field.inScope(scope))
|
|
120
|
+
throw new Error(`Field "${nameOrPath}" does not exist in scope "${scope || 'null'}"`);
|
|
46
121
|
if (!field) {
|
|
47
122
|
throw new Error(`Field (${nameOrPath}) does not exist`);
|
|
48
123
|
}
|
|
@@ -155,10 +230,10 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
155
230
|
const pickList = !!(projection && Object.values(projection).find(p => !p.sign));
|
|
156
231
|
// Process fields
|
|
157
232
|
let fieldName;
|
|
158
|
-
for (const field of this.
|
|
233
|
+
for (const field of this._fields.values()) {
|
|
159
234
|
if (
|
|
160
235
|
/** Ignore field if required scope(s) do not match field scopes */
|
|
161
|
-
|
|
236
|
+
!field.inScope(context.scope) ||
|
|
162
237
|
/** Ignore field if readonly and ignoreReadonlyFields option true */
|
|
163
238
|
(context.ignoreReadonlyFields && field.readonly) ||
|
|
164
239
|
/** Ignore field if writeonly and ignoreWriteonlyFields option true */
|
|
@@ -31,8 +31,8 @@ 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
|
|
35
|
-
|
|
34
|
+
for (const v of _this.base.fields()) {
|
|
35
|
+
_this._fields.set(v.name, new ApiField(this, v));
|
|
36
36
|
}
|
|
37
37
|
});
|
|
38
38
|
}
|
|
@@ -49,7 +49,7 @@ export const ComplexType = function (...args) {
|
|
|
49
49
|
...v,
|
|
50
50
|
name: k,
|
|
51
51
|
});
|
|
52
|
-
this.
|
|
52
|
+
this._fields.set(field.name, field);
|
|
53
53
|
}
|
|
54
54
|
});
|
|
55
55
|
}
|
|
@@ -92,12 +92,11 @@ class ComplexTypeClass extends ComplexTypeBase {
|
|
|
92
92
|
else
|
|
93
93
|
out.additionalFields = this.additionalFields;
|
|
94
94
|
}
|
|
95
|
-
if (this.
|
|
95
|
+
if (this._fields.size) {
|
|
96
96
|
const fields = {};
|
|
97
97
|
let i = 0;
|
|
98
|
-
for (const field of this.
|
|
99
|
-
if (field.origin === this &&
|
|
100
|
-
(!options?.scope || field.inScope(options?.scope))) {
|
|
98
|
+
for (const field of this._fields.values()) {
|
|
99
|
+
if (field.origin === this && field.inScope(options?.scope)) {
|
|
101
100
|
fields[field.name] = field.toJSON(options);
|
|
102
101
|
i++;
|
|
103
102
|
}
|
|
@@ -36,13 +36,11 @@ class DataTypeClass extends DocumentElement {
|
|
|
36
36
|
return testScopeMatch(scope, this.scopePattern);
|
|
37
37
|
}
|
|
38
38
|
toJSON(options) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
throw new TypeError(`"${baseName}" model is not available for "${options.scope}" scope`);
|
|
45
|
-
}
|
|
39
|
+
/** Locate base model which is not available for given scope */
|
|
40
|
+
const outOfScope = this._locateBase(dt => !dt.inScope(options?.scope));
|
|
41
|
+
if (outOfScope) {
|
|
42
|
+
const baseName = this.node.getDataTypeNameWithNs(outOfScope);
|
|
43
|
+
throw new TypeError(`"${baseName}" model is not available for "${options?.scope || 'null'}" scope`);
|
|
46
44
|
}
|
|
47
45
|
return omitUndefined({
|
|
48
46
|
kind: this.kind,
|
|
@@ -46,7 +46,7 @@ export const MappedType = function (...args) {
|
|
|
46
46
|
const required = Array.isArray(_this.required)
|
|
47
47
|
? _this.required.map(x => x.toLowerCase())
|
|
48
48
|
: _this.required;
|
|
49
|
-
for (const [k, v] of _this.base.
|
|
49
|
+
for (const [k, v] of _this.base.fieldEntries()) {
|
|
50
50
|
if (!isInheritedPredicate(k))
|
|
51
51
|
continue;
|
|
52
52
|
const meta = { ...v };
|
|
@@ -59,7 +59,7 @@ export const MappedType = function (...args) {
|
|
|
59
59
|
meta.required = true;
|
|
60
60
|
}
|
|
61
61
|
const field = new ApiField(this, meta);
|
|
62
|
-
_this.
|
|
62
|
+
_this._fields.set(field.name, field);
|
|
63
63
|
}
|
|
64
64
|
if (!_this.pick ||
|
|
65
65
|
_this.base.additionalFields === false ||
|
|
@@ -27,9 +27,9 @@ 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
|
-
_this.
|
|
32
|
+
_this._fields.set(field.name, field);
|
|
33
33
|
}
|
|
34
34
|
_this.types.push(base);
|
|
35
35
|
if (base.keyField)
|
|
@@ -103,6 +103,14 @@ class SimpleTypeClass extends DataType {
|
|
|
103
103
|
out.nameMappings = { ...this.ownNameMappings };
|
|
104
104
|
return omitUndefined(out, true);
|
|
105
105
|
}
|
|
106
|
+
_locateBase(callback) {
|
|
107
|
+
if (!this.base)
|
|
108
|
+
return;
|
|
109
|
+
if (callback(this.base))
|
|
110
|
+
return this.base;
|
|
111
|
+
if (this.base._locateBase)
|
|
112
|
+
return this.base._locateBase(callback);
|
|
113
|
+
}
|
|
106
114
|
}
|
|
107
115
|
SimpleType.prototype = SimpleTypeClass.prototype;
|
|
108
116
|
Object.assign(SimpleType, SimpleTypeDecoratorFactory);
|
package/package.json
CHANGED
|
@@ -52,7 +52,7 @@ declare class ApiFieldClass extends DocumentElement {
|
|
|
52
52
|
readonly readonly?: boolean;
|
|
53
53
|
readonly writeonly?: boolean;
|
|
54
54
|
readonly examples?: any[] | Record<string, any>;
|
|
55
|
-
inScope(scope
|
|
55
|
+
inScope(scope?: string): boolean;
|
|
56
56
|
toJSON(options?: ApiDocument.ExportOptions): OpraSchema.Field;
|
|
57
57
|
}
|
|
58
58
|
/**
|
|
@@ -40,9 +40,13 @@ export declare const ComplexTypeBase: ComplexTypeBaseStatic;
|
|
|
40
40
|
*/
|
|
41
41
|
declare abstract class ComplexTypeBaseClass extends DataType {
|
|
42
42
|
readonly ctor?: Type;
|
|
43
|
-
|
|
43
|
+
protected _fields: ResponsiveMap<ApiField>;
|
|
44
44
|
readonly additionalFields?: boolean | DataType | ['error'] | ['error', string];
|
|
45
45
|
readonly keyField?: OpraSchema.Field.Name;
|
|
46
|
+
fieldCount(scope?: string): number;
|
|
47
|
+
fieldEntries(scope?: string): IterableIterator<[string, ApiField]>;
|
|
48
|
+
fields(scope?: string): IterableIterator<ApiField>;
|
|
49
|
+
fieldNames(scope?: string): IterableIterator<string>;
|
|
46
50
|
/**
|
|
47
51
|
*
|
|
48
52
|
*/
|
|
@@ -61,7 +61,7 @@ declare abstract class DataTypeClass extends DocumentElement {
|
|
|
61
61
|
abstract generateCodec(codec: 'encode' | 'decode', options?: DataType.GenerateCodecOptions): Validator;
|
|
62
62
|
get embedded(): any;
|
|
63
63
|
abstract extendsFrom(baseType: DataType | string | Type | object): boolean;
|
|
64
|
-
inScope(scope
|
|
64
|
+
inScope(scope?: string): boolean;
|
|
65
65
|
toJSON(options?: ApiDocument.ExportOptions): OpraSchema.DataType;
|
|
66
66
|
toString(): string;
|
|
67
67
|
protected abstract _locateBase(callback: (base: DataType) => boolean): DataType | undefined;
|
|
@@ -74,5 +74,6 @@ declare abstract class SimpleTypeClass extends DataType {
|
|
|
74
74
|
extendsFrom(baseType: DataType | string | Type | object): boolean;
|
|
75
75
|
generateCodec<T extends Record<string, any> | object = object>(codec: 'encode' | 'decode', options?: DataType.GenerateCodecOptions | null, properties?: Partial<T>): Validator;
|
|
76
76
|
toJSON(options?: ApiDocument.ExportOptions): OpraSchema.SimpleType;
|
|
77
|
+
protected _locateBase(callback: (base: SimpleType) => boolean): SimpleType | undefined;
|
|
77
78
|
}
|
|
78
79
|
export {};
|
|
@@ -10,7 +10,6 @@ export declare namespace ApiDocumentFactory {
|
|
|
10
10
|
references?: Record<string, ReferenceThunk>;
|
|
11
11
|
types?: DataTypeInitSources;
|
|
12
12
|
api?: StrictOmit<HttpApiFactory.InitArguments, 'owner'> | StrictOmit<RpcApiFactory.InitArguments, 'owner'>;
|
|
13
|
-
scopes?: string | string[];
|
|
14
13
|
}
|
|
15
14
|
type ReferenceSource = string | OpraSchema.ApiDocument | InitArguments | ApiDocument;
|
|
16
15
|
type ReferenceThunk = ThunkAsync<ReferenceSource>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function testScopeMatch(scope
|
|
1
|
+
export declare function testScopeMatch(scope?: string, pattern?: (string | RegExp) | (string | RegExp)[]): boolean;
|