@opra/common 1.0.0-alpha.8 → 1.0.0-beta.1
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 +12 -0
- package/browser/index.mjs +12 -0
- package/cjs/document/api-document.js +11 -0
- package/cjs/document/common/api-base.js +1 -1
- package/cjs/document/common/document-element.js +2 -0
- package/cjs/document/data-type/api-field.js +8 -7
- package/cjs/document/data-type/complex-type-base.js +5 -3
- package/cjs/document/data-type/extended-types/date-string.type.js +2 -2
- package/cjs/document/data-type/extended-types/date-time-string.type.js +2 -2
- package/cjs/document/data-type/extended-types/date-time.type.js +2 -2
- package/cjs/document/data-type/extended-types/date.type.js +2 -2
- package/cjs/document/data-type/extended-types/email.type.js +2 -2
- package/cjs/document/data-type/extended-types/filter.type.js +1 -1
- package/cjs/document/data-type/extended-types/time.type.js +2 -2
- package/cjs/document/data-type/extended-types/url.type.js +2 -2
- package/cjs/document/data-type/omit-type.js +7 -2
- package/cjs/document/data-type/partial-type.js +7 -2
- package/cjs/document/data-type/pick-type.js +1 -2
- package/cjs/document/data-type/primitive-types/object.type.js +0 -3
- package/cjs/document/data-type/required-type.js +1 -2
- package/cjs/document/data-type/simple-type.js +1 -6
- package/cjs/document/data-type/utils/create-mapped-class.js +1 -2
- package/cjs/document/data-type/utils/get-is-inherited-predicate-fn.js +1 -2
- package/cjs/document/decorators/api-field-decorator.js +4 -6
- package/cjs/document/decorators/complex-type.decorator.js +1 -2
- package/cjs/document/decorators/http-controller.decorator.js +2 -3
- package/cjs/document/decorators/http-operation-entity.decorator.js +68 -74
- package/cjs/document/decorators/http-operation.decorator.js +4 -2
- package/cjs/document/decorators/simple-type.decorator.js +2 -3
- package/cjs/document/factory/api-document.factory.js +17 -8
- package/cjs/document/http/http-api.js +0 -1
- package/cjs/document/http/http-controller.js +4 -2
- package/cjs/document/http/http-media-type.js +17 -2
- package/cjs/document/http/http-multipart-field.js +0 -1
- package/cjs/document/http/http-operation-response.js +0 -1
- package/cjs/document/http/http-operation.js +12 -1
- package/cjs/document/http/http-parameter.js +2 -0
- package/cjs/document/http/http-request-body.js +0 -1
- package/cjs/document/http/http-status-range.js +5 -2
- package/cjs/document/utils/parse-regexp.util.js +1 -2
- package/cjs/document/utils/string-compare.util.js +1 -2
- package/cjs/exception/opra-exception.js +1 -0
- package/cjs/filter/build.js +21 -22
- package/cjs/filter/filter-rules.js +17 -16
- package/cjs/filter/parse.js +1 -2
- package/cjs/filter/utils.js +2 -3
- package/cjs/helpers/function-utils.js +1 -2
- package/cjs/helpers/get-stack-filename.js +2 -3
- package/cjs/helpers/index.js +1 -0
- package/cjs/helpers/mixin-utils.js +2 -3
- package/cjs/helpers/object-utils.js +5 -6
- package/cjs/helpers/parse-fields-projection.js +3 -3
- package/cjs/helpers/safe-json-stringify.js +16 -0
- package/cjs/helpers/type-guards.js +10 -11
- package/cjs/i18n/string-utils.js +2 -3
- package/cjs/i18n/translate.js +1 -2
- package/cjs/schema/index.js +2 -27
- package/cjs/schema/opra-schema.js +24 -0
- package/cjs/schema/type-guards.js +7 -8
- package/esm/document/api-document.js +11 -0
- package/esm/document/common/api-base.js +1 -1
- package/esm/document/common/document-element.js +2 -0
- package/esm/document/data-type/api-field.js +8 -7
- package/esm/document/data-type/complex-type-base.js +5 -3
- package/esm/document/data-type/extended-types/date-string.type.js +2 -2
- package/esm/document/data-type/extended-types/date-time-string.type.js +2 -2
- package/esm/document/data-type/extended-types/date-time.type.js +2 -2
- package/esm/document/data-type/extended-types/date.type.js +2 -2
- package/esm/document/data-type/extended-types/email.type.js +2 -2
- package/esm/document/data-type/extended-types/filter.type.js +1 -1
- package/esm/document/data-type/extended-types/time.type.js +2 -2
- package/esm/document/data-type/extended-types/url.type.js +2 -2
- package/esm/document/data-type/omit-type.js +6 -0
- package/esm/document/data-type/partial-type.js +6 -0
- package/esm/document/data-type/primitive-types/object.type.js +0 -3
- package/esm/document/data-type/simple-type.js +1 -6
- package/esm/document/decorators/api-field-decorator.js +1 -2
- package/esm/document/decorators/http-controller.decorator.js +1 -1
- package/esm/document/decorators/http-operation-entity.decorator.js +25 -31
- package/esm/document/decorators/http-operation.decorator.js +3 -0
- package/esm/document/factory/api-document.factory.js +17 -7
- package/esm/document/http/http-api.js +0 -1
- package/esm/document/http/http-controller.js +3 -2
- package/esm/document/http/http-media-type.js +16 -2
- package/esm/document/http/http-multipart-field.js +0 -1
- package/esm/document/http/http-operation-response.js +0 -1
- package/esm/document/http/http-operation.js +12 -1
- package/esm/document/http/http-parameter.js +2 -0
- package/esm/document/http/http-request-body.js +0 -1
- package/esm/document/http/http-status-range.js +5 -2
- package/esm/exception/opra-exception.js +1 -0
- package/esm/filter/filter-rules.js +10 -9
- package/esm/helpers/index.js +1 -0
- package/esm/helpers/object-utils.js +2 -2
- package/esm/helpers/safe-json-stringify.js +13 -0
- package/esm/package.json +3 -0
- package/esm/schema/index.js +2 -27
- package/esm/schema/opra-schema.js +21 -0
- package/package.json +47 -53
- package/types/document/api-document.d.ts +2 -1
- package/types/document/common/api-base.d.ts +2 -2
- package/types/document/common/data-type-map.d.ts +1 -1
- package/types/document/common/document-element.d.ts +1 -0
- package/types/document/common/document-node.d.ts +8 -8
- package/types/document/common/value.d.ts +1 -1
- package/types/document/data-type/api-field.d.ts +11 -1
- package/types/document/data-type/complex-type-base.d.ts +6 -7
- package/types/document/data-type/complex-type.d.ts +1 -1
- package/types/document/data-type/data-type.d.ts +3 -2
- package/types/document/data-type/enum-type.d.ts +2 -2
- package/types/document/data-type/extended-types/base64.type.d.ts +1 -1
- package/types/document/data-type/extended-types/date-string.type.d.ts +1 -1
- package/types/document/data-type/extended-types/date-time-string.type.d.ts +1 -1
- package/types/document/data-type/extended-types/date-time.type.d.ts +1 -1
- package/types/document/data-type/extended-types/date.type.d.ts +1 -1
- package/types/document/data-type/extended-types/email.type.d.ts +1 -1
- package/types/document/data-type/extended-types/field-path.type.d.ts +3 -3
- package/types/document/data-type/extended-types/filter.type.d.ts +3 -3
- package/types/document/data-type/extended-types/object-id.type.d.ts +1 -1
- package/types/document/data-type/extended-types/operation-result.type.d.ts +2 -2
- package/types/document/data-type/extended-types/time.type.d.ts +1 -1
- package/types/document/data-type/extended-types/url.type.d.ts +1 -1
- package/types/document/data-type/extended-types/uuid.type.d.ts +1 -1
- package/types/document/data-type/mapped-type.d.ts +3 -3
- package/types/document/data-type/mixin-type.d.ts +1 -1
- package/types/document/data-type/omit-type.d.ts +1 -7
- package/types/document/data-type/partial-type.d.ts +1 -7
- package/types/document/data-type/pick-type.d.ts +3 -3
- package/types/document/data-type/primitive-types/any.type.d.ts +1 -1
- package/types/document/data-type/primitive-types/bigint.type.d.ts +1 -1
- package/types/document/data-type/primitive-types/boolean.type.d.ts +1 -1
- package/types/document/data-type/primitive-types/integer.type.d.ts +1 -1
- package/types/document/data-type/primitive-types/null.type.d.ts +1 -1
- package/types/document/data-type/primitive-types/number.type.d.ts +1 -1
- package/types/document/data-type/primitive-types/string.type.d.ts +1 -1
- package/types/document/data-type/required-type.d.ts +8 -8
- package/types/document/data-type/simple-type.d.ts +2 -2
- package/types/document/data-type/utils/create-mapped-class.d.ts +2 -2
- package/types/document/decorators/api-field-decorator.d.ts +1 -1
- package/types/document/decorators/http-controller.decorator.d.ts +3 -3
- package/types/document/decorators/http-operation-entity.decorator.d.ts +5 -4
- package/types/document/decorators/http-operation.decorator.d.ts +1 -1
- package/types/document/factory/api-document.factory.d.ts +2 -1
- package/types/document/factory/data-type.factory.d.ts +1 -1
- package/types/document/factory/http-api.factory.d.ts +1 -1
- package/types/document/http/http-api.d.ts +2 -2
- package/types/document/http/http-controller.d.ts +1 -1
- package/types/document/http/http-media-type.d.ts +3 -2
- package/types/document/http/http-multipart-field.d.ts +1 -2
- package/types/document/http/http-operation-response.d.ts +1 -1
- package/types/document/http/http-operation.d.ts +6 -5
- package/types/document/http/http-parameter.d.ts +2 -2
- package/types/document/http/http-request-body.d.ts +1 -1
- package/types/document/http/http-status-range.d.ts +2 -1
- package/types/exception/http-errors/bad-request.error.d.ts +1 -1
- package/types/exception/http-errors/conflict.error.d.ts +1 -1
- package/types/exception/http-errors/failed-dependency.error.d.ts +1 -1
- package/types/exception/http-errors/forbidden.error.d.ts +1 -1
- package/types/exception/http-errors/internal-server.error.d.ts +1 -1
- package/types/exception/http-errors/method-not-allowed.error.d.ts +1 -1
- package/types/exception/http-errors/not-acceptable.error.d.ts +1 -1
- package/types/exception/http-errors/not-found.error.d.ts +1 -1
- package/types/exception/http-errors/permission.error.d.ts +1 -1
- package/types/exception/http-errors/unauthorized.error.d.ts +1 -1
- package/types/exception/http-errors/unprocessable-entity.error.d.ts +1 -1
- package/types/exception/opra-exception.d.ts +1 -1
- package/types/exception/opra-http-error.d.ts +1 -1
- package/types/filter/antlr/OpraFilterParser.d.ts +1 -1
- package/types/filter/ast/expressions/comparison-expression.d.ts +1 -1
- package/types/filter/errors.d.ts +3 -4
- package/types/filter/filter-rules.d.ts +5 -5
- package/types/filter/opra-error-listener.d.ts +1 -2
- package/types/helpers/function-utils.d.ts +1 -1
- package/types/helpers/index.d.ts +1 -0
- package/types/helpers/mixin-utils.d.ts +1 -1
- package/types/helpers/object-utils.d.ts +1 -1
- package/types/helpers/safe-json-stringify.d.ts +1 -0
- package/types/helpers/type-guards.d.ts +1 -3
- package/types/i18n/i18n.d.ts +2 -2
- package/types/i18n/translate.d.ts +1 -1
- package/types/index.d.cts +9 -0
- package/types/schema/{document.interface.d.ts → api-document.interface.d.ts} +4 -4
- package/types/schema/data-type/complex-type.interface.d.ts +1 -1
- package/types/schema/data-type/data-type.interface.d.ts +1 -1
- package/types/schema/data-type/enum-type.interface.d.ts +1 -1
- package/types/schema/data-type/mapped-type.interface.d.ts +3 -3
- package/types/schema/data-type/mixin-type.interface.d.ts +1 -1
- package/types/schema/data-type-container.interface.d.ts +1 -1
- package/types/schema/http/http-controller.interface.d.ts +2 -2
- package/types/schema/http/http-media-type.interface.d.ts +1 -1
- package/types/schema/http/http-operation-response.interface.d.ts +2 -2
- package/types/schema/http/http-operation.interface.d.ts +8 -4
- package/types/schema/http/http-parameter.interface.d.ts +2 -2
- package/types/schema/index.d.ts +2 -62
- package/types/schema/opra-schema.d.ts +21 -0
- package/types/schema/type-guards.d.ts +1 -1
- package/browser.js +0 -13393
- /package/cjs/schema/{document.interface.js → api-document.interface.js} +0 -0
- /package/esm/schema/{document.interface.js → api-document.interface.js} +0 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { FilterRules } from '../../filter/filter-rules.js';
|
|
2
|
-
import { omitUndefined } from '../../helpers/index.js';
|
|
3
2
|
import { HttpStatusCode, MimeTypes } from '../../http/index.js';
|
|
4
3
|
import { DATATYPE_METADATA } from '../constants.js';
|
|
5
4
|
import { FieldPathType, FilterType } from '../data-type/extended-types/index.js';
|
|
@@ -20,7 +19,7 @@ HttpOperation.Entity.Create = function (arg0, arg1) {
|
|
|
20
19
|
args = { ...arg1, type: arg0 };
|
|
21
20
|
/** Initialize the decorator and the chain */
|
|
22
21
|
const decoratorChain = [];
|
|
23
|
-
const decorator = HttpOperationDecoratorFactory(decoratorChain,
|
|
22
|
+
const decorator = HttpOperationDecoratorFactory(decoratorChain, {
|
|
24
23
|
method: 'POST',
|
|
25
24
|
...args,
|
|
26
25
|
composition: 'Entity.Create',
|
|
@@ -29,7 +28,7 @@ HttpOperation.Entity.Create = function (arg0, arg1) {
|
|
|
29
28
|
...args.requestBody,
|
|
30
29
|
required: true,
|
|
31
30
|
},
|
|
32
|
-
})
|
|
31
|
+
});
|
|
33
32
|
decorator
|
|
34
33
|
.QueryParam('projection', {
|
|
35
34
|
description: 'Determines fields projection',
|
|
@@ -51,8 +50,6 @@ HttpOperation.Entity.Create = function (arg0, arg1) {
|
|
|
51
50
|
description: 'The request was well-formed but was unable to process operation due to one or many errors.',
|
|
52
51
|
contentType: MimeTypes.opra_response_json,
|
|
53
52
|
});
|
|
54
|
-
if (typeof args.type === 'function')
|
|
55
|
-
decorator.UseType(args.type);
|
|
56
53
|
decoratorChain.push((operationMeta) => {
|
|
57
54
|
const compositionOptions = (operationMeta.compositionOptions = operationMeta.compositionOptions || {});
|
|
58
55
|
compositionOptions.type = getDataTypeName(args.type);
|
|
@@ -71,11 +68,11 @@ HttpOperation.Entity.Delete = function (arg0, arg1) {
|
|
|
71
68
|
args = { ...arg1, type: arg0 };
|
|
72
69
|
/** Initialize the decorator and the chain */
|
|
73
70
|
const decoratorChain = [];
|
|
74
|
-
const decorator = HttpOperationDecoratorFactory(decoratorChain,
|
|
71
|
+
const decorator = HttpOperationDecoratorFactory(decoratorChain, {
|
|
75
72
|
method: 'DELETE',
|
|
76
73
|
...args,
|
|
77
74
|
composition: 'Entity.Delete',
|
|
78
|
-
})
|
|
75
|
+
});
|
|
79
76
|
decorator
|
|
80
77
|
.Response(HttpStatusCode.OK, {
|
|
81
78
|
description: 'Operation is successful. Returns OperationResult with "affected" field.',
|
|
@@ -85,8 +82,6 @@ HttpOperation.Entity.Delete = function (arg0, arg1) {
|
|
|
85
82
|
description: 'The request was well-formed but was unable to process operation due to one or many errors.',
|
|
86
83
|
contentType: MimeTypes.opra_response_json,
|
|
87
84
|
});
|
|
88
|
-
if (typeof args.type === 'function')
|
|
89
|
-
decorator.UseType(args.type);
|
|
90
85
|
/**
|
|
91
86
|
*
|
|
92
87
|
*/
|
|
@@ -108,6 +103,7 @@ HttpOperation.Entity.Delete = function (arg0, arg1) {
|
|
|
108
103
|
decoratorChain.push((meta) => {
|
|
109
104
|
if (!meta.path?.includes(':' + name))
|
|
110
105
|
meta.path = (meta.path || '') + '@:' + name;
|
|
106
|
+
meta.mergePath = true;
|
|
111
107
|
});
|
|
112
108
|
return decorator;
|
|
113
109
|
};
|
|
@@ -132,11 +128,11 @@ HttpOperation.Entity.DeleteMany = function (arg0, arg1) {
|
|
|
132
128
|
const filterRules = new FilterRules();
|
|
133
129
|
const filterType = new FilterType({ dataType: args.type });
|
|
134
130
|
filterType.rules = {};
|
|
135
|
-
const decorator = HttpOperationDecoratorFactory(decoratorChain,
|
|
131
|
+
const decorator = HttpOperationDecoratorFactory(decoratorChain, {
|
|
136
132
|
method: 'DELETE',
|
|
137
133
|
...args,
|
|
138
134
|
composition: 'Entity.DeleteMany',
|
|
139
|
-
})
|
|
135
|
+
});
|
|
140
136
|
decorator
|
|
141
137
|
.Response(HttpStatusCode.OK, {
|
|
142
138
|
description: 'Operation is successful. Returns OperationResult with "affected" field.',
|
|
@@ -150,8 +146,6 @@ HttpOperation.Entity.DeleteMany = function (arg0, arg1) {
|
|
|
150
146
|
type: filterType,
|
|
151
147
|
description: 'Determines filter fields',
|
|
152
148
|
});
|
|
153
|
-
if (typeof args.type === 'function')
|
|
154
|
-
decorator.UseType(args.type);
|
|
155
149
|
decoratorChain.push((operationMeta) => {
|
|
156
150
|
const compositionOptions = (operationMeta.compositionOptions = operationMeta.compositionOptions || {});
|
|
157
151
|
compositionOptions.type = getDataTypeName(args.type);
|
|
@@ -180,11 +174,11 @@ HttpOperation.Entity.FindMany = function (arg0, arg1) {
|
|
|
180
174
|
const filterRules = new FilterRules();
|
|
181
175
|
const filterType = new FilterType({ dataType: args.type });
|
|
182
176
|
filterType.rules = {};
|
|
183
|
-
const decorator = HttpOperationDecoratorFactory(decoratorChain,
|
|
177
|
+
const decorator = HttpOperationDecoratorFactory(decoratorChain, {
|
|
184
178
|
method: 'GET',
|
|
185
179
|
...args,
|
|
186
180
|
composition: 'Entity.FindMany',
|
|
187
|
-
})
|
|
181
|
+
});
|
|
188
182
|
decorator
|
|
189
183
|
.Response(HttpStatusCode.OK, {
|
|
190
184
|
description: 'Operation is successful. Returns OperationResult with "payload" field that contains list of resources.',
|
|
@@ -199,7 +193,7 @@ HttpOperation.Entity.FindMany = function (arg0, arg1) {
|
|
|
199
193
|
})
|
|
200
194
|
.QueryParam('limit', {
|
|
201
195
|
description: 'Determines number of returning instances',
|
|
202
|
-
type: new IntegerType({ minValue: 1 }),
|
|
196
|
+
type: new IntegerType({ minValue: 1, maxValue: args.maxLimit }),
|
|
203
197
|
})
|
|
204
198
|
.QueryParam('skip', {
|
|
205
199
|
description: 'Determines number of returning instances',
|
|
@@ -231,11 +225,15 @@ HttpOperation.Entity.FindMany = function (arg0, arg1) {
|
|
|
231
225
|
isArray: true,
|
|
232
226
|
arraySeparator: ',',
|
|
233
227
|
});
|
|
234
|
-
if (typeof args.type === 'function')
|
|
235
|
-
decorator.UseType(args.type);
|
|
236
228
|
decoratorChain.push((operationMeta) => {
|
|
237
229
|
const compositionOptions = (operationMeta.compositionOptions = operationMeta.compositionOptions || {});
|
|
238
230
|
compositionOptions.type = getDataTypeName(args.type);
|
|
231
|
+
if (args.defaultLimit)
|
|
232
|
+
compositionOptions.defaultLimit = args.defaultLimit;
|
|
233
|
+
if (args.defaultProjection)
|
|
234
|
+
compositionOptions.defaultProjection = args.defaultProjection;
|
|
235
|
+
if (args.maxLimit)
|
|
236
|
+
compositionOptions.maxLimit = args.maxLimit;
|
|
239
237
|
});
|
|
240
238
|
decorator.DefaultSort = (...fields) => {
|
|
241
239
|
decoratorChain.push((operationMeta) => {
|
|
@@ -272,11 +270,11 @@ HttpOperation.Entity.Get = function (arg0, arg1) {
|
|
|
272
270
|
args = { ...arg1, type: arg0 };
|
|
273
271
|
/** Initialize the decorator and the chain */
|
|
274
272
|
const decoratorChain = [];
|
|
275
|
-
const decorator = HttpOperationDecoratorFactory(decoratorChain,
|
|
273
|
+
const decorator = HttpOperationDecoratorFactory(decoratorChain, {
|
|
276
274
|
method: 'GET',
|
|
277
275
|
...args,
|
|
278
276
|
composition: 'Entity.Get',
|
|
279
|
-
})
|
|
277
|
+
});
|
|
280
278
|
decorator
|
|
281
279
|
.QueryParam('projection', {
|
|
282
280
|
description: 'Determines fields projection',
|
|
@@ -300,8 +298,6 @@ HttpOperation.Entity.Get = function (arg0, arg1) {
|
|
|
300
298
|
description: 'The request was well-formed but was unable to process operation due to one or many errors.',
|
|
301
299
|
contentType: MimeTypes.opra_response_json,
|
|
302
300
|
});
|
|
303
|
-
if (typeof args.type === 'function')
|
|
304
|
-
decorator.UseType(args.type);
|
|
305
301
|
/**
|
|
306
302
|
*
|
|
307
303
|
*/
|
|
@@ -323,6 +319,7 @@ HttpOperation.Entity.Get = function (arg0, arg1) {
|
|
|
323
319
|
decoratorChain.push((meta) => {
|
|
324
320
|
if (!meta.path?.includes(':' + name))
|
|
325
321
|
meta.path = (meta.path || '') + '@:' + name;
|
|
322
|
+
meta.mergePath = true;
|
|
326
323
|
});
|
|
327
324
|
return decorator;
|
|
328
325
|
};
|
|
@@ -347,7 +344,7 @@ HttpOperation.Entity.UpdateMany = function (arg0, arg1) {
|
|
|
347
344
|
const filterType = new FilterType({ dataType: args.type });
|
|
348
345
|
filterType.rules = {};
|
|
349
346
|
const filterRules = new FilterRules();
|
|
350
|
-
const decorator = HttpOperationDecoratorFactory(decoratorChain,
|
|
347
|
+
const decorator = HttpOperationDecoratorFactory(decoratorChain, {
|
|
351
348
|
method: 'PATCH',
|
|
352
349
|
...args,
|
|
353
350
|
composition: 'Entity.UpdateMany',
|
|
@@ -357,11 +354,9 @@ HttpOperation.Entity.UpdateMany = function (arg0, arg1) {
|
|
|
357
354
|
...args.requestBody,
|
|
358
355
|
required: true,
|
|
359
356
|
},
|
|
360
|
-
})
|
|
361
|
-
decorator.RequestContent(args.requestBody?.type || args.type);
|
|
362
|
-
if (typeof args.type === 'function')
|
|
363
|
-
decorator.UseType(args.type);
|
|
357
|
+
});
|
|
364
358
|
decorator
|
|
359
|
+
.RequestContent(args.requestBody?.type || args.type)
|
|
365
360
|
.Response(HttpStatusCode.OK, {
|
|
366
361
|
description: 'Operation is successful. Returns OperationResult with "affected" field.',
|
|
367
362
|
contentType: MimeTypes.opra_response_json,
|
|
@@ -402,7 +397,7 @@ HttpOperation.Entity.Update = function (arg0, arg1) {
|
|
|
402
397
|
const filterRules = new FilterRules();
|
|
403
398
|
const filterType = new FilterType({ dataType: args.type });
|
|
404
399
|
filterType.rules = {};
|
|
405
|
-
const decorator = HttpOperationDecoratorFactory(decoratorChain,
|
|
400
|
+
const decorator = HttpOperationDecoratorFactory(decoratorChain, {
|
|
406
401
|
method: 'PATCH',
|
|
407
402
|
...args,
|
|
408
403
|
composition: 'Entity.Update',
|
|
@@ -412,7 +407,7 @@ HttpOperation.Entity.Update = function (arg0, arg1) {
|
|
|
412
407
|
...args.requestBody,
|
|
413
408
|
required: true,
|
|
414
409
|
},
|
|
415
|
-
})
|
|
410
|
+
});
|
|
416
411
|
decorator
|
|
417
412
|
.QueryParam('projection', {
|
|
418
413
|
description: 'Determines fields projection',
|
|
@@ -441,8 +436,6 @@ HttpOperation.Entity.Update = function (arg0, arg1) {
|
|
|
441
436
|
description: 'The request was well-formed but was unable to process operation due to one or many errors.',
|
|
442
437
|
contentType: MimeTypes.opra_response_json,
|
|
443
438
|
});
|
|
444
|
-
if (typeof args.type === 'function')
|
|
445
|
-
decorator.UseType(args.type);
|
|
446
439
|
/**
|
|
447
440
|
*
|
|
448
441
|
*/
|
|
@@ -464,6 +457,7 @@ HttpOperation.Entity.Update = function (arg0, arg1) {
|
|
|
464
457
|
decoratorChain.push((meta) => {
|
|
465
458
|
if (!meta.path?.includes(':' + name))
|
|
466
459
|
meta.path = (meta.path || '') + '@:' + name;
|
|
460
|
+
meta.mergePath = true;
|
|
467
461
|
});
|
|
468
462
|
return decorator;
|
|
469
463
|
};
|
|
@@ -114,6 +114,9 @@ export function HttpOperationDecoratorFactory(decoratorChain, options) {
|
|
|
114
114
|
responseMeta.contentType = responseMeta.contentType || MimeTypes.opra_response_json;
|
|
115
115
|
responseMeta.contentEncoding = responseMeta.contentEncoding || 'utf-8';
|
|
116
116
|
}
|
|
117
|
+
if (responseMeta.contentType === MimeTypes.opra_response_json) {
|
|
118
|
+
responseMeta.contentEncoding = responseMeta.contentEncoding || 'utf-8';
|
|
119
|
+
}
|
|
117
120
|
decoratorChain.push((meta) => {
|
|
118
121
|
meta.responses = meta.responses || [];
|
|
119
122
|
meta.responses.push(responseMeta);
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import crypto from 'node:crypto';
|
|
2
|
-
import { asMutable } from 'ts-gems';
|
|
3
1
|
import { resolveThunk } from '../../helpers/index.js';
|
|
4
2
|
import { OpraSchema } from '../../schema/index.js';
|
|
5
3
|
import { ApiDocument } from '../api-document.js';
|
|
@@ -15,6 +13,9 @@ const OPRA_SPEC_URL = 'https://oprajs.com/spec/v' + OpraSchema.SpecVersion;
|
|
|
15
13
|
* @class ApiDocumentFactory
|
|
16
14
|
*/
|
|
17
15
|
export class ApiDocumentFactory {
|
|
16
|
+
constructor() {
|
|
17
|
+
this._allDocuments = {};
|
|
18
|
+
}
|
|
18
19
|
/**
|
|
19
20
|
* Creates ApiDocument instance from given schema object
|
|
20
21
|
*/
|
|
@@ -64,9 +65,14 @@ export class ApiDocumentFactory {
|
|
|
64
65
|
else
|
|
65
66
|
init = schemaOrUrl;
|
|
66
67
|
// Add builtin data types if this document is the root
|
|
68
|
+
let builtinDocument;
|
|
67
69
|
if (!document[BUILTIN]) {
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
+
const t = document.node.findDataType('string');
|
|
71
|
+
builtinDocument = t?.node.getDocument();
|
|
72
|
+
if (!builtinDocument) {
|
|
73
|
+
builtinDocument = await this.createBuiltinDocument(context);
|
|
74
|
+
document.references.set('opra', builtinDocument);
|
|
75
|
+
}
|
|
70
76
|
}
|
|
71
77
|
init.spec = init.spec || OpraSchema.SpecVersion;
|
|
72
78
|
document.url = init.url;
|
|
@@ -87,8 +93,10 @@ export class ApiDocumentFactory {
|
|
|
87
93
|
return;
|
|
88
94
|
}
|
|
89
95
|
const refDoc = new ApiDocument();
|
|
96
|
+
if (builtinDocument)
|
|
97
|
+
refDoc.references.set('opra', builtinDocument);
|
|
90
98
|
await this.initDocument(refDoc, context, r);
|
|
91
|
-
document.references.set(ns, refDoc);
|
|
99
|
+
document.references.set(ns, this._allDocuments[refDoc.id]);
|
|
92
100
|
});
|
|
93
101
|
}
|
|
94
102
|
});
|
|
@@ -109,8 +117,10 @@ export class ApiDocumentFactory {
|
|
|
109
117
|
context.addError(`Unknown service protocol (${init.api.protocol})`);
|
|
110
118
|
});
|
|
111
119
|
}
|
|
112
|
-
|
|
113
|
-
|
|
120
|
+
document.invalidate();
|
|
121
|
+
/** Add document to global registry */
|
|
122
|
+
if (!this._allDocuments[document.id])
|
|
123
|
+
this._allDocuments[document.id] = document;
|
|
114
124
|
}
|
|
115
125
|
/**
|
|
116
126
|
*
|
|
@@ -7,7 +7,6 @@ import { HttpController } from './http-controller.js';
|
|
|
7
7
|
export class HttpApi extends ApiBase {
|
|
8
8
|
constructor(owner) {
|
|
9
9
|
super(owner);
|
|
10
|
-
this.owner = owner;
|
|
11
10
|
// noinspection JSUnusedGlobalSymbols
|
|
12
11
|
this._controllerReverseMap = new WeakMap();
|
|
13
12
|
this.protocol = 'http';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import nodePath from 'node:path';
|
|
1
2
|
import { asMutable } from 'ts-gems';
|
|
2
3
|
import { omitUndefined, ResponsiveMap } from '../../helpers/index.js';
|
|
3
4
|
import { OpraSchema } from '../../schema/index.js';
|
|
@@ -26,7 +27,7 @@ export const HttpController = function (...args) {
|
|
|
26
27
|
_this.parameters = [];
|
|
27
28
|
_this.name = initArgs.name;
|
|
28
29
|
_this.description = initArgs.description;
|
|
29
|
-
_this.path = initArgs.path
|
|
30
|
+
_this.path = initArgs.path ?? initArgs.name;
|
|
30
31
|
_this.instance = initArgs.instance;
|
|
31
32
|
_this.ctor = initArgs.ctor;
|
|
32
33
|
_this._controllerReverseMap = new WeakMap();
|
|
@@ -97,7 +98,7 @@ class HttpControllerClass extends DocumentElement {
|
|
|
97
98
|
}
|
|
98
99
|
}
|
|
99
100
|
getFullUrl() {
|
|
100
|
-
return (this.owner instanceof HttpController ? this.owner.getFullUrl() : '/'
|
|
101
|
+
return nodePath.posix.join(this.owner instanceof HttpController ? this.owner.getFullUrl() : '/', this.path);
|
|
101
102
|
}
|
|
102
103
|
/**
|
|
103
104
|
*
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import typeIs from '@browsery/type-is';
|
|
1
2
|
import { asMutable } from 'ts-gems';
|
|
3
|
+
import { isAny, vg } from 'valgen';
|
|
2
4
|
import { omitUndefined } from '../../helpers/index.js';
|
|
3
5
|
import { DocumentElement } from '../common/document-element.js';
|
|
4
6
|
import { DataType } from '../data-type/data-type.js';
|
|
@@ -21,7 +23,6 @@ export const HttpMediaType = function (owner, initArgs) {
|
|
|
21
23
|
_this.maxFiles = initArgs.maxFiles;
|
|
22
24
|
_this.maxFileSize = initArgs.maxFileSize;
|
|
23
25
|
_this.maxTotalFileSize = initArgs.maxTotalFileSize;
|
|
24
|
-
_this.minFileSize = initArgs.minFileSize;
|
|
25
26
|
if (initArgs?.type) {
|
|
26
27
|
_this.type = initArgs?.type instanceof DataType ? initArgs.type : _this.owner.node.getDataType(initArgs.type);
|
|
27
28
|
}
|
|
@@ -56,12 +57,25 @@ class HttpMediaTypeClass extends DocumentElement {
|
|
|
56
57
|
maxFiles: this.maxFiles,
|
|
57
58
|
maxFileSize: this.maxFileSize,
|
|
58
59
|
maxTotalFileSize: this.maxTotalFileSize,
|
|
59
|
-
minFileSize: this.minFileSize,
|
|
60
60
|
});
|
|
61
61
|
if (this.multipartFields?.length) {
|
|
62
62
|
out.multipartFields = this.multipartFields.map(x => x.toJSON());
|
|
63
63
|
}
|
|
64
64
|
return out;
|
|
65
65
|
}
|
|
66
|
+
generateCodec(codec, options) {
|
|
67
|
+
let fn;
|
|
68
|
+
if (this.type) {
|
|
69
|
+
fn = this.type.generateCodec(codec, options);
|
|
70
|
+
}
|
|
71
|
+
else if (this.contentType) {
|
|
72
|
+
const arr = Array.isArray(this.contentType) ? this.contentType : [this.contentType];
|
|
73
|
+
if (arr.find(ct => typeIs.is(ct, ['json']))) {
|
|
74
|
+
fn = this.node.findDataType('object').generateCodec(codec);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
fn = fn || isAny;
|
|
78
|
+
return this.isArray ? vg.isArray(fn) : fn;
|
|
79
|
+
}
|
|
66
80
|
}
|
|
67
81
|
HttpMediaType.prototype = HttpMediaTypeClass.prototype;
|
|
@@ -8,7 +8,6 @@ import { HttpMediaType } from './http-media-type.js';
|
|
|
8
8
|
export class HttpMultipartField extends HttpMediaType {
|
|
9
9
|
constructor(owner, initArgs) {
|
|
10
10
|
super(owner, initArgs);
|
|
11
|
-
this.owner = owner;
|
|
12
11
|
this.fieldName =
|
|
13
12
|
initArgs.fieldName instanceof RegExp
|
|
14
13
|
? initArgs.fieldName
|
|
@@ -7,7 +7,6 @@ import { HttpStatusRange } from './http-status-range.js';
|
|
|
7
7
|
export class HttpOperationResponse extends HttpMediaType {
|
|
8
8
|
constructor(owner, init) {
|
|
9
9
|
super(owner, init);
|
|
10
|
-
this.owner = owner;
|
|
11
10
|
this.parameters = [];
|
|
12
11
|
this.statusCode = (Array.isArray(init.statusCode) ? init.statusCode : [init.statusCode]).map(x => typeof x === 'object' ? new HttpStatusRange(x.start, x.end) : new HttpStatusRange(x));
|
|
13
12
|
this.partial = init.partial;
|
|
@@ -27,6 +27,7 @@ export const HttpOperation = function (...args) {
|
|
|
27
27
|
_this.types = _this.node[kDataTypeMap] = new DataTypeMap();
|
|
28
28
|
_this.name = initArgs.name;
|
|
29
29
|
_this.path = initArgs.path;
|
|
30
|
+
_this.mergePath = initArgs.mergePath;
|
|
30
31
|
_this.method = initArgs.method || 'GET';
|
|
31
32
|
_this.description = initArgs.description;
|
|
32
33
|
_this.composition = initArgs.composition;
|
|
@@ -53,13 +54,23 @@ class HttpOperationClass extends DocumentElement {
|
|
|
53
54
|
}
|
|
54
55
|
getFullUrl() {
|
|
55
56
|
const out = this.owner.getFullUrl();
|
|
56
|
-
|
|
57
|
+
if (out) {
|
|
58
|
+
if (this.path) {
|
|
59
|
+
if (this.mergePath)
|
|
60
|
+
return out + this.path;
|
|
61
|
+
return nodePath.posix.join(out, this.path);
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
return this.path || '/';
|
|
57
66
|
}
|
|
58
67
|
toJSON() {
|
|
59
68
|
const out = omitUndefined({
|
|
60
69
|
kind: OpraSchema.HttpOperation.Kind,
|
|
61
70
|
description: this.description,
|
|
62
71
|
method: this.method,
|
|
72
|
+
path: this.path,
|
|
73
|
+
mergePath: this.mergePath,
|
|
63
74
|
composition: this.composition,
|
|
64
75
|
requestBody: this.requestBody?.toJSON(),
|
|
65
76
|
});
|
|
@@ -21,6 +21,8 @@ export const HttpParameter = function (owner, initArgs) {
|
|
|
21
21
|
_this.location = initArgs.location;
|
|
22
22
|
_this.deprecated = initArgs.deprecated;
|
|
23
23
|
_this.required = initArgs.required;
|
|
24
|
+
if (_this.required == null && initArgs.location === 'path')
|
|
25
|
+
_this.required = true;
|
|
24
26
|
_this.arraySeparator = initArgs.arraySeparator;
|
|
25
27
|
_this.keyParam = initArgs.keyParam;
|
|
26
28
|
};
|
|
@@ -22,8 +22,11 @@ export class HttpStatusRange {
|
|
|
22
22
|
this.end = m[2] ? parseInt(m[2], 10) : this.start;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
return this.
|
|
25
|
+
includes(statusCode) {
|
|
26
|
+
return statusCode >= this.start && statusCode <= this.end;
|
|
27
|
+
}
|
|
28
|
+
intersects(start, end) {
|
|
29
|
+
return end >= this.start && start <= this.end;
|
|
27
30
|
}
|
|
28
31
|
toString() {
|
|
29
32
|
if (this.start === this.end)
|
|
@@ -6,6 +6,7 @@ import { i18n } from '../i18n/index.js';
|
|
|
6
6
|
export class OpraException extends Error {
|
|
7
7
|
constructor(issue, cause) {
|
|
8
8
|
super('Unknown error');
|
|
9
|
+
this.severity = 'error';
|
|
9
10
|
cause = cause || (issue instanceof Error ? issue : undefined);
|
|
10
11
|
if (issue instanceof Error)
|
|
11
12
|
cause = issue;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { OpraException } from '../exception/index.js';
|
|
2
|
-
import { OpraFilter } from '../filter/index.js';
|
|
3
2
|
import { omitUndefined, ResponsiveMap } from '../helpers/index.js';
|
|
4
3
|
import { translate } from '../i18n/index.js';
|
|
4
|
+
import { ArithmeticExpression, ArrayExpression, ComparisonExpression, LogicalExpression, ParenthesizedExpression, QualifiedIdentifier, } from './ast/index.js';
|
|
5
|
+
import { parse } from './parse.js';
|
|
5
6
|
export class FilterRules {
|
|
6
7
|
constructor(rules, options) {
|
|
7
8
|
this._rules = new ResponsiveMap();
|
|
@@ -27,10 +28,10 @@ export class FilterRules {
|
|
|
27
28
|
normalizeFilter(filter, dataType) {
|
|
28
29
|
if (!filter)
|
|
29
30
|
return;
|
|
30
|
-
const ast = typeof filter === 'string' ?
|
|
31
|
-
if (ast instanceof
|
|
31
|
+
const ast = typeof filter === 'string' ? parse(filter) : filter;
|
|
32
|
+
if (ast instanceof ComparisonExpression) {
|
|
32
33
|
this.normalizeFilter(ast.left, dataType);
|
|
33
|
-
if (!(ast.left instanceof
|
|
34
|
+
if (!(ast.left instanceof QualifiedIdentifier && ast.left.field)) {
|
|
34
35
|
throw new TypeError(`Invalid filter query. Left side should be a data field.`);
|
|
35
36
|
}
|
|
36
37
|
// Check if filtering accepted for given field
|
|
@@ -59,23 +60,23 @@ export class FilterRules {
|
|
|
59
60
|
this.normalizeFilter(ast.right, dataType);
|
|
60
61
|
return ast;
|
|
61
62
|
}
|
|
62
|
-
if (ast instanceof
|
|
63
|
+
if (ast instanceof LogicalExpression) {
|
|
63
64
|
ast.items.forEach(item => this.normalizeFilter(item, dataType));
|
|
64
65
|
return ast;
|
|
65
66
|
}
|
|
66
|
-
if (ast instanceof
|
|
67
|
+
if (ast instanceof ArithmeticExpression) {
|
|
67
68
|
ast.items.forEach(item => this.normalizeFilter(item.expression, dataType));
|
|
68
69
|
return ast;
|
|
69
70
|
}
|
|
70
|
-
if (ast instanceof
|
|
71
|
+
if (ast instanceof ArrayExpression) {
|
|
71
72
|
ast.items.forEach(item => this.normalizeFilter(item, dataType));
|
|
72
73
|
return ast;
|
|
73
74
|
}
|
|
74
|
-
if (ast instanceof
|
|
75
|
+
if (ast instanceof ParenthesizedExpression) {
|
|
75
76
|
this.normalizeFilter(ast.expression, dataType);
|
|
76
77
|
return ast;
|
|
77
78
|
}
|
|
78
|
-
if (ast instanceof
|
|
79
|
+
if (ast instanceof QualifiedIdentifier && dataType) {
|
|
79
80
|
ast.value = dataType.normalizeFieldPath(ast.value);
|
|
80
81
|
ast.field = dataType.getField(ast.value);
|
|
81
82
|
ast.dataType = ast.field.type;
|
package/esm/helpers/index.js
CHANGED
|
@@ -4,10 +4,10 @@ import { DATATYPE_METADATA } from '../document/constants.js';
|
|
|
4
4
|
export function cloneObject(obj, jsonOnly) {
|
|
5
5
|
return merge({}, obj, {
|
|
6
6
|
deep: v => isPlainObject(v) && !v[DATATYPE_METADATA],
|
|
7
|
+
descriptor: true,
|
|
7
8
|
filter: (source, key) => {
|
|
8
9
|
const v = source[key];
|
|
9
|
-
return (
|
|
10
|
-
(typeof v !== 'function' && (typeof v !== 'object' || isPlainObject(v) || Array.isArray(v))));
|
|
10
|
+
return !jsonOnly || (typeof v !== 'function' && (typeof v !== 'object' || isPlainObject(v) || Array.isArray(v)));
|
|
11
11
|
},
|
|
12
12
|
});
|
|
13
13
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function safeJsonStringify(value, replacer, space) {
|
|
2
|
+
const seen = new WeakSet();
|
|
3
|
+
return JSON.stringify(value, (k, v) => {
|
|
4
|
+
if (v !== null && typeof v === 'object') {
|
|
5
|
+
if (seen.has(v))
|
|
6
|
+
return;
|
|
7
|
+
seen.add(v);
|
|
8
|
+
}
|
|
9
|
+
if (replacer)
|
|
10
|
+
return replacer(k, v);
|
|
11
|
+
return v;
|
|
12
|
+
}, space);
|
|
13
|
+
}
|
package/esm/package.json
ADDED
package/esm/schema/index.js
CHANGED
|
@@ -1,27 +1,2 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
|
|
3
|
-
import * as enumType_ from './data-type/enum-type.interface.js';
|
|
4
|
-
import * as mappedType_ from './data-type/mapped-type.interface.js';
|
|
5
|
-
import * as mixinType_ from './data-type/mixin-type.interface.js';
|
|
6
|
-
import * as simpleType_ from './data-type/simple-type.interface.js';
|
|
7
|
-
import * as controller_ from './http/http-controller.interface.js';
|
|
8
|
-
import * as operation_ from './http/http-operation.interface.js';
|
|
9
|
-
import * as typeGuards_ from './type-guards.js';
|
|
10
|
-
export var OpraSchema;
|
|
11
|
-
(function (OpraSchema) {
|
|
12
|
-
OpraSchema.SpecVersion = constants_.SpecVersion;
|
|
13
|
-
OpraSchema.ComplexType = complexType_.ComplexType;
|
|
14
|
-
OpraSchema.EnumType = enumType_.EnumType;
|
|
15
|
-
OpraSchema.MappedType = mappedType_.MappedType;
|
|
16
|
-
OpraSchema.MixinType = mixinType_.MixinType;
|
|
17
|
-
OpraSchema.SimpleType = simpleType_.SimpleType;
|
|
18
|
-
OpraSchema.HttpController = controller_.HttpController;
|
|
19
|
-
OpraSchema.HttpOperation = operation_.HttpOperation;
|
|
20
|
-
OpraSchema.isComplexType = typeGuards_.isComplexType;
|
|
21
|
-
OpraSchema.isDataType = typeGuards_.isDataType;
|
|
22
|
-
OpraSchema.isSimpleType = typeGuards_.isSimpleType;
|
|
23
|
-
OpraSchema.isMixinType = typeGuards_.isMixinType;
|
|
24
|
-
OpraSchema.isMappedType = typeGuards_.isMappedType;
|
|
25
|
-
OpraSchema.isEnumType = typeGuards_.isEnumType;
|
|
26
|
-
OpraSchema.isHttpController = typeGuards_.isHttpController;
|
|
27
|
-
})(OpraSchema || (OpraSchema = {}));
|
|
1
|
+
import * as OpraSchema from './opra-schema.js';
|
|
2
|
+
export { OpraSchema };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export * from './api-document.interface.js';
|
|
2
|
+
export * from './constants.js';
|
|
3
|
+
export * from './data-type/complex-type.interface.js';
|
|
4
|
+
export * from './data-type/data-type.interface.js';
|
|
5
|
+
export * from './data-type/enum-type.interface.js';
|
|
6
|
+
export * from './data-type/field.interface.js';
|
|
7
|
+
export * from './data-type/mapped-type.interface.js';
|
|
8
|
+
export * from './data-type/mixin-type.interface.js';
|
|
9
|
+
export * from './data-type/simple-type.interface.js';
|
|
10
|
+
export * from './data-type-container.interface.js';
|
|
11
|
+
export * from './http/http-controller.interface.js';
|
|
12
|
+
export * from './http/http-media-type.interface.js';
|
|
13
|
+
export * from './http/http-multipart-field.interface.js';
|
|
14
|
+
export * from './http/http-operation.interface.js';
|
|
15
|
+
export * from './http/http-operation-response.interface.js';
|
|
16
|
+
export * from './http/http-parameter.interface.js';
|
|
17
|
+
export * from './http/http-request-body.interface.js';
|
|
18
|
+
export * from './http/http-status-range.interface.js';
|
|
19
|
+
export * from './type-guards.js';
|
|
20
|
+
export * from './types.js';
|
|
21
|
+
export * from './value.interface.js';
|