@opra/common 1.4.4 → 1.5.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/index.cjs +5 -5
- package/browser/index.mjs +5 -5
- package/cjs/document/api-document.js +13 -8
- package/cjs/document/common/api-base.js +2 -1
- package/cjs/document/common/document-init-context.js +5 -0
- package/cjs/document/common/document-node.js +25 -29
- package/cjs/document/common/value.js +6 -2
- package/cjs/document/constants.js +1 -2
- package/cjs/document/data-type/api-field.js +16 -3
- package/cjs/document/data-type/complex-type-base.js +12 -3
- package/cjs/document/data-type/complex-type.js +12 -5
- package/cjs/document/data-type/data-type.js +16 -1
- package/cjs/document/data-type/enum-type.js +9 -2
- package/cjs/document/data-type/extended-types/base64.type.js +1 -0
- package/cjs/document/data-type/extended-types/date-string.type.js +1 -0
- package/cjs/document/data-type/extended-types/date-time-string.type.js +1 -0
- package/cjs/document/data-type/extended-types/date-time.type.js +1 -0
- package/cjs/document/data-type/extended-types/date.type.js +1 -0
- package/cjs/document/data-type/extended-types/email.type.js +1 -0
- package/cjs/document/data-type/extended-types/field-path.type.js +6 -2
- package/cjs/document/data-type/extended-types/filter.type.js +11 -4
- package/cjs/document/data-type/extended-types/object-id.type.js +1 -0
- package/cjs/document/data-type/extended-types/operation-result.type.js +1 -0
- package/cjs/document/data-type/extended-types/time.type.js +1 -0
- package/cjs/document/data-type/extended-types/url.type.js +1 -0
- package/cjs/document/data-type/extended-types/uuid.type.js +1 -0
- package/cjs/document/data-type/mapped-type.js +6 -3
- package/cjs/document/data-type/mixin-type.js +7 -4
- package/cjs/document/data-type/primitive-types/any.type.js +1 -0
- package/cjs/document/data-type/primitive-types/bigint.type.js +1 -0
- package/cjs/document/data-type/primitive-types/boolean.type.js +1 -0
- package/cjs/document/data-type/primitive-types/integer.type.js +1 -0
- package/cjs/document/data-type/primitive-types/null.type.js +1 -0
- package/cjs/document/data-type/primitive-types/number.type.js +1 -0
- package/cjs/document/data-type/primitive-types/string.type.js +1 -0
- package/cjs/document/data-type/simple-type.js +10 -3
- package/cjs/document/decorators/complex-type.decorator.js +1 -1
- package/cjs/document/decorators/simple-type.decorator.js +1 -1
- package/cjs/document/factory/api-document.factory.js +1 -0
- package/cjs/document/http/http-api.js +2 -2
- package/cjs/document/http/http-controller.js +5 -5
- package/cjs/document/http/http-media-type.js +3 -3
- package/cjs/document/http/http-multipart-field.js +2 -2
- package/cjs/document/http/http-operation-response.js +3 -3
- package/cjs/document/http/http-operation.js +5 -5
- package/cjs/document/http/http-parameter.js +2 -2
- package/cjs/document/http/http-request-body.js +4 -2
- package/cjs/filter/filter-rules.js +5 -4
- package/esm/document/api-document.js +13 -8
- package/esm/document/common/api-base.js +2 -1
- package/esm/document/common/document-init-context.js +5 -0
- package/esm/document/common/document-node.js +25 -29
- package/esm/document/common/value.js +6 -2
- package/esm/document/constants.js +0 -1
- package/esm/document/data-type/api-field.js +16 -3
- package/esm/document/data-type/complex-type-base.js +12 -3
- package/esm/document/data-type/complex-type.js +12 -5
- package/esm/document/data-type/data-type.js +16 -1
- package/esm/document/data-type/enum-type.js +9 -2
- package/esm/document/data-type/extended-types/base64.type.js +1 -0
- package/esm/document/data-type/extended-types/date-string.type.js +1 -0
- package/esm/document/data-type/extended-types/date-time-string.type.js +1 -0
- package/esm/document/data-type/extended-types/date-time.type.js +1 -0
- package/esm/document/data-type/extended-types/date.type.js +1 -0
- package/esm/document/data-type/extended-types/email.type.js +1 -0
- package/esm/document/data-type/extended-types/field-path.type.js +6 -2
- package/esm/document/data-type/extended-types/filter.type.js +11 -4
- package/esm/document/data-type/extended-types/object-id.type.js +1 -0
- package/esm/document/data-type/extended-types/operation-result.type.js +1 -0
- package/esm/document/data-type/extended-types/time.type.js +1 -0
- package/esm/document/data-type/extended-types/url.type.js +1 -0
- package/esm/document/data-type/extended-types/uuid.type.js +1 -0
- package/esm/document/data-type/mapped-type.js +6 -3
- package/esm/document/data-type/mixin-type.js +7 -4
- package/esm/document/data-type/primitive-types/any.type.js +1 -0
- package/esm/document/data-type/primitive-types/bigint.type.js +1 -0
- package/esm/document/data-type/primitive-types/boolean.type.js +1 -0
- package/esm/document/data-type/primitive-types/integer.type.js +1 -0
- package/esm/document/data-type/primitive-types/null.type.js +1 -0
- package/esm/document/data-type/primitive-types/number.type.js +1 -0
- package/esm/document/data-type/primitive-types/string.type.js +1 -0
- package/esm/document/data-type/simple-type.js +10 -3
- package/esm/document/decorators/complex-type.decorator.js +2 -2
- package/esm/document/decorators/simple-type.decorator.js +2 -2
- package/esm/document/factory/api-document.factory.js +1 -0
- package/esm/document/http/http-api.js +2 -2
- package/esm/document/http/http-controller.js +5 -5
- package/esm/document/http/http-media-type.js +3 -3
- package/esm/document/http/http-multipart-field.js +2 -2
- package/esm/document/http/http-operation-response.js +3 -3
- package/esm/document/http/http-operation.js +5 -5
- package/esm/document/http/http-parameter.js +2 -2
- package/esm/document/http/http-request-body.js +4 -2
- package/esm/filter/filter-rules.js +5 -4
- package/package.json +1 -1
- package/types/document/api-document.d.ts +8 -2
- package/types/document/common/api-base.d.ts +1 -1
- package/types/document/common/document-init-context.d.ts +2 -0
- package/types/document/common/document-node.d.ts +8 -14
- package/types/document/common/value.d.ts +2 -1
- package/types/document/constants.d.ts +0 -1
- package/types/document/data-type/api-field.d.ts +6 -11
- package/types/document/data-type/complex-type.d.ts +2 -1
- package/types/document/data-type/data-type.d.ts +7 -2
- package/types/document/data-type/enum-type.d.ts +2 -1
- package/types/document/data-type/extended-types/field-path.type.d.ts +2 -1
- package/types/document/data-type/extended-types/filter.type.d.ts +2 -1
- package/types/document/data-type/mapped-type.d.ts +2 -1
- package/types/document/data-type/mixin-type.d.ts +2 -1
- package/types/document/data-type/simple-type.d.ts +2 -1
- package/types/document/factory/api-document.factory.d.ts +2 -1
- package/types/document/http/http-api.d.ts +1 -1
- package/types/document/http/http-controller.d.ts +2 -1
- package/types/document/http/http-media-type.d.ts +2 -1
- package/types/document/http/http-multipart-field.d.ts +2 -1
- package/types/document/http/http-operation-response.d.ts +2 -1
- package/types/document/http/http-operation.d.ts +2 -1
- package/types/document/http/http-parameter.d.ts +2 -1
- package/types/document/http/http-request-body.d.ts +2 -1
- package/types/filter/filter-rules.d.ts +3 -3
|
@@ -20,6 +20,7 @@ let BooleanType = class BooleanType {
|
|
|
20
20
|
exports.BooleanType = BooleanType;
|
|
21
21
|
exports.BooleanType = BooleanType = tslib_1.__decorate([
|
|
22
22
|
(0, simple_type_js_1.SimpleType)({
|
|
23
|
+
name: 'boolean',
|
|
23
24
|
description: 'Simple true/false value',
|
|
24
25
|
nameMappings: {
|
|
25
26
|
js: 'boolean',
|
|
@@ -27,6 +27,7 @@ let IntegerType = class IntegerType extends number_type_js_1.NumberType {
|
|
|
27
27
|
exports.IntegerType = IntegerType;
|
|
28
28
|
exports.IntegerType = IntegerType = tslib_1.__decorate([
|
|
29
29
|
(0, simple_type_js_1.SimpleType)({
|
|
30
|
+
name: 'integer',
|
|
30
31
|
description: 'An integer number',
|
|
31
32
|
nameMappings: {
|
|
32
33
|
js: 'number',
|
|
@@ -39,6 +39,7 @@ tslib_1.__decorate([
|
|
|
39
39
|
], NumberType.prototype, "maxValue", void 0);
|
|
40
40
|
exports.NumberType = NumberType = tslib_1.__decorate([
|
|
41
41
|
(0, simple_type_js_1.SimpleType)({
|
|
42
|
+
name: 'number',
|
|
42
43
|
description: 'Both Integer as well as Floating-Point numbers',
|
|
43
44
|
nameMappings: {
|
|
44
45
|
js: 'number',
|
|
@@ -59,6 +59,7 @@ tslib_1.__decorate([
|
|
|
59
59
|
], StringType.prototype, "maxLength", void 0);
|
|
60
60
|
exports.StringType = StringType = tslib_1.__decorate([
|
|
61
61
|
(0, simple_type_js_1.SimpleType)({
|
|
62
|
+
name: 'string',
|
|
62
63
|
description: 'A sequence of characters',
|
|
63
64
|
nameMappings: {
|
|
64
65
|
js: 'string',
|
|
@@ -83,20 +83,27 @@ class SimpleTypeClass extends data_type_js_1.DataType {
|
|
|
83
83
|
}
|
|
84
84
|
return valgen_1.isAny;
|
|
85
85
|
}
|
|
86
|
-
toJSON() {
|
|
86
|
+
toJSON(options) {
|
|
87
87
|
const attributes = (0, objects_1.omitUndefined)(this.ownAttributes);
|
|
88
88
|
let properties;
|
|
89
89
|
if (this.properties && typeof this.properties.toJSON === 'function') {
|
|
90
|
-
properties = this.properties.toJSON(this.properties, this.owner);
|
|
90
|
+
properties = this.properties.toJSON(this.properties, this.owner, options);
|
|
91
91
|
}
|
|
92
92
|
else
|
|
93
93
|
properties = this.properties ? (0, index_js_1.cloneObject)(this.properties) : {};
|
|
94
94
|
const baseName = this.base
|
|
95
95
|
? this.node.getDataTypeNameWithNs(this.base)
|
|
96
96
|
: undefined;
|
|
97
|
+
if (options?.scopes && !this.base?.inScope(options?.scopes))
|
|
98
|
+
throw new TypeError(`Base type ${baseName ? '(' + baseName + ')' : ''} of ${this.name ? +this.name : 'embedded'} type ` +
|
|
99
|
+
`is not in required scope(s) [${options.scopes}`);
|
|
97
100
|
const out = (0, objects_1.omitUndefined)({
|
|
98
101
|
...data_type_js_1.DataType.prototype.toJSON.apply(this),
|
|
99
|
-
base: this.base
|
|
102
|
+
base: this.base
|
|
103
|
+
? baseName
|
|
104
|
+
? baseName
|
|
105
|
+
: this.base.toJSON(options)
|
|
106
|
+
: undefined,
|
|
100
107
|
attributes: attributes && Object.keys(attributes).length ? attributes : undefined,
|
|
101
108
|
properties: Object.keys(properties).length ? properties : undefined,
|
|
102
109
|
});
|
|
@@ -14,7 +14,7 @@ function ComplexTypeDecorator(options) {
|
|
|
14
14
|
name = options.name;
|
|
15
15
|
}
|
|
16
16
|
else {
|
|
17
|
-
name = target.name
|
|
17
|
+
name = target.name;
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
let metadata = Reflect.getOwnMetadata(constants_js_1.DATATYPE_METADATA, target);
|
|
@@ -30,6 +30,7 @@ class ApiDocumentFactory {
|
|
|
30
30
|
: new document_init_context_js_1.DocumentInitContext(options);
|
|
31
31
|
try {
|
|
32
32
|
const document = new api_document_js_1.ApiDocument();
|
|
33
|
+
document.scopes = context.scopes;
|
|
33
34
|
await factory.initDocument(document, context, schemaOrUrl);
|
|
34
35
|
if (context.error.details.length)
|
|
35
36
|
throw context.error;
|
|
@@ -23,7 +23,7 @@ class HttpApi extends api_base_js_1.ApiBase {
|
|
|
23
23
|
const controller = this.findController(arg0);
|
|
24
24
|
return controller?.operations.get(operationName);
|
|
25
25
|
}
|
|
26
|
-
toJSON() {
|
|
26
|
+
toJSON(options) {
|
|
27
27
|
const schema = super.toJSON();
|
|
28
28
|
const out = {
|
|
29
29
|
...schema,
|
|
@@ -32,7 +32,7 @@ class HttpApi extends api_base_js_1.ApiBase {
|
|
|
32
32
|
controllers: {},
|
|
33
33
|
};
|
|
34
34
|
for (const v of this.controllers.values()) {
|
|
35
|
-
out.controllers[v.name] = v.toJSON();
|
|
35
|
+
out.controllers[v.name] = v.toJSON(options);
|
|
36
36
|
}
|
|
37
37
|
return out;
|
|
38
38
|
}
|
|
@@ -115,7 +115,7 @@ class HttpControllerClass extends document_element_js_1.DocumentElement {
|
|
|
115
115
|
/**
|
|
116
116
|
*
|
|
117
117
|
*/
|
|
118
|
-
toJSON() {
|
|
118
|
+
toJSON(options) {
|
|
119
119
|
const out = (0, objects_1.omitUndefined)({
|
|
120
120
|
kind: this.kind,
|
|
121
121
|
description: this.description,
|
|
@@ -124,25 +124,25 @@ class HttpControllerClass extends document_element_js_1.DocumentElement {
|
|
|
124
124
|
if (this.operations.size) {
|
|
125
125
|
out.operations = {};
|
|
126
126
|
for (const v of this.operations.values()) {
|
|
127
|
-
out.operations[v.name] = v.toJSON();
|
|
127
|
+
out.operations[v.name] = v.toJSON(options);
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
if (this.controllers.size) {
|
|
131
131
|
out.controllers = {};
|
|
132
132
|
for (const v of this.controllers.values()) {
|
|
133
|
-
out.controllers[v.name] = v.toJSON();
|
|
133
|
+
out.controllers[v.name] = v.toJSON(options);
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
if (this.types.size) {
|
|
137
137
|
out.types = {};
|
|
138
138
|
for (const v of this.types.values()) {
|
|
139
|
-
out.types[v.name] = v.toJSON();
|
|
139
|
+
out.types[v.name] = v.toJSON(options);
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
if (this.parameters.length) {
|
|
143
143
|
out.parameters = [];
|
|
144
144
|
for (const prm of this.parameters) {
|
|
145
|
-
out.parameters.push(prm.toJSON());
|
|
145
|
+
out.parameters.push(prm.toJSON(options));
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
return out;
|
|
@@ -52,7 +52,7 @@ class HttpMediaTypeClass extends document_element_js_1.DocumentElement {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
-
toJSON() {
|
|
55
|
+
toJSON(options) {
|
|
56
56
|
const typeName = this.type
|
|
57
57
|
? this.node.getDataTypeNameWithNs(this.type)
|
|
58
58
|
: undefined;
|
|
@@ -60,7 +60,7 @@ class HttpMediaTypeClass extends document_element_js_1.DocumentElement {
|
|
|
60
60
|
description: this.description,
|
|
61
61
|
contentType: this.contentType,
|
|
62
62
|
contentEncoding: this.contentEncoding,
|
|
63
|
-
type: typeName ? typeName : this.type?.toJSON(),
|
|
63
|
+
type: typeName ? typeName : this.type?.toJSON(options),
|
|
64
64
|
isArray: this.isArray,
|
|
65
65
|
example: this.example,
|
|
66
66
|
examples: this.examples,
|
|
@@ -71,7 +71,7 @@ class HttpMediaTypeClass extends document_element_js_1.DocumentElement {
|
|
|
71
71
|
maxTotalFileSize: this.maxTotalFileSize,
|
|
72
72
|
});
|
|
73
73
|
if (this.multipartFields?.length) {
|
|
74
|
-
out.multipartFields = this.multipartFields.map(x => x.toJSON());
|
|
74
|
+
out.multipartFields = this.multipartFields.map(x => x.toJSON(options));
|
|
75
75
|
}
|
|
76
76
|
return out;
|
|
77
77
|
}
|
|
@@ -20,12 +20,12 @@ class HttpMultipartField extends http_media_type_js_1.HttpMediaType {
|
|
|
20
20
|
this.fieldType = initArgs.fieldType;
|
|
21
21
|
this.required = initArgs.required;
|
|
22
22
|
}
|
|
23
|
-
toJSON() {
|
|
23
|
+
toJSON(options) {
|
|
24
24
|
return (0, objects_1.omitUndefined)({
|
|
25
25
|
fieldName: this.fieldName,
|
|
26
26
|
fieldType: this.fieldType,
|
|
27
27
|
required: this.required,
|
|
28
|
-
...super.toJSON(),
|
|
28
|
+
...super.toJSON(options),
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
31
|
}
|
|
@@ -26,10 +26,10 @@ class HttpOperationResponse extends http_media_type_js_1.HttpMediaType {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
toJSON() {
|
|
29
|
+
toJSON(options) {
|
|
30
30
|
const statusCode = this.statusCode.map(x => x.toJSON());
|
|
31
31
|
const out = (0, objects_1.omitUndefined)({
|
|
32
|
-
...super.toJSON(),
|
|
32
|
+
...super.toJSON(options),
|
|
33
33
|
statusCode: statusCode.length === 1 && typeof statusCode[0] === 'number'
|
|
34
34
|
? statusCode[0]
|
|
35
35
|
: statusCode,
|
|
@@ -38,7 +38,7 @@ class HttpOperationResponse extends http_media_type_js_1.HttpMediaType {
|
|
|
38
38
|
if (this.parameters.length) {
|
|
39
39
|
out.parameters = [];
|
|
40
40
|
for (const prm of this.parameters) {
|
|
41
|
-
out.parameters.push(prm.toJSON());
|
|
41
|
+
out.parameters.push(prm.toJSON(options));
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
return out;
|
|
@@ -71,7 +71,7 @@ class HttpOperationClass extends document_element_js_1.DocumentElement {
|
|
|
71
71
|
}
|
|
72
72
|
return this.path || '/';
|
|
73
73
|
}
|
|
74
|
-
toJSON() {
|
|
74
|
+
toJSON(options) {
|
|
75
75
|
const out = (0, objects_1.omitUndefined)({
|
|
76
76
|
kind: index_js_2.OpraSchema.HttpOperation.Kind,
|
|
77
77
|
description: this.description,
|
|
@@ -79,22 +79,22 @@ class HttpOperationClass extends document_element_js_1.DocumentElement {
|
|
|
79
79
|
path: this.path,
|
|
80
80
|
mergePath: this.mergePath,
|
|
81
81
|
composition: this.composition,
|
|
82
|
-
requestBody: this.requestBody?.toJSON(),
|
|
82
|
+
requestBody: this.requestBody?.toJSON(options),
|
|
83
83
|
});
|
|
84
84
|
if (this.types.size) {
|
|
85
85
|
out.types = {};
|
|
86
86
|
for (const v of this.types.values()) {
|
|
87
|
-
out.types[v.name] = v.toJSON();
|
|
87
|
+
out.types[v.name] = v.toJSON(options);
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
if (this.parameters.length) {
|
|
91
91
|
out.parameters = [];
|
|
92
92
|
for (const prm of this.parameters) {
|
|
93
|
-
out.parameters.push(prm.toJSON());
|
|
93
|
+
out.parameters.push(prm.toJSON(options));
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
if (this.responses.length)
|
|
97
|
-
out.responses = this.responses.map(r => r.toJSON());
|
|
97
|
+
out.responses = this.responses.map(r => r.toJSON(options));
|
|
98
98
|
return out;
|
|
99
99
|
}
|
|
100
100
|
}
|
|
@@ -33,9 +33,9 @@ exports.HttpParameter = function (owner, initArgs) {
|
|
|
33
33
|
* @class HttpParameter
|
|
34
34
|
*/
|
|
35
35
|
class HttpParameterClass extends value_js_1.Value {
|
|
36
|
-
toJSON() {
|
|
36
|
+
toJSON(options) {
|
|
37
37
|
return (0, objects_1.omitUndefined)({
|
|
38
|
-
...super.toJSON(),
|
|
38
|
+
...super.toJSON(options),
|
|
39
39
|
name: this.name,
|
|
40
40
|
location: this.location,
|
|
41
41
|
arraySeparator: this.arraySeparator,
|
|
@@ -11,12 +11,14 @@ class HttpRequestBody extends document_element_js_1.DocumentElement {
|
|
|
11
11
|
super(owner);
|
|
12
12
|
this.content = [];
|
|
13
13
|
}
|
|
14
|
-
toJSON() {
|
|
14
|
+
toJSON(options) {
|
|
15
15
|
return (0, objects_1.omitUndefined)({
|
|
16
16
|
description: this.description,
|
|
17
17
|
required: this.required,
|
|
18
18
|
maxContentSize: this.maxContentSize,
|
|
19
|
-
content: this.content.length
|
|
19
|
+
content: this.content.length
|
|
20
|
+
? this.content.map(x => x.toJSON(options))
|
|
21
|
+
: [],
|
|
20
22
|
partial: this.partial,
|
|
21
23
|
allowPatchOperators: this.allowPatchOperators,
|
|
22
24
|
});
|
|
@@ -32,11 +32,12 @@ class FilterRules {
|
|
|
32
32
|
operators,
|
|
33
33
|
}));
|
|
34
34
|
}
|
|
35
|
-
normalizeFilter(filter, currentType) {
|
|
35
|
+
normalizeFilter(filter, currentType, element) {
|
|
36
36
|
const ast = typeof filter === 'string' ? (0, parse_js_1.parse)(filter) : filter;
|
|
37
|
-
|
|
37
|
+
const doc = element?.node.getDocument();
|
|
38
|
+
return this.normalizeFilterAst(ast, [], currentType, doc?.scopes);
|
|
38
39
|
}
|
|
39
|
-
normalizeFilterAst(ast, stack, currentType) {
|
|
40
|
+
normalizeFilterAst(ast, stack, currentType, scopes) {
|
|
40
41
|
if (ast instanceof index_js_4.ComparisonExpression) {
|
|
41
42
|
stack.push(ast);
|
|
42
43
|
this.normalizeFilterAst(ast.left, stack, currentType);
|
|
@@ -128,9 +129,9 @@ class FilterRules {
|
|
|
128
129
|
decoder = this._decoderCache.get(comp.left.field);
|
|
129
130
|
if (!decoder) {
|
|
130
131
|
decoder = comp.left.field.type.generateCodec('decode', {
|
|
132
|
+
scope: scopes,
|
|
131
133
|
projection: '*',
|
|
132
134
|
ignoreWriteonlyFields: true,
|
|
133
|
-
ignoreHiddenFields: true,
|
|
134
135
|
coerce: true,
|
|
135
136
|
});
|
|
136
137
|
this._decoderCache.set(comp.left.field, decoder);
|
|
@@ -64,13 +64,14 @@ export class ApiDocument extends DocumentElement {
|
|
|
64
64
|
/**
|
|
65
65
|
* Export as Opra schema definition object
|
|
66
66
|
*/
|
|
67
|
-
export() {
|
|
67
|
+
export(options) {
|
|
68
68
|
const out = omitUndefined({
|
|
69
69
|
spec: OpraSchema.SpecVersion,
|
|
70
70
|
id: this.id,
|
|
71
71
|
url: this.url,
|
|
72
72
|
info: cloneObject(this.info, true),
|
|
73
73
|
});
|
|
74
|
+
options = options || { scopes: this.scopes };
|
|
74
75
|
if (this.references.size) {
|
|
75
76
|
let i = 0;
|
|
76
77
|
const references = {};
|
|
@@ -90,25 +91,29 @@ export class ApiDocument extends DocumentElement {
|
|
|
90
91
|
if (this.types.size) {
|
|
91
92
|
out.types = {};
|
|
92
93
|
for (const v of this.types.values()) {
|
|
93
|
-
|
|
94
|
+
if (!v.inScope(options.scopes))
|
|
95
|
+
continue;
|
|
96
|
+
out.types[v.name] = v.toJSON(options);
|
|
94
97
|
}
|
|
95
98
|
}
|
|
96
99
|
if (this.api)
|
|
97
|
-
out.api = this.api.toJSON();
|
|
100
|
+
out.api = this.api.toJSON(options);
|
|
98
101
|
return out;
|
|
99
102
|
}
|
|
100
103
|
invalidate() {
|
|
101
104
|
/** Generate id */
|
|
102
|
-
const x = this.export();
|
|
105
|
+
const x = this.export({});
|
|
103
106
|
delete x.id;
|
|
104
107
|
this.id = md5(JSON.stringify(x));
|
|
105
108
|
/** Clear [kTypeNSMap] */
|
|
106
109
|
this[kTypeNSMap] = new WeakMap();
|
|
107
110
|
}
|
|
108
|
-
_findDataType(nameOrCtor, visitedRefs) {
|
|
111
|
+
_findDataType(nameOrCtor, scope, visitedRefs) {
|
|
109
112
|
let result = this.types.get(nameOrCtor);
|
|
110
|
-
if (result
|
|
113
|
+
if (result && result.inScope(scope))
|
|
111
114
|
return result;
|
|
115
|
+
if (!this.references.size)
|
|
116
|
+
return;
|
|
112
117
|
// Lookup for references
|
|
113
118
|
if (typeof nameOrCtor === 'string') {
|
|
114
119
|
// If given string has namespace pattern (ns:type_name)
|
|
@@ -122,7 +127,7 @@ export class ApiDocument extends DocumentElement {
|
|
|
122
127
|
visitedRefs = visitedRefs || new WeakMap();
|
|
123
128
|
visitedRefs.set(this, true);
|
|
124
129
|
visitedRefs.set(ref, true);
|
|
125
|
-
return ref._findDataType(m[2], visitedRefs);
|
|
130
|
+
return ref._findDataType(m[2], scope, visitedRefs);
|
|
126
131
|
}
|
|
127
132
|
nameOrCtor = m[2];
|
|
128
133
|
}
|
|
@@ -144,7 +149,7 @@ export class ApiDocument extends DocumentElement {
|
|
|
144
149
|
for (const refNs of references) {
|
|
145
150
|
const ref = this.references.get(refNs);
|
|
146
151
|
visitedRefs.set(ref, true);
|
|
147
|
-
result = ref._findDataType(nameOrCtor, visitedRefs);
|
|
152
|
+
result = ref._findDataType(nameOrCtor, scope, visitedRefs);
|
|
148
153
|
if (result) {
|
|
149
154
|
this[kTypeNSMap].set(result, ref?.[BUILTIN] ? '' : refNs);
|
|
150
155
|
return result;
|
|
@@ -8,7 +8,8 @@ export class ApiBase extends DocumentElement {
|
|
|
8
8
|
this.name = init.name;
|
|
9
9
|
this.description = init.description;
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
12
|
+
toJSON(options) {
|
|
12
13
|
return omitUndefined({
|
|
13
14
|
transport: this.transport,
|
|
14
15
|
name: this.name,
|
|
@@ -6,6 +6,11 @@ export class DocumentInitContext {
|
|
|
6
6
|
this.showErrorDetails = true;
|
|
7
7
|
this.maxErrors = options?.maxErrors || 0;
|
|
8
8
|
this.error.message = '';
|
|
9
|
+
this.scopes = options?.scopes
|
|
10
|
+
? Array.isArray(options.scopes)
|
|
11
|
+
? options?.scopes
|
|
12
|
+
: [options?.scopes]
|
|
13
|
+
: undefined;
|
|
9
14
|
}
|
|
10
15
|
addError(error) {
|
|
11
16
|
if (!this.error.details.length) {
|
|
@@ -18,25 +18,24 @@ export class DocumentNode {
|
|
|
18
18
|
// istanbul ignore next
|
|
19
19
|
throw new Error('ApiDocument not found in document tree');
|
|
20
20
|
}
|
|
21
|
-
hasDataType(nameOrCtor) {
|
|
22
|
-
|
|
23
|
-
if (result)
|
|
24
|
-
return result;
|
|
25
|
-
return this.parent ? this.parent.hasDataType(nameOrCtor) : false;
|
|
21
|
+
hasDataType(nameOrCtor, scope) {
|
|
22
|
+
return !!this.findDataType(nameOrCtor, scope);
|
|
26
23
|
}
|
|
27
|
-
findDataType(nameOrCtor) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
findDataType(nameOrCtor, scope) {
|
|
25
|
+
scope = scope || this.getDocument().scopes;
|
|
26
|
+
const dt = this[kDataTypeMap]?.get(nameOrCtor);
|
|
27
|
+
if (dt && dt.inScope(scope))
|
|
28
|
+
return dt;
|
|
29
|
+
return this.parent
|
|
30
|
+
? this.parent.findDataType(nameOrCtor, scope)
|
|
31
|
+
: undefined;
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
34
|
* Returns DataType instance by name or Constructor. Returns undefined if not found
|
|
35
|
-
* @param nameOrCtor
|
|
36
35
|
*/
|
|
37
|
-
getDataType(nameOrCtor) {
|
|
36
|
+
getDataType(nameOrCtor, scope) {
|
|
38
37
|
const dt = this.findDataType(nameOrCtor);
|
|
39
|
-
if (dt)
|
|
38
|
+
if (dt && dt.inScope(scope))
|
|
40
39
|
return dt;
|
|
41
40
|
let name = '';
|
|
42
41
|
if (typeof nameOrCtor === 'function') {
|
|
@@ -53,7 +52,9 @@ export class DocumentNode {
|
|
|
53
52
|
else if (typeof nameOrCtor === 'function')
|
|
54
53
|
name = nameOrCtor.name;
|
|
55
54
|
}
|
|
56
|
-
|
|
55
|
+
if (dt)
|
|
56
|
+
throw new TypeError(`Data type${name ? ' (' + name + ')' : ''} is not in requested scope (${scope})`);
|
|
57
|
+
throw new TypeError(`Unknown data type${name ? ' (' + name + ')' : ''}`);
|
|
57
58
|
}
|
|
58
59
|
getDataTypeNameWithNs(dataType) {
|
|
59
60
|
if (!dataType.name)
|
|
@@ -65,10 +66,9 @@ export class DocumentNode {
|
|
|
65
66
|
* Returns ComplexType instance by name or Constructor.
|
|
66
67
|
* Returns undefined if not found
|
|
67
68
|
* Throws error if data type is not a ComplexType
|
|
68
|
-
* @param nameOrCtor
|
|
69
69
|
*/
|
|
70
|
-
getComplexType(nameOrCtor) {
|
|
71
|
-
const t = this.getDataType(nameOrCtor);
|
|
70
|
+
getComplexType(nameOrCtor, scope) {
|
|
71
|
+
const t = this.getDataType(nameOrCtor, scope);
|
|
72
72
|
if (t.kind === OpraSchema.ComplexType.Kind)
|
|
73
73
|
return t;
|
|
74
74
|
throw new TypeError(`Data type "${t.name}" is not a ComplexType`);
|
|
@@ -77,10 +77,9 @@ export class DocumentNode {
|
|
|
77
77
|
* Returns SimpleType instance by name or Constructor.
|
|
78
78
|
* Returns undefined if not found
|
|
79
79
|
* Throws error if data type is not a SimpleType
|
|
80
|
-
* @param nameOrCtor
|
|
81
80
|
*/
|
|
82
|
-
getSimpleType(nameOrCtor) {
|
|
83
|
-
const t = this.getDataType(nameOrCtor);
|
|
81
|
+
getSimpleType(nameOrCtor, scope) {
|
|
82
|
+
const t = this.getDataType(nameOrCtor, scope);
|
|
84
83
|
if (t.kind === OpraSchema.SimpleType.Kind)
|
|
85
84
|
return t;
|
|
86
85
|
throw new TypeError(`Data type "${t.name || t}" is not a SimpleType`);
|
|
@@ -89,10 +88,9 @@ export class DocumentNode {
|
|
|
89
88
|
* Returns EnumType instance by name or Constructor.
|
|
90
89
|
* Returns undefined if not found
|
|
91
90
|
* Throws error if data type is not a EnumType
|
|
92
|
-
* @param nameOrCtor
|
|
93
91
|
*/
|
|
94
|
-
getEnumType(nameOrCtor) {
|
|
95
|
-
const t = this.getDataType(nameOrCtor);
|
|
92
|
+
getEnumType(nameOrCtor, scope) {
|
|
93
|
+
const t = this.getDataType(nameOrCtor, scope);
|
|
96
94
|
if (t.kind === OpraSchema.EnumType.Kind)
|
|
97
95
|
return t;
|
|
98
96
|
throw new TypeError(`Data type "${t.name || t}" is not a EnumType`);
|
|
@@ -101,10 +99,9 @@ export class DocumentNode {
|
|
|
101
99
|
* Returns EnumType instance by name or Constructor.
|
|
102
100
|
* Returns undefined if not found
|
|
103
101
|
* Throws error if data type is not a MappedType
|
|
104
|
-
* @param nameOrCtor
|
|
105
102
|
*/
|
|
106
|
-
getMappedType(nameOrCtor) {
|
|
107
|
-
const t = this.getDataType(nameOrCtor);
|
|
103
|
+
getMappedType(nameOrCtor, scope) {
|
|
104
|
+
const t = this.getDataType(nameOrCtor, scope);
|
|
108
105
|
if (t.kind === OpraSchema.MappedType.Kind)
|
|
109
106
|
return t;
|
|
110
107
|
throw new TypeError(`Data type "${t.name || t}" is not a MappedType`);
|
|
@@ -113,10 +110,9 @@ export class DocumentNode {
|
|
|
113
110
|
* Returns EnumType instance by name or Constructor.
|
|
114
111
|
* Returns undefined if not found
|
|
115
112
|
* Throws error if data type is not a MixinType
|
|
116
|
-
* @param nameOrCtor
|
|
117
113
|
*/
|
|
118
|
-
getMixinType(nameOrCtor) {
|
|
119
|
-
const t = this.getDataType(nameOrCtor);
|
|
114
|
+
getMixinType(nameOrCtor, scope) {
|
|
115
|
+
const t = this.getDataType(nameOrCtor, scope);
|
|
120
116
|
if (t.kind === OpraSchema.MixinType.Kind)
|
|
121
117
|
return t;
|
|
122
118
|
throw new TypeError(`Data type "${t.name || t}" is not a MixinType`);
|
|
@@ -17,12 +17,16 @@ export const Value = function (owner, initArgs) {
|
|
|
17
17
|
* @class Value
|
|
18
18
|
*/
|
|
19
19
|
class ValueClass extends DocumentElement {
|
|
20
|
-
toJSON() {
|
|
20
|
+
toJSON(options) {
|
|
21
21
|
const typeName = this.type
|
|
22
22
|
? this.node.getDataTypeNameWithNs(this.type)
|
|
23
23
|
: undefined;
|
|
24
24
|
return omitUndefined({
|
|
25
|
-
type: this.type
|
|
25
|
+
type: this.type
|
|
26
|
+
? typeName
|
|
27
|
+
? typeName
|
|
28
|
+
: this.type.toJSON(options)
|
|
29
|
+
: 'any',
|
|
26
30
|
description: this.description,
|
|
27
31
|
isArray: this.isArray,
|
|
28
32
|
examples: this.examples,
|
|
@@ -7,7 +7,6 @@ export const DECORATOR = Symbol.for('DECORATOR');
|
|
|
7
7
|
export const BUILTIN = Symbol.for('BUILTIN');
|
|
8
8
|
export const NAMESPACE_PATTERN = /([a-z$_]\w+):(.+)/i;
|
|
9
9
|
export const CLASS_NAME_PATTERN = /^[a-z][\w_]*$/i;
|
|
10
|
-
export const EXTRACT_TYPENAME_PATTERN = /^(.*)Type(\d*)$/;
|
|
11
10
|
export const kDataTypeMap = Symbol.for('kDataTypeMap');
|
|
12
11
|
export const kCtorMap = Symbol.for('kCtorMap');
|
|
13
12
|
export const kTypeNSMap = Symbol.for('kTypeNSMap');
|
|
@@ -25,6 +25,7 @@ export const ApiField = function (...args) {
|
|
|
25
25
|
throw new Error('Field origin should be one of ComplexType, MappedType or MixinType');
|
|
26
26
|
}
|
|
27
27
|
_this.origin = origin;
|
|
28
|
+
_this.scopes = initArgs.scopes;
|
|
28
29
|
_this.type = initArgs.type || owner.node.getDataType('any');
|
|
29
30
|
_this.description = initArgs.description;
|
|
30
31
|
_this.isArray = initArgs.isArray;
|
|
@@ -38,19 +39,31 @@ export const ApiField = function (...args) {
|
|
|
38
39
|
_this.readonly = initArgs.readonly;
|
|
39
40
|
_this.writeonly = initArgs.writeonly;
|
|
40
41
|
_this.examples = initArgs.examples;
|
|
41
|
-
_this.hidden = initArgs.hidden;
|
|
42
42
|
};
|
|
43
43
|
/**
|
|
44
44
|
*
|
|
45
45
|
* @class ApiField
|
|
46
46
|
*/
|
|
47
47
|
class ApiFieldClass extends DocumentElement {
|
|
48
|
-
|
|
48
|
+
inScope(scopes) {
|
|
49
|
+
if (!this.scopes?.length || !scopes)
|
|
50
|
+
return true;
|
|
51
|
+
/** this.scope should match all required scopes */
|
|
52
|
+
scopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
53
|
+
for (const scope of scopes) {
|
|
54
|
+
if (!this.scopes.some(s => {
|
|
55
|
+
return typeof s === 'string' ? scope === s : s.test(scope);
|
|
56
|
+
}))
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
toJSON(options) {
|
|
49
62
|
const typeName = this.type
|
|
50
63
|
? this.node.getDataTypeNameWithNs(this.type)
|
|
51
64
|
: undefined;
|
|
52
65
|
return omitUndefined({
|
|
53
|
-
type: typeName ? typeName : this.type?.toJSON(),
|
|
66
|
+
type: typeName ? typeName : this.type?.toJSON(options),
|
|
54
67
|
description: this.description,
|
|
55
68
|
isArray: this.isArray || undefined,
|
|
56
69
|
default: this.default,
|
|
@@ -146,12 +146,21 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
146
146
|
const schema = {};
|
|
147
147
|
const { currentPath, projection } = context;
|
|
148
148
|
const pickList = !!(projection && Object.values(projection).find(p => !p.sign));
|
|
149
|
+
const scope = context.scope
|
|
150
|
+
? Array.isArray(context.scope)
|
|
151
|
+
? context.scope
|
|
152
|
+
: [context.scope]
|
|
153
|
+
: undefined;
|
|
149
154
|
// Process fields
|
|
150
155
|
let fieldName;
|
|
151
156
|
for (const field of this.fields.values()) {
|
|
152
|
-
if (
|
|
153
|
-
|
|
154
|
-
|
|
157
|
+
if (
|
|
158
|
+
/** Ignore field if required scope(s) do not match field scopes */
|
|
159
|
+
(scope && !field.inScope(scope)) ||
|
|
160
|
+
/** Ignore field if readonly and ignoreReadonlyFields option true */
|
|
161
|
+
(context.ignoreReadonlyFields && field.readonly) ||
|
|
162
|
+
/** Ignore field if writeonly and ignoreWriteonlyFields option true */
|
|
163
|
+
(context.ignoreWriteonlyFields && field.writeonly)) {
|
|
155
164
|
schema[field.name] = vg.isUndefined({ coerce: true });
|
|
156
165
|
continue;
|
|
157
166
|
}
|