@opra/common 1.0.0-alpha.1 → 1.0.0-alpha.11

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.
Files changed (177) hide show
  1. package/browser.js +5535 -5248
  2. package/cjs/document/api-document.js +18 -12
  3. package/cjs/document/common/data-type-map.js +1 -1
  4. package/cjs/document/common/document-element.js +2 -1
  5. package/cjs/document/constants.js +1 -1
  6. package/cjs/document/data-type/api-field.js +7 -2
  7. package/cjs/document/data-type/complex-type-base.js +6 -1
  8. package/cjs/document/data-type/complex-type.js +8 -5
  9. package/cjs/document/data-type/data-type.js +2 -1
  10. package/cjs/document/data-type/enum-type.js +5 -2
  11. package/cjs/document/data-type/extended-types/base64.type.js +6 -1
  12. package/cjs/document/data-type/extended-types/date-string.type.js +10 -3
  13. package/cjs/document/data-type/extended-types/date-time-string.type.js +10 -3
  14. package/cjs/document/data-type/extended-types/date-time.type.js +10 -3
  15. package/cjs/document/data-type/extended-types/date.type.js +10 -3
  16. package/cjs/document/data-type/extended-types/email.type.js +24 -10
  17. package/cjs/document/data-type/extended-types/field-path.type.js +13 -7
  18. package/cjs/document/data-type/extended-types/filter.type.js +25 -20
  19. package/cjs/document/data-type/extended-types/object-id.type.js +6 -1
  20. package/cjs/document/data-type/extended-types/operation-result.type.js +20 -10
  21. package/cjs/document/data-type/extended-types/time.type.js +10 -3
  22. package/cjs/document/data-type/extended-types/url.type.js +6 -1
  23. package/cjs/document/data-type/extended-types/uuid.type.js +8 -2
  24. package/cjs/document/data-type/mapped-type.js +12 -5
  25. package/cjs/document/data-type/mixin-type.js +5 -1
  26. package/cjs/document/data-type/primitive-types/any.type.js +2 -1
  27. package/cjs/document/data-type/primitive-types/bigint.type.js +6 -1
  28. package/cjs/document/data-type/primitive-types/boolean.type.js +6 -1
  29. package/cjs/document/data-type/primitive-types/integer.type.js +6 -1
  30. package/cjs/document/data-type/primitive-types/null.type.js +6 -1
  31. package/cjs/document/data-type/primitive-types/number.type.js +10 -3
  32. package/cjs/document/data-type/primitive-types/object.type.js +2 -1
  33. package/cjs/document/data-type/primitive-types/string.type.js +14 -5
  34. package/cjs/document/data-type/simple-type.js +16 -10
  35. package/cjs/document/data-type/utils/create-mapped-class.js +2 -1
  36. package/cjs/document/decorators/http-controller.decorator.js +25 -0
  37. package/cjs/document/decorators/http-operation-entity.decorator.js +55 -19
  38. package/cjs/document/decorators/http-operation.decorator.js +8 -4
  39. package/cjs/document/factory/api-document.factory.js +6 -3
  40. package/cjs/document/factory/data-type.factory.js +98 -57
  41. package/cjs/document/factory/http-api.factory.js +4 -2
  42. package/cjs/document/http/http-api.js +2 -2
  43. package/cjs/document/http/http-controller.js +25 -13
  44. package/cjs/document/http/http-media-type.js +4 -2
  45. package/cjs/document/http/http-operation-response.js +2 -1
  46. package/cjs/document/http/http-operation.js +18 -4
  47. package/cjs/document/http/http-parameter.js +2 -0
  48. package/cjs/document/http/http-status-range.js +1 -2
  49. package/cjs/document/index.js +5 -5
  50. package/cjs/exception/index.js +5 -5
  51. package/cjs/filter/antlr/OpraFilterParser.js +28 -82
  52. package/cjs/filter/ast/index.js +1 -1
  53. package/cjs/filter/build.js +1 -3
  54. package/cjs/filter/filter-rules.js +4 -2
  55. package/cjs/filter/opra-filter.ns.js +2 -2
  56. package/cjs/filter/parse.js +1 -3
  57. package/cjs/helpers/mixin-utils.js +2 -1
  58. package/cjs/helpers/monkey-patches.js +4 -2
  59. package/cjs/helpers/parse-fields-projection.js +1 -3
  60. package/cjs/helpers/responsive-map.js +5 -4
  61. package/cjs/i18n/i18n.js +4 -3
  62. package/cjs/i18n/index.js +1 -1
  63. package/cjs/index.js +1 -1
  64. package/esm/document/api-document.js +18 -12
  65. package/esm/document/common/data-type-map.js +1 -1
  66. package/esm/document/common/document-element.js +2 -1
  67. package/esm/document/constants.js +1 -1
  68. package/esm/document/data-type/api-field.js +7 -2
  69. package/esm/document/data-type/complex-type-base.js +6 -1
  70. package/esm/document/data-type/complex-type.js +8 -5
  71. package/esm/document/data-type/data-type.js +2 -1
  72. package/esm/document/data-type/enum-type.js +5 -2
  73. package/esm/document/data-type/extended-types/base64.type.js +7 -2
  74. package/esm/document/data-type/extended-types/date-string.type.js +11 -4
  75. package/esm/document/data-type/extended-types/date-time-string.type.js +11 -4
  76. package/esm/document/data-type/extended-types/date-time.type.js +11 -4
  77. package/esm/document/data-type/extended-types/date.type.js +11 -4
  78. package/esm/document/data-type/extended-types/email.type.js +25 -11
  79. package/esm/document/data-type/extended-types/field-path.type.js +14 -8
  80. package/esm/document/data-type/extended-types/filter.type.js +26 -21
  81. package/esm/document/data-type/extended-types/object-id.type.js +7 -2
  82. package/esm/document/data-type/extended-types/operation-result.type.js +21 -11
  83. package/esm/document/data-type/extended-types/time.type.js +11 -4
  84. package/esm/document/data-type/extended-types/url.type.js +7 -2
  85. package/esm/document/data-type/extended-types/uuid.type.js +9 -3
  86. package/esm/document/data-type/mapped-type.js +12 -5
  87. package/esm/document/data-type/mixin-type.js +5 -1
  88. package/esm/document/data-type/primitive-types/any.type.js +3 -2
  89. package/esm/document/data-type/primitive-types/bigint.type.js +7 -2
  90. package/esm/document/data-type/primitive-types/boolean.type.js +7 -2
  91. package/esm/document/data-type/primitive-types/integer.type.js +7 -2
  92. package/esm/document/data-type/primitive-types/null.type.js +7 -2
  93. package/esm/document/data-type/primitive-types/number.type.js +11 -4
  94. package/esm/document/data-type/primitive-types/object.type.js +3 -2
  95. package/esm/document/data-type/primitive-types/string.type.js +15 -6
  96. package/esm/document/data-type/simple-type.js +16 -10
  97. package/esm/document/data-type/utils/create-mapped-class.js +2 -1
  98. package/esm/document/decorators/http-controller.decorator.js +25 -0
  99. package/esm/document/decorators/http-operation-entity.decorator.js +55 -19
  100. package/esm/document/decorators/http-operation.decorator.js +8 -4
  101. package/esm/document/factory/api-document.factory.js +5 -3
  102. package/esm/document/factory/data-type.factory.js +98 -57
  103. package/esm/document/factory/http-api.factory.js +4 -2
  104. package/esm/document/http/http-api.js +2 -2
  105. package/esm/document/http/http-controller.js +24 -13
  106. package/esm/document/http/http-media-type.js +4 -2
  107. package/esm/document/http/http-operation-response.js +2 -1
  108. package/esm/document/http/http-operation.js +17 -4
  109. package/esm/document/http/http-parameter.js +2 -0
  110. package/esm/document/http/http-status-range.js +1 -2
  111. package/esm/document/index.js +5 -5
  112. package/esm/exception/index.js +5 -5
  113. package/esm/filter/antlr/OpraFilterParser.js +28 -82
  114. package/esm/filter/ast/index.js +1 -1
  115. package/esm/filter/build.js +1 -3
  116. package/esm/filter/filter-rules.js +4 -2
  117. package/esm/filter/opra-filter.ns.js +2 -2
  118. package/esm/filter/parse.js +1 -3
  119. package/esm/helpers/mixin-utils.js +2 -1
  120. package/esm/helpers/monkey-patches.js +4 -2
  121. package/esm/helpers/parse-fields-projection.js +1 -3
  122. package/esm/helpers/responsive-map.js +5 -4
  123. package/esm/i18n/i18n.js +4 -3
  124. package/esm/i18n/index.js +1 -1
  125. package/esm/index.js +1 -1
  126. package/package.json +8 -7
  127. package/types/document/api-document.d.ts +3 -6
  128. package/types/document/data-type/api-field.d.ts +2 -0
  129. package/types/document/data-type/complex-type.d.ts +1 -1
  130. package/types/document/data-type/data-type.d.ts +4 -2
  131. package/types/document/data-type/enum-type.d.ts +2 -2
  132. package/types/document/data-type/mapped-type.d.ts +2 -2
  133. package/types/document/data-type/mixin-type.d.ts +2 -2
  134. package/types/document/data-type/simple-type.d.ts +4 -2
  135. package/types/document/decorators/http-controller.decorator.d.ts +1 -0
  136. package/types/document/factory/api-document.factory.d.ts +1 -1
  137. package/types/document/factory/data-type.factory.d.ts +5 -0
  138. package/types/document/http/http-controller.d.ts +1 -0
  139. package/types/document/http/http-operation.d.ts +1 -0
  140. package/types/document/http/http-parameter.d.ts +3 -2
  141. package/types/document/index.d.ts +5 -5
  142. package/types/exception/index.d.ts +5 -5
  143. package/types/filter/ast/index.d.ts +1 -1
  144. package/types/filter/opra-filter.ns.d.ts +2 -2
  145. package/types/i18n/i18n.d.ts +21 -19
  146. package/types/index.d.ts +1 -1
  147. package/types/schema/data-type/simple-type.interface.d.ts +4 -0
  148. package/types/schema/document.interface.d.ts +13 -1
  149. package/types/schema/http/http-parameter.interface.d.ts +4 -0
  150. package/types/schema/index.d.ts +1 -0
  151. package/cjs/document/data-type/decorators/api-field-decorator.js +0 -26
  152. package/cjs/document/data-type/decorators/complex-type.decorator.js +0 -33
  153. package/cjs/document/data-type/decorators/simple-type.decorator.js +0 -67
  154. package/cjs/document/http/decorators/http-controller.decorator.js +0 -117
  155. package/cjs/document/http/decorators/http-operation-entity.decorator.js +0 -461
  156. package/cjs/document/http/decorators/http-operation.decorator.js +0 -183
  157. package/cjs/helpers/is-url-string.js +0 -12
  158. package/cjs/http/opra-url-path.js +0 -266
  159. package/cjs/http/opra-url.js +0 -253
  160. package/esm/document/data-type/decorators/api-field-decorator.js +0 -22
  161. package/esm/document/data-type/decorators/complex-type.decorator.js +0 -28
  162. package/esm/document/data-type/decorators/simple-type.decorator.js +0 -61
  163. package/esm/document/http/decorators/http-controller.decorator.js +0 -112
  164. package/esm/document/http/decorators/http-operation-entity.decorator.js +0 -459
  165. package/esm/document/http/decorators/http-operation.decorator.js +0 -178
  166. package/esm/helpers/is-url-string.js +0 -7
  167. package/esm/http/opra-url-path.js +0 -260
  168. package/esm/http/opra-url.js +0 -249
  169. package/types/document/data-type/decorators/api-field-decorator.d.ts +0 -5
  170. package/types/document/data-type/decorators/complex-type.decorator.d.ts +0 -2
  171. package/types/document/data-type/decorators/simple-type.decorator.d.ts +0 -20
  172. package/types/document/http/decorators/http-controller.decorator.d.ts +0 -14
  173. package/types/document/http/decorators/http-operation-entity.decorator.d.ts +0 -100
  174. package/types/document/http/decorators/http-operation.decorator.d.ts +0 -30
  175. package/types/helpers/is-url-string.d.ts +0 -2
  176. package/types/http/opra-url-path.d.ts +0 -55
  177. package/types/http/opra-url.d.ts +0 -66
