@opra/common 1.4.3 → 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 +16 -9
- package/cjs/document/common/api-base.js +4 -2
- package/cjs/document/common/data-type-map.js +14 -3
- 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 +9 -3
- package/cjs/document/constants.js +1 -2
- package/cjs/document/data-type/api-field.js +19 -4
- package/cjs/document/data-type/complex-type-base.js +24 -7
- package/cjs/document/data-type/complex-type.js +17 -6
- package/cjs/document/data-type/data-type.js +16 -1
- package/cjs/document/data-type/enum-type.js +12 -3
- 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 +6 -1
- package/cjs/document/data-type/extended-types/date.type.js +6 -1
- package/cjs/document/data-type/extended-types/email.type.js +1 -0
- package/cjs/document/data-type/extended-types/field-path.type.js +9 -3
- package/cjs/document/data-type/extended-types/filter.type.js +14 -5
- 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 +21 -9
- package/cjs/document/data-type/mixin-type.js +10 -5
- package/cjs/document/data-type/primitive-types/any.type.js +1 -0
- package/cjs/document/data-type/primitive-types/bigint.type.js +4 -1
- package/cjs/document/data-type/primitive-types/boolean.type.js +1 -0
- package/cjs/document/data-type/primitive-types/integer.type.js +4 -1
- package/cjs/document/data-type/primitive-types/null.type.js +1 -0
- package/cjs/document/data-type/primitive-types/number.type.js +4 -1
- package/cjs/document/data-type/primitive-types/string.type.js +4 -1
- package/cjs/document/data-type/simple-type.js +17 -5
- package/cjs/document/data-type/utils/create-mapped-class.js +3 -1
- package/cjs/document/decorators/api-field-decorator.js +2 -1
- package/cjs/document/decorators/complex-type.decorator.js +1 -1
- package/cjs/document/decorators/http-controller.decorator.js +7 -1
- package/cjs/document/decorators/http-operation-entity.decorator.js +20 -10
- package/cjs/document/decorators/http-operation.decorator.js +23 -10
- package/cjs/document/decorators/rpc-operation.decorator.js +1 -2
- package/cjs/document/decorators/simple-type.decorator.js +3 -2
- package/cjs/document/factory/api-document.factory.js +12 -3
- package/cjs/document/factory/data-type.factory.js +19 -7
- package/cjs/document/factory/http-api.factory.js +13 -4
- package/cjs/document/http/http-api.js +2 -2
- package/cjs/document/http/http-controller.js +7 -6
- package/cjs/document/http/http-media-type.js +18 -8
- package/cjs/document/http/http-multipart-field.js +2 -2
- package/cjs/document/http/http-operation-response.js +11 -6
- package/cjs/document/http/http-operation.js +8 -6
- package/cjs/document/http/http-parameter.js +2 -2
- package/cjs/document/http/http-request-body.js +4 -2
- package/cjs/document/http/http-status-range.js +3 -1
- package/cjs/document/rpc/rpc-operation-response.js +11 -3
- package/cjs/document/rpc/rpc-operation.js +11 -3
- package/cjs/document/utils/parse-regexp.util.js +2 -2
- package/cjs/exception/opra-exception.js +3 -1
- package/cjs/filter/antlr/OpraFilterLexer.js +190 -123
- package/cjs/filter/antlr/OpraFilterParser.js +53 -35
- package/cjs/filter/ast/expressions/arithmetic-expression.js +3 -1
- package/cjs/filter/ast/terms/number-literal.js +3 -1
- package/cjs/filter/filter-rules.js +18 -8
- package/cjs/filter/filter-tree-visitor.js +2 -1
- package/cjs/filter/opra-error-listener.js +7 -1
- package/cjs/filter/parse.js +3 -1
- package/cjs/filter/utils.js +3 -1
- package/cjs/helpers/get-stack-filename.js +6 -2
- package/cjs/helpers/mixin-utils.js +7 -2
- package/cjs/helpers/object-utils.js +3 -1
- package/cjs/helpers/parse-fields-projection.js +4 -2
- package/cjs/helpers/type-guards.js +7 -2
- package/cjs/i18n/i18n.js +13 -3
- package/cjs/i18n/translate.js +3 -1
- package/cjs/polifils/array-find-last.js +0 -2
- package/esm/document/api-document.js +17 -10
- package/esm/document/common/api-base.js +4 -2
- package/esm/document/common/data-type-map.js +14 -3
- 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 +9 -3
- package/esm/document/constants.js +0 -1
- package/esm/document/data-type/api-field.js +19 -4
- package/esm/document/data-type/complex-type-base.js +25 -8
- package/esm/document/data-type/complex-type.js +17 -6
- package/esm/document/data-type/data-type.js +17 -2
- package/esm/document/data-type/enum-type.js +12 -3
- 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 +6 -1
- package/esm/document/data-type/extended-types/date.type.js +6 -1
- package/esm/document/data-type/extended-types/email.type.js +1 -0
- package/esm/document/data-type/extended-types/field-path.type.js +9 -3
- package/esm/document/data-type/extended-types/filter.type.js +14 -5
- 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 +21 -9
- package/esm/document/data-type/mixin-type.js +11 -6
- package/esm/document/data-type/primitive-types/any.type.js +1 -0
- package/esm/document/data-type/primitive-types/bigint.type.js +4 -1
- package/esm/document/data-type/primitive-types/boolean.type.js +1 -0
- package/esm/document/data-type/primitive-types/integer.type.js +4 -1
- package/esm/document/data-type/primitive-types/null.type.js +1 -0
- package/esm/document/data-type/primitive-types/number.type.js +4 -1
- package/esm/document/data-type/primitive-types/string.type.js +4 -1
- package/esm/document/data-type/simple-type.js +18 -6
- package/esm/document/data-type/utils/create-mapped-class.js +4 -2
- package/esm/document/decorators/api-field-decorator.js +2 -1
- package/esm/document/decorators/complex-type.decorator.js +2 -2
- package/esm/document/decorators/http-controller.decorator.js +7 -1
- package/esm/document/decorators/http-operation-entity.decorator.js +22 -12
- package/esm/document/decorators/http-operation.decorator.js +23 -10
- package/esm/document/decorators/rpc-operation.decorator.js +1 -2
- package/esm/document/decorators/simple-type.decorator.js +4 -3
- package/esm/document/factory/api-document.factory.js +12 -3
- package/esm/document/factory/data-type.factory.js +21 -9
- package/esm/document/factory/http-api.factory.js +13 -4
- package/esm/document/http/http-api.js +2 -2
- package/esm/document/http/http-controller.js +8 -7
- package/esm/document/http/http-media-type.js +18 -8
- package/esm/document/http/http-multipart-field.js +2 -2
- package/esm/document/http/http-operation-response.js +11 -6
- package/esm/document/http/http-operation.js +9 -7
- package/esm/document/http/http-parameter.js +3 -3
- package/esm/document/http/http-request-body.js +4 -2
- package/esm/document/http/http-status-range.js +3 -1
- package/esm/document/rpc/rpc-controller.js +1 -1
- package/esm/document/rpc/rpc-header.js +1 -1
- package/esm/document/rpc/rpc-operation-response.js +11 -3
- package/esm/document/rpc/rpc-operation.js +12 -4
- package/esm/document/utils/parse-regexp.util.js +2 -2
- package/esm/exception/opra-exception.js +3 -1
- package/esm/filter/antlr/OpraFilterLexer.js +190 -123
- package/esm/filter/antlr/OpraFilterParser.js +53 -35
- package/esm/filter/ast/expressions/arithmetic-expression.js +3 -1
- package/esm/filter/ast/terms/number-literal.js +3 -1
- package/esm/filter/filter-rules.js +18 -8
- package/esm/filter/filter-tree-visitor.js +2 -1
- package/esm/filter/opra-error-listener.js +8 -2
- package/esm/filter/parse.js +3 -1
- package/esm/filter/utils.js +3 -1
- package/esm/helpers/get-stack-filename.js +6 -2
- package/esm/helpers/mixin-utils.js +7 -2
- package/esm/helpers/object-utils.js +3 -1
- package/esm/helpers/parse-fields-projection.js +4 -2
- package/esm/helpers/type-guards.js +7 -2
- package/esm/i18n/i18n.js +13 -3
- package/esm/i18n/translate.js +3 -1
- package/esm/polifils/array-find-last.js +0 -2
- 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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { asMutable } from 'ts-gems';
|
|
2
2
|
import { validator, vg } from 'valgen';
|
|
3
|
-
import { parseFieldsProjection, ResponsiveMap } from '../../helpers/index.js';
|
|
3
|
+
import { parseFieldsProjection, ResponsiveMap, } from '../../helpers/index.js';
|
|
4
4
|
import { translate } from '../../i18n/index.js';
|
|
5
5
|
import { DataType } from './data-type.js';
|
|
6
6
|
export const FIELD_PATH_PATTERN = /^([+-])?([a-z$_][\w.]*)$/i;
|
|
@@ -83,7 +83,8 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
83
83
|
dataType = undefined;
|
|
84
84
|
continue;
|
|
85
85
|
}
|
|
86
|
-
if (dataType.additionalFields?.[0] === 'type' &&
|
|
86
|
+
if (dataType.additionalFields?.[0] === 'type' &&
|
|
87
|
+
dataType.additionalFields?.[1] instanceof DataType) {
|
|
87
88
|
item.additionalField = true;
|
|
88
89
|
item.dataType = dataType.additionalFields[1];
|
|
89
90
|
dataType = dataType.additionalFields[1];
|
|
@@ -113,7 +114,11 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
113
114
|
const projection = Array.isArray(options?.projection)
|
|
114
115
|
? parseFieldsProjection(options.projection)
|
|
115
116
|
: options?.projection;
|
|
116
|
-
const schema = this._generateSchema(codec, {
|
|
117
|
+
const schema = this._generateSchema(codec, {
|
|
118
|
+
...options,
|
|
119
|
+
projection,
|
|
120
|
+
currentPath: '',
|
|
121
|
+
});
|
|
117
122
|
let additionalFields;
|
|
118
123
|
if (this.additionalFields instanceof DataType) {
|
|
119
124
|
additionalFields = this.additionalFields.generateCodec(codec, options);
|
|
@@ -141,12 +146,21 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
141
146
|
const schema = {};
|
|
142
147
|
const { currentPath, projection } = context;
|
|
143
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;
|
|
144
154
|
// Process fields
|
|
145
155
|
let fieldName;
|
|
146
156
|
for (const field of this.fields.values()) {
|
|
147
|
-
if (
|
|
148
|
-
|
|
149
|
-
|
|
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)) {
|
|
150
164
|
schema[field.name] = vg.isUndefined({ coerce: true });
|
|
151
165
|
continue;
|
|
152
166
|
}
|
|
@@ -168,10 +182,13 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
168
182
|
const fn = this._generateFieldCodec(codec, field, {
|
|
169
183
|
...context,
|
|
170
184
|
partial: context.partial === 'deep' ? context.partial : undefined,
|
|
171
|
-
projection: typeof projection === 'object'
|
|
185
|
+
projection: typeof projection === 'object'
|
|
186
|
+
? projection[fieldName]?.projection || '*'
|
|
187
|
+
: projection,
|
|
172
188
|
currentPath: currentPath + (currentPath ? '.' : '') + fieldName,
|
|
173
189
|
});
|
|
174
|
-
schema[fieldName] =
|
|
190
|
+
schema[fieldName] =
|
|
191
|
+
context.partial || !field.required ? vg.optional(fn) : vg.required(fn);
|
|
175
192
|
}
|
|
176
193
|
if (context.allowPatchOperators) {
|
|
177
194
|
schema._$pull = vg.optional(vg.isAny());
|
|
@@ -68,17 +68,28 @@ class ComplexTypeClass extends ComplexTypeBase {
|
|
|
68
68
|
return true;
|
|
69
69
|
return !!this.base?.extendsFrom(baseType);
|
|
70
70
|
}
|
|
71
|
-
toJSON() {
|
|
72
|
-
const baseName = this.base
|
|
71
|
+
toJSON(options) {
|
|
72
|
+
const baseName = this.base
|
|
73
|
+
? this.node.getDataTypeNameWithNs(this.base)
|
|
74
|
+
: undefined;
|
|
75
|
+
if (options?.scopes && !this.base?.inScope(options?.scopes))
|
|
76
|
+
throw new TypeError(`Base type ${baseName ? '(' + baseName + ')' : ''} of ${this.name ? +this.name : 'embedded'} type ` +
|
|
77
|
+
`is not in required scope(s) [${options.scopes}`);
|
|
73
78
|
const out = omitUndefined({
|
|
74
79
|
...ComplexTypeBase.prototype.toJSON.call(this),
|
|
75
80
|
kind: this.kind,
|
|
76
|
-
base: this.base
|
|
81
|
+
base: this.base
|
|
82
|
+
? baseName
|
|
83
|
+
? baseName
|
|
84
|
+
: this.base.toJSON(options)
|
|
85
|
+
: undefined,
|
|
77
86
|
});
|
|
78
87
|
if (this.additionalFields) {
|
|
79
88
|
if (this.additionalFields instanceof DataType) {
|
|
80
89
|
const typeName = this.node.getDataTypeNameWithNs(this.additionalFields);
|
|
81
|
-
out.additionalFields = typeName
|
|
90
|
+
out.additionalFields = typeName
|
|
91
|
+
? typeName
|
|
92
|
+
: this.additionalFields.toJSON(options);
|
|
82
93
|
}
|
|
83
94
|
else
|
|
84
95
|
out.additionalFields = this.additionalFields;
|
|
@@ -87,8 +98,8 @@ class ComplexTypeClass extends ComplexTypeBase {
|
|
|
87
98
|
const fields = {};
|
|
88
99
|
let i = 0;
|
|
89
100
|
for (const field of this.fields.values()) {
|
|
90
|
-
if (field.origin === this) {
|
|
91
|
-
fields[field.name] = field.toJSON();
|
|
101
|
+
if (field.origin === this && field.inScope(options?.scopes)) {
|
|
102
|
+
fields[field.name] = field.toJSON(options);
|
|
92
103
|
i++;
|
|
93
104
|
}
|
|
94
105
|
}
|
|
@@ -2,7 +2,7 @@ import { omitUndefined } from '@jsopen/objects';
|
|
|
2
2
|
import { asMutable } from 'ts-gems';
|
|
3
3
|
import { DocumentElement } from '../common/document-element.js';
|
|
4
4
|
import { CLASS_NAME_PATTERN } from '../constants.js';
|
|
5
|
-
import { colorFgMagenta, colorFgYellow, colorReset, nodeInspectCustom } from '../utils/inspect.util.js';
|
|
5
|
+
import { colorFgMagenta, colorFgYellow, colorReset, nodeInspectCustom, } from '../utils/inspect.util.js';
|
|
6
6
|
/**
|
|
7
7
|
* DataType constructor
|
|
8
8
|
*/
|
|
@@ -17,6 +17,7 @@ context) {
|
|
|
17
17
|
DocumentElement.call(this, owner);
|
|
18
18
|
const _this = asMutable(this);
|
|
19
19
|
_this.kind = initArgs.kind;
|
|
20
|
+
_this.scopes = initArgs.scopes;
|
|
20
21
|
_this.name = initArgs.name;
|
|
21
22
|
_this.description = initArgs.description;
|
|
22
23
|
_this.abstract = initArgs.abstract;
|
|
@@ -30,7 +31,21 @@ class DataTypeClass extends DocumentElement {
|
|
|
30
31
|
get embedded() {
|
|
31
32
|
return !this.name;
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
+
inScope(scopes) {
|
|
35
|
+
if (!this.scopes?.length || !scopes)
|
|
36
|
+
return true;
|
|
37
|
+
/** this.scope should match all required scopes */
|
|
38
|
+
scopes = Array.isArray(scopes) ? scopes : [scopes];
|
|
39
|
+
for (const scope of scopes) {
|
|
40
|
+
if (!this.scopes.some(s => {
|
|
41
|
+
return typeof s === 'string' ? scope === s : s.test(scope);
|
|
42
|
+
}))
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
// eslint-disable-next-line
|
|
48
|
+
toJSON(options) {
|
|
34
49
|
return omitUndefined({
|
|
35
50
|
kind: this.kind,
|
|
36
51
|
description: this.description,
|
|
@@ -48,11 +48,20 @@ class EnumTypeClass extends DataType {
|
|
|
48
48
|
generateCodec() {
|
|
49
49
|
return vg.isEnum(Object.keys(this.attributes));
|
|
50
50
|
}
|
|
51
|
-
toJSON() {
|
|
52
|
-
const baseName = this.base
|
|
51
|
+
toJSON(options) {
|
|
52
|
+
const baseName = this.base
|
|
53
|
+
? this.node.getDataTypeNameWithNs(this.base)
|
|
54
|
+
: undefined;
|
|
55
|
+
if (options?.scopes && !this.base?.inScope(options?.scopes))
|
|
56
|
+
throw new TypeError(`Base type ${baseName ? '(' + baseName + ')' : ''} of ${this.name ? +this.name : 'embedded'} type ` +
|
|
57
|
+
`is not in required scope(s) [${options.scopes}`);
|
|
53
58
|
return omitUndefined({
|
|
54
59
|
...DataType.prototype.toJSON.call(this),
|
|
55
|
-
base: this.base
|
|
60
|
+
base: this.base
|
|
61
|
+
? baseName
|
|
62
|
+
? baseName
|
|
63
|
+
: this.base.toJSON(options)
|
|
64
|
+
: undefined,
|
|
56
65
|
attributes: cloneObject(this.ownAttributes),
|
|
57
66
|
});
|
|
58
67
|
}
|
|
@@ -21,7 +21,11 @@ let DateTimeType = class DateTimeType {
|
|
|
21
21
|
return x.length > 0 ? vg.pipe([fn, ...x], { returnIndex: 0 }) : fn;
|
|
22
22
|
}
|
|
23
23
|
[ENCODER](properties) {
|
|
24
|
-
const fn = vg.isDateString({
|
|
24
|
+
const fn = vg.isDateString({
|
|
25
|
+
precision: 'time',
|
|
26
|
+
trim: 'time',
|
|
27
|
+
coerce: true,
|
|
28
|
+
});
|
|
25
29
|
const x = [];
|
|
26
30
|
if (properties.minValue) {
|
|
27
31
|
isDateString(properties.minValue);
|
|
@@ -48,6 +52,7 @@ __decorate([
|
|
|
48
52
|
], DateTimeType.prototype, "maxValue", void 0);
|
|
49
53
|
DateTimeType = __decorate([
|
|
50
54
|
(SimpleType({
|
|
55
|
+
name: 'datetime',
|
|
51
56
|
description: 'A full datetime value',
|
|
52
57
|
nameMappings: {
|
|
53
58
|
js: 'string',
|
|
@@ -21,7 +21,11 @@ let DateType = class DateType {
|
|
|
21
21
|
return x.length > 0 ? vg.pipe([fn, ...x], { returnIndex: 0 }) : fn;
|
|
22
22
|
}
|
|
23
23
|
[ENCODER](properties) {
|
|
24
|
-
const fn = vg.isDateString({
|
|
24
|
+
const fn = vg.isDateString({
|
|
25
|
+
precision: 'date',
|
|
26
|
+
trim: 'date',
|
|
27
|
+
coerce: true,
|
|
28
|
+
});
|
|
25
29
|
const x = [];
|
|
26
30
|
if (properties.minValue) {
|
|
27
31
|
isDateString(properties.minValue);
|
|
@@ -48,6 +52,7 @@ __decorate([
|
|
|
48
52
|
], DateType.prototype, "maxValue", void 0);
|
|
49
53
|
DateType = __decorate([
|
|
50
54
|
(SimpleType({
|
|
55
|
+
name: 'date',
|
|
51
56
|
description: 'A date without time',
|
|
52
57
|
nameMappings: {
|
|
53
58
|
js: 'Date',
|
|
@@ -18,13 +18,18 @@ let FieldPathType = class FieldPathType {
|
|
|
18
18
|
[ENCODER](properties, element) {
|
|
19
19
|
return this[DECODER](properties, element);
|
|
20
20
|
}
|
|
21
|
-
toJSON(properties, element) {
|
|
21
|
+
toJSON(properties, element, options) {
|
|
22
22
|
const dataType = properties.dataType
|
|
23
23
|
? element.node.getComplexType(properties.dataType)
|
|
24
24
|
: element.node.getComplexType('object');
|
|
25
|
-
const typeName = dataType
|
|
25
|
+
const typeName = dataType
|
|
26
|
+
? element.node.getDataTypeNameWithNs(dataType)
|
|
27
|
+
: undefined;
|
|
28
|
+
if (options?.scopes && !dataType.inScope(options?.scopes))
|
|
29
|
+
throw new TypeError(`Data type ${typeName ? '(' + typeName + ')' : ''} ` +
|
|
30
|
+
`is not in required scope(s) [${options.scopes}`);
|
|
26
31
|
return {
|
|
27
|
-
dataType: typeName ? typeName : dataType.toJSON(),
|
|
32
|
+
dataType: typeName ? typeName : dataType.toJSON(options),
|
|
28
33
|
allowSigns: properties.allowSigns,
|
|
29
34
|
};
|
|
30
35
|
}
|
|
@@ -45,6 +50,7 @@ __decorate([
|
|
|
45
50
|
], FieldPathType.prototype, "allowSigns", void 0);
|
|
46
51
|
FieldPathType = __decorate([
|
|
47
52
|
SimpleType({
|
|
53
|
+
name: 'fieldpath',
|
|
48
54
|
description: 'Field path',
|
|
49
55
|
nameMappings: {
|
|
50
56
|
js: 'string',
|
|
@@ -13,18 +13,26 @@ let FilterType = class FilterType {
|
|
|
13
13
|
const dataType = properties.dataType
|
|
14
14
|
? element.node.getComplexType(properties.dataType)
|
|
15
15
|
: element.node.getComplexType('object');
|
|
16
|
-
const rules = properties.rules
|
|
16
|
+
const rules = properties.rules
|
|
17
|
+
? new FilterRules(properties.rules)
|
|
18
|
+
: undefined;
|
|
17
19
|
return decodeFilter(dataType, rules);
|
|
18
20
|
}
|
|
19
21
|
[ENCODER]() {
|
|
20
22
|
return encodeFilter;
|
|
21
23
|
}
|
|
22
|
-
toJSON(properties, element) {
|
|
24
|
+
toJSON(properties, element, options) {
|
|
23
25
|
const dataType = properties.dataType
|
|
24
26
|
? element.node.getComplexType(properties.dataType)
|
|
25
27
|
: element.node.getComplexType('object');
|
|
28
|
+
const typeName = dataType
|
|
29
|
+
? element.node.getDataTypeNameWithNs(dataType)
|
|
30
|
+
: undefined;
|
|
31
|
+
if (options?.scopes && !dataType.inScope(options?.scopes))
|
|
32
|
+
throw new TypeError(`Data type ${typeName ? '(' + typeName + ')' : ''} ` +
|
|
33
|
+
`is not in required scope(s) [${options.scopes}`);
|
|
26
34
|
return {
|
|
27
|
-
dataType:
|
|
35
|
+
dataType: typeName ? typeName : dataType.toJSON(options),
|
|
28
36
|
rules: properties.rules,
|
|
29
37
|
};
|
|
30
38
|
}
|
|
@@ -44,6 +52,7 @@ __decorate([
|
|
|
44
52
|
], FilterType.prototype, "rules", void 0);
|
|
45
53
|
FilterType = __decorate([
|
|
46
54
|
SimpleType({
|
|
55
|
+
name: 'filter',
|
|
47
56
|
description: 'A query filter',
|
|
48
57
|
nameMappings: {
|
|
49
58
|
js: 'object',
|
|
@@ -53,12 +62,12 @@ FilterType = __decorate([
|
|
|
53
62
|
__metadata("design:paramtypes", [Object])
|
|
54
63
|
], FilterType);
|
|
55
64
|
export { FilterType };
|
|
56
|
-
const decodeFilter = (dataType, rules) => validator('decodeFilter', (input, context, _this) => {
|
|
65
|
+
const decodeFilter = (dataType, rules, element) => validator('decodeFilter', (input, context, _this) => {
|
|
57
66
|
if (typeof input === 'string') {
|
|
58
67
|
try {
|
|
59
68
|
const filter = OpraFilter.parse(input);
|
|
60
69
|
if (rules)
|
|
61
|
-
return rules.normalizeFilter(filter, dataType);
|
|
70
|
+
return rules.normalizeFilter(filter, dataType, element);
|
|
62
71
|
return filter;
|
|
63
72
|
}
|
|
64
73
|
catch (e) {
|
|
@@ -40,16 +40,22 @@ export const MappedType = function (...args) {
|
|
|
40
40
|
}
|
|
41
41
|
/** Copy fields from base */
|
|
42
42
|
const isInheritedPredicate = getIsInheritedPredicateFn(_this.pick, _this.omit);
|
|
43
|
-
const partial = Array.isArray(_this.partial)
|
|
44
|
-
|
|
43
|
+
const partial = Array.isArray(_this.partial)
|
|
44
|
+
? _this.partial.map(x => x.toLowerCase())
|
|
45
|
+
: _this.partial;
|
|
46
|
+
const required = Array.isArray(_this.required)
|
|
47
|
+
? _this.required.map(x => x.toLowerCase())
|
|
48
|
+
: _this.required;
|
|
45
49
|
for (const [k, v] of _this.base.fields.entries()) {
|
|
46
50
|
if (!isInheritedPredicate(k))
|
|
47
51
|
continue;
|
|
48
52
|
const meta = { ...v };
|
|
49
|
-
if (partial === true ||
|
|
53
|
+
if (partial === true ||
|
|
54
|
+
(Array.isArray(partial) && partial.includes(v.name.toLowerCase()))) {
|
|
50
55
|
meta.required = false;
|
|
51
56
|
}
|
|
52
|
-
else if (required === true ||
|
|
57
|
+
else if (required === true ||
|
|
58
|
+
(Array.isArray(required) && required.includes(v.name.toLowerCase()))) {
|
|
53
59
|
meta.required = true;
|
|
54
60
|
}
|
|
55
61
|
const field = new ApiField(this, meta);
|
|
@@ -57,7 +63,8 @@ export const MappedType = function (...args) {
|
|
|
57
63
|
}
|
|
58
64
|
if (!_this.pick ||
|
|
59
65
|
_this.base.additionalFields === false ||
|
|
60
|
-
(Array.isArray(_this.base.additionalFields) &&
|
|
66
|
+
(Array.isArray(_this.base.additionalFields) &&
|
|
67
|
+
_this.base.additionalFields?.[0] === 'error')) {
|
|
61
68
|
_this.additionalFields = _this.base.additionalFields;
|
|
62
69
|
}
|
|
63
70
|
if (initArgs.base.keyField && isInheritedPredicate(initArgs.base.keyField))
|
|
@@ -78,11 +85,16 @@ class MappedTypeClass extends ComplexTypeBase {
|
|
|
78
85
|
return true;
|
|
79
86
|
return !!this.base?.extendsFrom(baseType);
|
|
80
87
|
}
|
|
81
|
-
toJSON() {
|
|
82
|
-
const baseName = this.base
|
|
88
|
+
toJSON(options) {
|
|
89
|
+
const baseName = this.base
|
|
90
|
+
? this.node.getDataTypeNameWithNs(this.base)
|
|
91
|
+
: undefined;
|
|
92
|
+
if (options?.scopes && !this.base?.inScope(options?.scopes))
|
|
93
|
+
throw new TypeError(`Base type ${baseName ? '(' + baseName + ')' : ''} of ${this.name ? +this.name : 'embedded'} type ` +
|
|
94
|
+
`is not in required scope(s) [${options.scopes}`);
|
|
83
95
|
return omitUndefined({
|
|
84
|
-
...ComplexTypeBase.prototype.toJSON.call(this),
|
|
85
|
-
base: baseName ? baseName : this.base.toJSON(),
|
|
96
|
+
...ComplexTypeBase.prototype.toJSON.call(this, options),
|
|
97
|
+
base: baseName ? baseName : this.base.toJSON(options),
|
|
86
98
|
kind: this.kind,
|
|
87
99
|
pick: this.pick,
|
|
88
100
|
omit: this.omit,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
2
|
import { omitUndefined } from '@jsopen/objects';
|
|
3
3
|
import { asMutable } from 'ts-gems';
|
|
4
|
-
import { inheritPropertyInitializers, mergePrototype } from '../../helpers/index.js';
|
|
4
|
+
import { inheritPropertyInitializers, mergePrototype, } from '../../helpers/index.js';
|
|
5
5
|
import { OpraSchema } from '../../schema/index.js';
|
|
6
6
|
import { DATATYPE_METADATA, DECORATOR } from '../constants.js';
|
|
7
7
|
import { ApiField } from './api-field.js';
|
|
@@ -54,13 +54,16 @@ class MixinTypeClass extends ComplexTypeBase {
|
|
|
54
54
|
}
|
|
55
55
|
return false;
|
|
56
56
|
}
|
|
57
|
-
toJSON() {
|
|
57
|
+
toJSON(options) {
|
|
58
58
|
return omitUndefined({
|
|
59
59
|
...ComplexTypeBase.prototype.toJSON.call(this),
|
|
60
60
|
kind: this.kind,
|
|
61
|
-
types: this.types.map(
|
|
62
|
-
const baseName = this.node.getDataTypeNameWithNs(
|
|
63
|
-
|
|
61
|
+
types: this.types.map(base => {
|
|
62
|
+
const baseName = this.node.getDataTypeNameWithNs(base);
|
|
63
|
+
if (options?.scopes && !base?.inScope(options?.scopes))
|
|
64
|
+
throw new TypeError(`Base type ${baseName ? '(' + baseName + ')' : ''} of ${this.name ? +this.name : 'embedded'} type ` +
|
|
65
|
+
`is not in required scope(s) [${options.scopes}`);
|
|
66
|
+
return baseName ? baseName : base.toJSON(options);
|
|
64
67
|
}),
|
|
65
68
|
});
|
|
66
69
|
}
|
|
@@ -73,7 +76,9 @@ MixinType[DECORATOR] = MixinTypeFactory;
|
|
|
73
76
|
function MixinTypeFactory(...args) {
|
|
74
77
|
// Filter undefined items
|
|
75
78
|
const clasRefs = args.filter(x => typeof x === 'function');
|
|
76
|
-
const options = typeof args[args.length - 1] === 'object'
|
|
79
|
+
const options = typeof args[args.length - 1] === 'object'
|
|
80
|
+
? args[args.length - 1]
|
|
81
|
+
: undefined;
|
|
77
82
|
if (!clasRefs.length)
|
|
78
83
|
throw new TypeError('No Class has been provided');
|
|
79
84
|
if (clasRefs.length === 1)
|
|
@@ -13,7 +13,9 @@ let BigintType = class BigintType extends NumberType {
|
|
|
13
13
|
x.push(vg.isGte(properties.minValue));
|
|
14
14
|
if (properties.maxValue)
|
|
15
15
|
x.push(vg.isLte(properties.maxValue));
|
|
16
|
-
return x.length > 0
|
|
16
|
+
return x.length > 0
|
|
17
|
+
? vg.pipe([toBigint, ...x], { returnIndex: 0 })
|
|
18
|
+
: toBigint;
|
|
17
19
|
}
|
|
18
20
|
[ENCODER](properties) {
|
|
19
21
|
return this[DECODER](properties);
|
|
@@ -21,6 +23,7 @@ let BigintType = class BigintType extends NumberType {
|
|
|
21
23
|
};
|
|
22
24
|
BigintType = __decorate([
|
|
23
25
|
SimpleType({
|
|
26
|
+
name: 'bigint',
|
|
24
27
|
description: 'BigInt number',
|
|
25
28
|
nameMappings: {
|
|
26
29
|
js: 'bigint',
|
|
@@ -13,7 +13,9 @@ let IntegerType = class IntegerType extends NumberType {
|
|
|
13
13
|
x.push(vg.isGte(properties.minValue));
|
|
14
14
|
if (properties.maxValue)
|
|
15
15
|
x.push(vg.isLte(properties.maxValue));
|
|
16
|
-
return x.length > 0
|
|
16
|
+
return x.length > 0
|
|
17
|
+
? vg.pipe([toInteger, ...x], { returnIndex: 0 })
|
|
18
|
+
: toInteger;
|
|
17
19
|
}
|
|
18
20
|
[ENCODER](properties) {
|
|
19
21
|
return this[DECODER](properties);
|
|
@@ -21,6 +23,7 @@ let IntegerType = class IntegerType extends NumberType {
|
|
|
21
23
|
};
|
|
22
24
|
IntegerType = __decorate([
|
|
23
25
|
SimpleType({
|
|
26
|
+
name: 'integer',
|
|
24
27
|
description: 'An integer number',
|
|
25
28
|
nameMappings: {
|
|
26
29
|
js: 'number',
|
|
@@ -13,7 +13,9 @@ let NumberType = class NumberType {
|
|
|
13
13
|
x.push(vg.isGte(properties.minValue));
|
|
14
14
|
if (properties.maxValue)
|
|
15
15
|
x.push(vg.isLte(properties.maxValue));
|
|
16
|
-
return x.length > 0
|
|
16
|
+
return x.length > 0
|
|
17
|
+
? vg.pipe([toNumber, ...x], { returnIndex: 0 })
|
|
18
|
+
: toNumber;
|
|
17
19
|
}
|
|
18
20
|
[ENCODER](properties) {
|
|
19
21
|
return this[DECODER](properties);
|
|
@@ -33,6 +35,7 @@ __decorate([
|
|
|
33
35
|
], NumberType.prototype, "maxValue", void 0);
|
|
34
36
|
NumberType = __decorate([
|
|
35
37
|
SimpleType({
|
|
38
|
+
name: 'number',
|
|
36
39
|
description: 'Both Integer as well as Floating-Point numbers',
|
|
37
40
|
nameMappings: {
|
|
38
41
|
js: 'number',
|
|
@@ -21,7 +21,9 @@ let StringType = class StringType {
|
|
|
21
21
|
x.push(vg.lengthMin(properties.minLength));
|
|
22
22
|
if (properties.maxLength)
|
|
23
23
|
x.push(vg.lengthMax(properties.maxLength));
|
|
24
|
-
return x.length > 0
|
|
24
|
+
return x.length > 0
|
|
25
|
+
? vg.pipe([toString, ...x], { returnIndex: 0 })
|
|
26
|
+
: toString;
|
|
25
27
|
}
|
|
26
28
|
[ENCODER](properties) {
|
|
27
29
|
return this[DECODER](properties);
|
|
@@ -53,6 +55,7 @@ __decorate([
|
|
|
53
55
|
], StringType.prototype, "maxLength", void 0);
|
|
54
56
|
StringType = __decorate([
|
|
55
57
|
SimpleType({
|
|
58
|
+
name: 'string',
|
|
56
59
|
description: 'A sequence of characters',
|
|
57
60
|
nameMappings: {
|
|
58
61
|
js: 'string',
|
|
@@ -5,7 +5,7 @@ import { isAny } from 'valgen';
|
|
|
5
5
|
import { cloneObject } from '../../helpers/index.js';
|
|
6
6
|
import { OpraSchema } from '../../schema/index.js';
|
|
7
7
|
import { DECORATOR } from '../constants.js';
|
|
8
|
-
import { AttributeDecoratorFactory, SimpleTypeDecoratorFactory } from '../decorators/simple-type.decorator.js';
|
|
8
|
+
import { AttributeDecoratorFactory, SimpleTypeDecoratorFactory, } from '../decorators/simple-type.decorator.js';
|
|
9
9
|
import { DataType } from './data-type.js';
|
|
10
10
|
/**
|
|
11
11
|
* SimpleType constructor
|
|
@@ -28,7 +28,10 @@ export const SimpleType = function (...args) {
|
|
|
28
28
|
}
|
|
29
29
|
_this.properties = initArgs.properties;
|
|
30
30
|
_this.ownNameMappings = { ...initArgs.nameMappings };
|
|
31
|
-
_this.nameMappings = {
|
|
31
|
+
_this.nameMappings = {
|
|
32
|
+
..._this.base?.nameMappings,
|
|
33
|
+
...initArgs.nameMappings,
|
|
34
|
+
};
|
|
32
35
|
_this.ownAttributes = cloneObject(initArgs.attributes || {});
|
|
33
36
|
_this.attributes = _this.base ? cloneObject(_this.base.attributes) : {};
|
|
34
37
|
if (_this.ownAttributes) {
|
|
@@ -77,18 +80,27 @@ class SimpleTypeClass extends DataType {
|
|
|
77
80
|
}
|
|
78
81
|
return isAny;
|
|
79
82
|
}
|
|
80
|
-
toJSON() {
|
|
83
|
+
toJSON(options) {
|
|
81
84
|
const attributes = omitUndefined(this.ownAttributes);
|
|
82
85
|
let properties;
|
|
83
86
|
if (this.properties && typeof this.properties.toJSON === 'function') {
|
|
84
|
-
properties = this.properties.toJSON(this.properties, this.owner);
|
|
87
|
+
properties = this.properties.toJSON(this.properties, this.owner, options);
|
|
85
88
|
}
|
|
86
89
|
else
|
|
87
90
|
properties = this.properties ? cloneObject(this.properties) : {};
|
|
88
|
-
const baseName = this.base
|
|
91
|
+
const baseName = this.base
|
|
92
|
+
? this.node.getDataTypeNameWithNs(this.base)
|
|
93
|
+
: undefined;
|
|
94
|
+
if (options?.scopes && !this.base?.inScope(options?.scopes))
|
|
95
|
+
throw new TypeError(`Base type ${baseName ? '(' + baseName + ')' : ''} of ${this.name ? +this.name : 'embedded'} type ` +
|
|
96
|
+
`is not in required scope(s) [${options.scopes}`);
|
|
89
97
|
const out = omitUndefined({
|
|
90
98
|
...DataType.prototype.toJSON.apply(this),
|
|
91
|
-
base: this.base
|
|
99
|
+
base: this.base
|
|
100
|
+
? baseName
|
|
101
|
+
? baseName
|
|
102
|
+
: this.base.toJSON(options)
|
|
103
|
+
: undefined,
|
|
92
104
|
attributes: attributes && Object.keys(attributes).length ? attributes : undefined,
|
|
93
105
|
properties: Object.keys(properties).length ? properties : undefined,
|
|
94
106
|
});
|