@@ -4,6 +4,7 @@ import { DocumentInitContext } from '../common/document-init-context.js';
4
4
  import { DATATYPE_METADATA, DECODER, ENCODER, kCtorMap, kDataTypeMap } from '../constants.js';
5
5
  import { ComplexType } from '../data-type/complex-type.js';
6
6
  import { ComplexTypeBase } from '../data-type/complex-type-base.js';
7
+ import { DataType } from '../data-type/data-type.js';
7
8
  import { EnumType } from '../data-type/enum-type.js';
8
9
  import { MappedType } from '../data-type/mapped-type.js';
9
10
  import { MixinType } from '../data-type/mixin-type.js';
@@ -91,10 +92,10 @@ export class DataTypeFactory {
91
92
  thunk = await resolveThunk(thunk);
92
93
  const metadata = Reflect.getMetadata(DATATYPE_METADATA, thunk) || thunk[DATATYPE_METADATA];
93
94
  if (!(metadata && metadata.name)) {
94
- if (typeof thunk === 'function')
95
+ if (typeof thunk === 'function') {
95
96
  return context.addError(`Class "${thunk.name}" doesn't have a valid data type metadata`);
96
- else
97
- return context.addError(`Object doesn't have a valid data type metadata`);
97
+ }
98
+ return context.addError(`Object doesn't have a valid data type metadata`);
98
99
  }
99
100
  importQueue.set(metadata.name, thunk);
100
101
  });
@@ -113,8 +114,9 @@ export class DataTypeFactory {
113
114
  continue;
114
115
  const dt = await this._importDataTypeArgs(context, owner, name);
115
116
  // istanbul ignore next
116
- if (dt && typeof dt !== 'string')
117
+ if (dt && typeof dt !== 'string') {
117
118
  context.addError(`Embedded data type can't be loaded into document node directly`);
119
+ }
118
120
  }
119
121
  return Array.from(initArgsMap.values());
120
122
  }
@@ -130,7 +132,7 @@ export class DataTypeFactory {
130
132
  const { importQueue, initArgsMap } = context;
131
133
  // Check if data type already exist (maybe a builtin type or already imported)
132
134
  const dataType = owner.node.findDataType(thunk);
133
- if (dataType)
135
+ if (dataType instanceof DataType)
134
136
  return dataType.name;
135
137
  let metadata;
136
138
  let ctor;
@@ -178,8 +180,9 @@ export class DataTypeFactory {
178
180
  const baseArgs = await this._importDataTypeArgs(context, owner, metadata.name);
179
181
  if (!baseArgs)
180
182
  return;
181
- if (typeof baseArgs === 'object' && baseArgs.kind !== OpraSchema.SimpleType.Kind)
183
+ if (typeof baseArgs === 'object' && baseArgs.kind !== OpraSchema.SimpleType.Kind) {
182
184
  return context.addError('Kind of base data type is not same');
185
+ }
183
186
  return {
184
187
  kind: OpraSchema.SimpleType.Kind,
185
188
  name: undefined,
@@ -209,11 +212,16 @@ export class DataTypeFactory {
209
212
  /** Mark "out" object as initializing. This will help us to detect circular dependencies */
210
213
  out[initializingSymbol] = true;
211
214
  try {
212
- if (out.name && importQueue?.has(out.name)) {
213
- initArgsMap?.set(metadata.name, out);
215
+ if (out.name) {
216
+ if (importQueue?.has(out.name)) {
217
+ initArgsMap?.set(metadata.name, out);
218
+ out._instance = { name: metadata.name };
219
+ out[kDataTypeMap] = owner.node[kDataTypeMap];
220
+ }
221
+ else {
222
+ return context.addError(`Data Type (${out.name}) must be explicitly added to type list in the document scope`);
223
+ }
214
224
  }
215
- else if (out.name)
216
- return context.addError(`Data Type (${out.name}) must be explicitly added to type list in the document scope`);
217
225
  switch (out.kind) {
218
226
  case OpraSchema.ComplexType.Kind:
219
227
  out.ctor = ctor;
@@ -260,8 +268,9 @@ export class DataTypeFactory {
260
268
  }
261
269
  else if (initArgs.ctor) {
262
270
  const baseClass = Object.getPrototypeOf(initArgs.ctor.prototype).constructor;
263
- if (Reflect.hasMetadata(DATATYPE_METADATA, baseClass))
271
+ if (Reflect.hasMetadata(DATATYPE_METADATA, baseClass)) {
264
272
  baseArgs = await this._importDataTypeArgs(context, owner, baseClass);
273
+ }
265
274
  }
266
275
  if (!baseArgs)
267
276
  return;
@@ -270,14 +279,16 @@ export class DataTypeFactory {
270
279
  });
271
280
  // Initialize additionalFields
272
281
  if (metadata.additionalFields != null) {
273
- if (typeof metadata.additionalFields === 'boolean' || Array.isArray(metadata.additionalFields))
282
+ if (typeof metadata.additionalFields === 'boolean' || Array.isArray(metadata.additionalFields)) {
274
283
  initArgs.additionalFields = metadata.additionalFields;
275
- else
284
+ }
285
+ else {
276
286
  await context.enterAsync('.additionalFields', async () => {
277
287
  const t = await this._importDataTypeArgs(context, owner, metadata.additionalFields);
278
288
  if (t)
279
289
  initArgs.additionalFields = preferName(t);
280
290
  });
291
+ }
281
292
  }
282
293
  if (metadata.fields) {
283
294
  initArgs.fields = {};
@@ -285,9 +296,10 @@ export class DataTypeFactory {
285
296
  for (const [k, v] of Object.entries(metadata.fields)) {
286
297
  await context.enterAsync(`[${k}]`, async () => {
287
298
  const fieldMeta = typeof v === 'string' ? { type: v } : v;
288
- if (fieldMeta.isArray && !fieldMeta.type)
299
+ if (fieldMeta.isArray && !fieldMeta.type) {
289
300
  return context.addError(`"type" must be defined explicitly for array fields`);
290
- const t = await this._importDataTypeArgs(context, owner, fieldMeta.type);
301
+ }
302
+ const t = await this._importDataTypeArgs(context, owner, fieldMeta.type || 'any');
291
303
  if (!t)
292
304
  return;
293
305
  initArgs.fields[k] = {
@@ -320,8 +332,9 @@ export class DataTypeFactory {
320
332
  }
321
333
  else if (initArgs.ctor) {
322
334
  const baseClass = Object.getPrototypeOf(initArgs.ctor.prototype).constructor;
323
- if (Reflect.hasMetadata(DATATYPE_METADATA, baseClass))
335
+ if (Reflect.hasMetadata(DATATYPE_METADATA, baseClass)) {
324
336
  baseArgs = await this._importDataTypeArgs(context, owner, baseClass);
337
+ }
325
338
  }
326
339
  if (!baseArgs)
327
340
  return;
@@ -329,14 +342,17 @@ export class DataTypeFactory {
329
342
  initArgs.ctor = initArgs.ctor || baseArgs.ctor;
330
343
  });
331
344
  initArgs.properties = metadata.properties;
345
+ initArgs.nameMappings = metadata.nameMappings;
332
346
  if (!initArgs.properties && initArgs.ctor)
333
347
  initArgs.properties = new initArgs.ctor();
334
348
  if (metadata.attributes)
335
349
  initArgs.attributes = cloneObject(metadata.attributes);
336
- if (typeof initArgs.properties?.[DECODER] === 'function')
350
+ if (typeof initArgs.properties?.[DECODER] === 'function') {
337
351
  initArgs.generateDecoder = initArgs.properties?.[DECODER].bind(initArgs.properties);
338
- if (typeof initArgs.properties?.[ENCODER] === 'function')
352
+ }
353
+ if (typeof initArgs.properties?.[ENCODER] === 'function') {
339
354
  initArgs.generateEncoder = initArgs.properties?.[ENCODER].bind(initArgs.properties);
355
+ }
340
356
  }
341
357
  static async _prepareMappedTypeArgs(context, owner, initArgs, metadata) {
342
358
  await this._prepareDataTypeArgs(context, initArgs, metadata);
@@ -347,8 +363,9 @@ export class DataTypeFactory {
347
363
  }
348
364
  else if (initArgs.ctor) {
349
365
  const baseClass = Object.getPrototypeOf(initArgs.ctor.prototype).constructor;
350
- if (Reflect.hasMetadata(DATATYPE_METADATA, baseClass))
366
+ if (Reflect.hasMetadata(DATATYPE_METADATA, baseClass)) {
351
367
  baseArgs = await this._importDataTypeArgs(context, owner, baseClass);
368
+ }
352
369
  }
353
370
  if (!baseArgs)
354
371
  return;
@@ -359,10 +376,12 @@ export class DataTypeFactory {
359
376
  initArgs.pick = [...metadata.pick];
360
377
  else if (metadata.omit)
361
378
  initArgs.omit = [...metadata.omit];
362
- else if (metadata.partial)
379
+ else if (metadata.partial) {
363
380
  initArgs.partial = Array.isArray(metadata.partial) ? [...metadata.partial] : metadata.partial;
364
- else if (metadata.required)
381
+ }
382
+ else if (metadata.required) {
365
383
  initArgs.required = Array.isArray(metadata.required) ? [...metadata.required] : metadata.required;
384
+ }
366
385
  }
367
386
  static async _prepareMixinTypeArgs(context, owner, initArgs, metadata) {
368
387
  await this._prepareDataTypeArgs(context, initArgs, metadata);
@@ -381,43 +400,52 @@ export class DataTypeFactory {
381
400
  });
382
401
  }
383
402
  static _createDataType(context, owner, args) {
403
+ let dataType = owner.node.findDataType(typeof args === 'string' ? args : args.name || '');
404
+ if (dataType instanceof DataType)
405
+ return dataType;
384
406
  const initArgs = typeof args === 'string' ? context.initArgsMap?.get(args) : args;
385
- switch (initArgs?.kind) {
386
- case OpraSchema.ComplexType.Kind:
387
- return this._createComplexType(context, owner, initArgs);
388
- case OpraSchema.EnumType.Kind:
389
- return this._createEnumType(context, owner, initArgs);
390
- case OpraSchema.MappedType.Kind:
391
- return this._createMappedType(context, owner, initArgs);
392
- case OpraSchema.MixinType.Kind:
393
- return this._createMixinType(context, owner, initArgs);
394
- case OpraSchema.SimpleType.Kind:
395
- return this._createSimpleType(context, owner, initArgs);
407
+ if (initArgs) {
408
+ const dataTypeMap = initArgs[kDataTypeMap];
409
+ if (!dataTypeMap)
410
+ delete initArgs._instance;
411
+ dataType = initArgs._instance;
412
+ if (dataType?.name && dataTypeMap) {
413
+ dataTypeMap.set(dataType.name, dataType);
414
+ }
415
+ switch (initArgs?.kind) {
416
+ case OpraSchema.ComplexType.Kind:
417
+ return this._createComplexType(context, owner, initArgs);
418
+ case OpraSchema.EnumType.Kind:
419
+ return this._createEnumType(context, owner, initArgs);
420
+ case OpraSchema.MappedType.Kind:
421
+ return this._createMappedType(context, owner, initArgs);
422
+ case OpraSchema.MixinType.Kind:
423
+ return this._createMixinType(context, owner, initArgs);
424
+ case OpraSchema.SimpleType.Kind:
425
+ return this._createSimpleType(context, owner, initArgs);
426
+ default:
427
+ break;
428
+ }
396
429
  }
397
430
  context.addError(`Unknown data type (${String(args)})`);
398
431
  }
399
432
  static _createComplexType(context, owner, args) {
433
+ const dataType = args._instance || {};
434
+ Object.setPrototypeOf(dataType, ComplexType.prototype);
400
435
  const initArgs = cloneObject(args);
401
436
  if (args.base) {
402
437
  context.enter('.base', () => {
403
- initArgs.base = (owner.node.findDataType(args.base) ||
404
- this._createDataType(context, owner, args.base));
438
+ initArgs.base = this._createDataType(context, owner, args.base);
405
439
  });
406
440
  }
407
441
  /** Set additionalFields */
408
442
  if (args.additionalFields) {
409
443
  context.enter('.additionalFields', () => {
410
- if (typeof args.additionalFields === 'boolean' || Array.isArray(args.additionalFields))
444
+ if (typeof args.additionalFields === 'boolean' || Array.isArray(args.additionalFields)) {
411
445
  initArgs.additionalFields = args.additionalFields;
446
+ }
412
447
  else {
413
- if (typeof args.additionalFields === 'string') {
414
- initArgs.additionalFields =
415
- owner.node.findDataType(args.additionalFields) ||
416
- this._createDataType(context, owner, args.additionalFields);
417
- }
418
- else {
419
- initArgs.additionalFields = this._createDataType(context, owner, args.additionalFields);
420
- }
448
+ initArgs.additionalFields = this._createDataType(context, owner, args.additionalFields);
421
449
  }
422
450
  });
423
451
  }
@@ -427,40 +455,49 @@ export class DataTypeFactory {
427
455
  context.enter('.fields', () => {
428
456
  for (const [k, v] of Object.entries(args.fields)) {
429
457
  context.enter(`[${k}]`, () => {
430
- const type = owner.node.findDataType(v.type) || this._createDataType(context, owner, v.type);
431
- if (type)
458
+ const type = this._createDataType(context, owner, v.type);
459
+ if (type) {
432
460
  initArgs.fields[k] = {
433
461
  ...v,
434
462
  name: k,
435
463
  type,
436
464
  };
465
+ }
437
466
  });
438
467
  }
439
468
  });
440
469
  }
441
- return new ComplexType(owner, initArgs);
470
+ ComplexType.apply(dataType, [owner, initArgs]);
471
+ return dataType;
442
472
  }
443
473
  static _createEnumType(context, owner, args) {
474
+ const dataType = args._instance || {};
475
+ Object.setPrototypeOf(dataType, EnumType.prototype);
444
476
  const initArgs = cloneObject(args);
445
477
  if (args.base) {
446
478
  context.enter('.base', () => {
447
- initArgs.base = (owner.node.findDataType(args.base) ||
448
- this._createDataType(context, owner, args.base));
479
+ initArgs.base = this._createDataType(context, owner, args.base);
449
480
  });
450
481
  }
451
482
  initArgs.attributes = args.attributes;
452
- return new EnumType(owner, initArgs);
483
+ EnumType.apply(dataType, [owner, initArgs]);
484
+ return dataType;
453
485
  }
454
486
  static _createMappedType(context, owner, args) {
487
+ const dataType = args._instance || {};
488
+ Object.setPrototypeOf(dataType, MappedType.prototype);
455
489
  const initArgs = cloneObject(args);
456
490
  if (args.base) {
457
491
  context.enter('.base', () => {
458
- initArgs.base = (owner.node.findDataType(args.base) || this._createDataType(context, owner, args.base));
492
+ initArgs.base = this._createDataType(context, owner, args.base);
459
493
  });
460
494
  }
461
- return new MappedType(owner, initArgs);
495
+ MappedType.apply(dataType, [owner, initArgs]);
496
+ return dataType;
462
497
  }
463
498
  static _createMixinType(context, owner, args) {
499
+ const dataType = args._instance || {};
500
+ Object.setPrototypeOf(dataType, MixinType.prototype);
464
501
  const initArgs = cloneObject(args);
465
502
  if (args.types) {
466
503
  context.enter('.types', () => {
@@ -468,25 +505,29 @@ export class DataTypeFactory {
468
505
  let i = 0;
469
506
  for (const t of args.types) {
470
507
  context.enter(`[${i++}]`, () => {
471
- const base = owner.node.findDataType(t) || this._createDataType(context, owner, t);
472
- if (!(base instanceof ComplexTypeBase))
508
+ const base = this._createDataType(context, owner, t);
509
+ if (!(base instanceof ComplexTypeBase)) {
473
510
  throw new TypeError(`"${base?.kind}" can't be set as base for a "${initArgs.kind}"`);
511
+ }
474
512
  initArgs.types.push(base);
475
513
  });
476
514
  }
477
515
  });
478
516
  }
479
- return new MixinType(owner, initArgs);
517
+ MixinType.apply(dataType, [owner, initArgs]);
518
+ return dataType;
480
519
  }
481
520
  static _createSimpleType(context, owner, args) {
521
+ const dataType = args._instance || {};
522
+ Object.setPrototypeOf(dataType, SimpleType.prototype);
482
523
  const initArgs = cloneObject(args);
483
524
  if (args.base) {
484
525
  context.enter('.base', () => {
485
- initArgs.base = (owner.node.findDataType(args.base) ||
486
- this._createDataType(context, owner, args.base));
526
+ initArgs.base = this._createDataType(context, owner, args.base);
487
527
  });
488
528
  }
489
- return new SimpleType(owner, initArgs);
529
+ SimpleType.apply(dataType, [owner, initArgs]);
530
+ return dataType;
490
531
  }
491
532
  }
492
533
  function preferName(initArgs) {
@@ -21,6 +21,7 @@ export class HttpApiFactory {
21
21
  */
22
22
  static async createApi(context, document, init) {
23
23
  const api = new HttpApi(document);
24
+ api.name = init.name;
24
25
  api.description = init.description;
25
26
  api.url = init.url;
26
27
  if (init.controllers) {
@@ -44,8 +45,9 @@ export class HttpApiFactory {
44
45
  return api;
45
46
  }
46
47
  static async _createController(context, parent, thunk, name) {
47
- if (typeof thunk === 'function' && !isConstructor(thunk))
48
+ if (typeof thunk === 'function' && !isConstructor(thunk)) {
48
49
  thunk = parent instanceof HttpController ? thunk(parent.instance) : thunk();
50
+ }
49
51
  thunk = await resolveThunk(thunk);
50
52
  let ctor;
51
53
  let metadata;
@@ -205,7 +207,7 @@ export class HttpApiFactory {
205
207
  });
206
208
  }
207
209
  if (metadata.requestBody) {
208
- await context.enter('.requestBody', async () => {
210
+ await context.enterAsync('.requestBody', async () => {
209
211
  const requestBody = new HttpRequestBody(operation);
210
212
  await this._initHttpRequestBody(context, requestBody, metadata.requestBody);
211
213
  operation.requestBody = requestBody;
@@ -28,8 +28,8 @@ export class HttpApi extends ApiBase {
28
28
  url: this.url,
29
29
  controllers: {},
30
30
  };
31
- for (const [name, v] of this.controllers.entries()) {
32
- out.controllers[name] = v.toJSON();
31
+ for (const v of this.controllers.values()) {
32
+ out.controllers[v.name] = v.toJSON();
33
33
  }
34
34
  return out;
35
35
  }
@@ -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';
@@ -58,7 +59,7 @@ class HttpControllerClass extends DocumentElement {
58
59
  if (c.controllers.size) {
59
60
  controller = c.findController(arg0);
60
61
  if (controller) {
61
- this._controllerReverseMap.set(arg0, c);
62
+ this._controllerReverseMap.set(arg0, controller);
62
63
  return controller;
63
64
  }
64
65
  }
@@ -79,15 +80,25 @@ class HttpControllerClass extends DocumentElement {
79
80
  return this.controllers.get(arg0);
80
81
  }
81
82
  findParameter(paramName, location) {
82
- paramName = paramName.toLowerCase();
83
- for (const prm of this.parameters) {
84
- if ((!location || location === prm.location) &&
85
- ((prm.name instanceof RegExp && prm.name.test(paramName)) ||
86
- (typeof prm.name === 'string' && prm.name.toLowerCase() === paramName)))
83
+ const paramNameLower = paramName.toLowerCase();
84
+ let prm;
85
+ for (prm of this.parameters) {
86
+ if (location && location !== prm.location)
87
+ continue;
88
+ if (typeof prm.name === 'string') {
89
+ prm._nameLower = prm._nameLower || prm.name.toLowerCase();
90
+ if (prm._nameLower === paramNameLower)
91
+ return prm;
92
+ }
93
+ if (prm.name instanceof RegExp && prm.name.test(paramName))
87
94
  return prm;
88
95
  }
89
- if (this.node.parent && this.node.parent.element instanceof HttpController)
96
+ if (this.node.parent && this.node.parent.element instanceof HttpController) {
90
97
  return this.node.parent.element.findParameter(paramName, location);
98
+ }
99
+ }
100
+ getFullUrl() {
101
+ return nodePath.posix.join(this.owner instanceof HttpController ? this.owner.getFullUrl() : '/', this.path);
91
102
  }
92
103
  /**
93
104
  *
@@ -106,20 +117,20 @@ class HttpControllerClass extends DocumentElement {
106
117
  });
107
118
  if (this.operations.size) {
108
119
  out.operations = {};
109
- for (const [name, v] of this.operations.entries()) {
110
- out.operations[name] = v.toJSON();
120
+ for (const v of this.operations.values()) {
121
+ out.operations[v.name] = v.toJSON();
111
122
  }
112
123
  }
113
124
  if (this.controllers.size) {
114
125
  out.controllers = {};
115
- for (const [name, v] of this.controllers.entries()) {
116
- out.controllers[name] = v.toJSON();
126
+ for (const v of this.controllers.values()) {
127
+ out.controllers[v.name] = v.toJSON();
117
128
  }
118
129
  }
119
130
  if (this.types.size) {
120
131
  out.types = {};
121
- for (const [name, v] of this.types.entries()) {
122
- out.types[name] = v.toJSON();
132
+ for (const v of this.types.values()) {
133
+ out.types[v.name] = v.toJSON();
123
134
  }
124
135
  }
125
136
  if (this.parameters.length) {
@@ -22,8 +22,9 @@ export const HttpMediaType = function (owner, initArgs) {
22
22
  _this.maxFileSize = initArgs.maxFileSize;
23
23
  _this.maxTotalFileSize = initArgs.maxTotalFileSize;
24
24
  _this.minFileSize = initArgs.minFileSize;
25
- if (initArgs?.type)
25
+ if (initArgs?.type) {
26
26
  _this.type = initArgs?.type instanceof DataType ? initArgs.type : _this.owner.node.getDataType(initArgs.type);
27
+ }
27
28
  _this.isArray = initArgs.isArray;
28
29
  };
29
30
  /**
@@ -35,8 +36,9 @@ class HttpMediaTypeClass extends DocumentElement {
35
36
  return;
36
37
  for (const f of this.multipartFields) {
37
38
  if ((!fieldType || fieldType === f.fieldType) &&
38
- ((f.fieldName instanceof RegExp && f.fieldName.test(fieldName)) || f.fieldName === fieldName))
39
+ ((f.fieldName instanceof RegExp && f.fieldName.test(fieldName)) || f.fieldName === fieldName)) {
39
40
  return f;
41
+ }
40
42
  }
41
43
  }
42
44
  toJSON() {
@@ -16,8 +16,9 @@ export class HttpOperationResponse extends HttpMediaType {
16
16
  paramName = paramName.toLowerCase();
17
17
  for (const prm of this.parameters) {
18
18
  if ((!location || location === prm.location) &&
19
- ((prm.name instanceof RegExp && prm.name.test(paramName)) || prm.name === paramName))
19
+ ((prm.name instanceof RegExp && prm.name.test(paramName)) || prm.name === paramName)) {
20
20
  return prm;
21
+ }
21
22
  }
22
23
  }
23
24
  toJSON() {
@@ -1,3 +1,4 @@
1
+ import nodePath from 'node:path';
1
2
  import { asMutable } from 'ts-gems';
2
3
  import { cloneObject, omitUndefined } from '../../helpers/index.js';
3
4
  import { OpraSchema } from '../../schema/index.js';
@@ -36,18 +37,30 @@ export const HttpOperation = function (...args) {
36
37
  */
37
38
  class HttpOperationClass extends DocumentElement {
38
39
  findParameter(paramName, location) {
39
- paramName = paramName.toLowerCase();
40
- for (const prm of this.parameters) {
41
- if ((!location || location === prm.location) &&
42
- ((prm.name instanceof RegExp && prm.name.test(paramName)) || prm.name === paramName))
40
+ const paramNameLower = paramName.toLowerCase();
41
+ let prm;
42
+ for (prm of this.parameters) {
43
+ if (location && location !== prm.location)
44
+ continue;
45
+ if (typeof prm.name === 'string') {
46
+ prm._nameLower = prm._nameLower || prm.name.toLowerCase();
47
+ if (prm._nameLower === paramNameLower)
48
+ return prm;
49
+ }
50
+ if (prm.name instanceof RegExp && prm.name.test(paramName))
43
51
  return prm;
44
52
  }
45
53
  }
54
+ getFullUrl() {
55
+ const out = this.owner.getFullUrl();
56
+ return out ? (this.path ? nodePath.posix.join(out, this.path) : out) : this.path || '/';
57
+ }
46
58
  toJSON() {
47
59
  const out = omitUndefined({
48
60
  kind: OpraSchema.HttpOperation.Kind,
49
61
  description: this.description,
50
62
  method: this.method,
63
+ path: this.path,
51
64
  composition: this.composition,
52
65
  requestBody: this.requestBody?.toJSON(),
53
66
  });
@@ -22,6 +22,7 @@ export const HttpParameter = function (owner, initArgs) {
22
22
  _this.deprecated = initArgs.deprecated;
23
23
  _this.required = initArgs.required;
24
24
  _this.arraySeparator = initArgs.arraySeparator;
25
+ _this.keyParam = initArgs.keyParam;
25
26
  };
26
27
  /**
27
28
  * @class HttpParameter
@@ -33,6 +34,7 @@ class HttpParameterClass extends Value {
33
34
  name: this.name,
34
35
  location: this.location,
35
36
  arraySeparator: this.arraySeparator,
37
+ keyParam: this.keyParam,
36
38
  required: this.required,
37
39
  deprecated: this.deprecated,
38
40
  });
@@ -28,8 +28,7 @@ export class HttpStatusRange {
28
28
  toString() {
29
29
  if (this.start === this.end)
30
30
  return String(this.start);
31
- else
32
- return String(this.start) + '-' + String(this.end);
31
+ return String(this.start) + '-' + String(this.end);
33
32
  }
34
33
  toJSON() {
35
34
  return !this.end || this.start === this.end ? this.start : { start: this.start, end: this.end };
@@ -2,36 +2,36 @@ import 'reflect-metadata';
2
2
  import * as DataTypeFactory_ from './factory/data-type.factory.js';
3
3
  import * as HttpApiFactory_ from './factory/http-api.factory.js';
4
4
  export * from './api-document.js';
5
- export * from './constants.js';
6
5
  export * from './common/api-base.js';
7
6
  export * from './common/data-type-map.js';
8
7
  export * from './common/document-element.js';
9
8
  export * from './common/document-init-context.js';
10
9
  export * from './common/document-node.js';
11
10
  export * from './common/opra-document-error.js';
11
+ export * from './constants.js';
12
+ export * from './data-type/api-field.js';
12
13
  export * from './data-type/complex-type.js';
13
14
  export * from './data-type/data-type.js';
14
15
  export * from './data-type/enum-type.js';
15
- export * from './data-type/api-field.js';
16
+ export * from './data-type/extended-types/index.js';
16
17
  export * from './data-type/mapped-type.js';
17
18
  export * from './data-type/mixin-type.js';
18
19
  export * from './data-type/omit-type.js';
19
20
  export * from './data-type/partial-type.js';
20
21
  export * from './data-type/pick-type.js';
22
+ export * from './data-type/primitive-types/index.js';
21
23
  export * from './data-type/required-type.js';
22
24
  export * from './data-type/simple-type.js';
23
- export * from './data-type/primitive-types/index.js';
24
- export * from './data-type/extended-types/index.js';
25
25
  export * from './decorators/http-operation-entity.decorator.js';
26
26
  export * from './factory/api-document.factory.js';
27
27
  export * from './http/http-api.js';
28
+ export * from './http/http-controller.js';
28
29
  export * from './http/http-media-type.js';
29
30
  export * from './http/http-multipart-field.js';
30
31
  export * from './http/http-operation.js';
31
32
  export * from './http/http-operation-response.js';
32
33
  export * from './http/http-parameter.js';
33
34
  export * from './http/http-request-body.js';
34
- export * from './http/http-controller.js';
35
35
  export * from './http/http-status-range.js';
36
36
  export var classes;
37
37
  (function (classes) {
@@ -1,7 +1,4 @@
1
- export * from './opra-exception.js';
2
- export * from './opra-http-error.js';
3
1
  export * from './error-issue.js';
4
- export * from './issue-severity.enum.js';
5
2
  export * from './http-errors/bad-request.error.js';
6
3
  export * from './http-errors/conflict.error.js';
7
4
  export * from './http-errors/failed-dependency.error.js';
@@ -10,8 +7,11 @@ export * from './http-errors/internal-server.error.js';
10
7
  export * from './http-errors/method-not-allowed.error.js';
11
8
  export * from './http-errors/not-acceptable.error.js';
12
9
  export * from './http-errors/not-found.error.js';
13
- export * from './http-errors/unauthorized.error.js';
14
- export * from './http-errors/unprocessable-entity.error.js';
15
10
  export * from './http-errors/permission.error.js';
16
11
  export * from './http-errors/resource-conflict.error.js';
17
12
  export * from './http-errors/resource-not.available.error.js';
13
+ export * from './http-errors/unauthorized.error.js';
14
+ export * from './http-errors/unprocessable-entity.error.js';
15
+ export * from './issue-severity.enum.js';
16
+ export * from './opra-exception.js';
17
+ export * from './opra-http-error.js';