@opra/common 1.0.0-alpha.2 → 1.0.0-alpha.21

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 (178) hide show
  1. package/browser.js +5836 -5537
  2. package/cjs/document/api-document.js +28 -12
  3. package/cjs/document/common/data-type-map.js +1 -1
  4. package/cjs/document/common/document-element.js +5 -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 +11 -4
  13. package/cjs/document/data-type/extended-types/date-time-string.type.js +11 -4
  14. package/cjs/document/data-type/extended-types/date-time.type.js +11 -4
  15. package/cjs/document/data-type/extended-types/date.type.js +11 -4
  16. package/cjs/document/data-type/extended-types/email.type.js +25 -11
  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 +11 -4
  22. package/cjs/document/data-type/extended-types/url.type.js +7 -2
  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/omit-type.js +1 -2
  27. package/cjs/document/data-type/partial-type.js +1 -2
  28. package/cjs/document/data-type/pick-type.js +1 -2
  29. package/cjs/document/data-type/primitive-types/any.type.js +2 -1
  30. package/cjs/document/data-type/primitive-types/bigint.type.js +6 -1
  31. package/cjs/document/data-type/primitive-types/boolean.type.js +6 -1
  32. package/cjs/document/data-type/primitive-types/integer.type.js +6 -1
  33. package/cjs/document/data-type/primitive-types/null.type.js +6 -1
  34. package/cjs/document/data-type/primitive-types/number.type.js +10 -3
  35. package/cjs/document/data-type/primitive-types/object.type.js +2 -1
  36. package/cjs/document/data-type/primitive-types/string.type.js +14 -5
  37. package/cjs/document/data-type/required-type.js +1 -2
  38. package/cjs/document/data-type/simple-type.js +16 -10
  39. package/cjs/document/data-type/utils/create-mapped-class.js +3 -3
  40. package/cjs/document/data-type/utils/get-is-inherited-predicate-fn.js +1 -2
  41. package/cjs/document/decorators/api-field-decorator.js +1 -2
  42. package/cjs/document/decorators/complex-type.decorator.js +1 -2
  43. package/cjs/document/decorators/http-controller.decorator.js +26 -2
  44. package/cjs/document/decorators/http-operation-entity.decorator.js +59 -34
  45. package/cjs/document/decorators/http-operation.decorator.js +12 -6
  46. package/cjs/document/decorators/simple-type.decorator.js +2 -3
  47. package/cjs/document/factory/api-document.factory.js +14 -6
  48. package/cjs/document/factory/data-type.factory.js +98 -57
  49. package/cjs/document/factory/http-api.factory.js +4 -2
  50. package/cjs/document/http/http-api.js +2 -2
  51. package/cjs/document/http/http-controller.js +25 -13
  52. package/cjs/document/http/http-media-type.js +4 -2
  53. package/cjs/document/http/http-operation-response.js +2 -1
  54. package/cjs/document/http/http-operation.js +28 -4
  55. package/cjs/document/http/http-parameter.js +4 -0
  56. package/cjs/document/http/http-status-range.js +6 -4
  57. package/cjs/document/index.js +5 -5
  58. package/cjs/document/utils/parse-regexp.util.js +1 -2
  59. package/cjs/document/utils/string-compare.util.js +1 -2
  60. package/cjs/exception/index.js +5 -5
  61. package/cjs/filter/antlr/OpraFilterParser.js +28 -82
  62. package/cjs/filter/ast/index.js +1 -1
  63. package/cjs/filter/build.js +22 -25
  64. package/cjs/filter/filter-rules.js +4 -2
  65. package/cjs/filter/opra-filter.ns.js +2 -2
  66. package/cjs/filter/parse.js +2 -5
  67. package/cjs/filter/utils.js +2 -3
  68. package/cjs/helpers/function-utils.js +1 -2
  69. package/cjs/helpers/get-stack-filename.js +2 -3
  70. package/cjs/helpers/mixin-utils.js +4 -4
  71. package/cjs/helpers/monkey-patches.js +4 -2
  72. package/cjs/helpers/object-utils.js +3 -4
  73. package/cjs/helpers/parse-fields-projection.js +4 -6
  74. package/cjs/helpers/responsive-map.js +5 -4
  75. package/cjs/helpers/type-guards.js +10 -11
  76. package/cjs/i18n/i18n.js +4 -3
  77. package/cjs/i18n/index.js +1 -1
  78. package/cjs/i18n/string-utils.js +2 -3
  79. package/cjs/i18n/translate.js +1 -2
  80. package/cjs/index.js +1 -1
  81. package/cjs/schema/type-guards.js +7 -8
  82. package/esm/document/api-document.js +27 -12
  83. package/esm/document/common/data-type-map.js +1 -1
  84. package/esm/document/common/document-element.js +4 -1
  85. package/esm/document/constants.js +1 -1
  86. package/esm/document/data-type/api-field.js +7 -2
  87. package/esm/document/data-type/complex-type-base.js +6 -1
  88. package/esm/document/data-type/complex-type.js +8 -5
  89. package/esm/document/data-type/data-type.js +2 -1
  90. package/esm/document/data-type/enum-type.js +5 -2
  91. package/esm/document/data-type/extended-types/base64.type.js +7 -2
  92. package/esm/document/data-type/extended-types/date-string.type.js +12 -5
  93. package/esm/document/data-type/extended-types/date-time-string.type.js +12 -5
  94. package/esm/document/data-type/extended-types/date-time.type.js +12 -5
  95. package/esm/document/data-type/extended-types/date.type.js +12 -5
  96. package/esm/document/data-type/extended-types/email.type.js +26 -12
  97. package/esm/document/data-type/extended-types/field-path.type.js +14 -8
  98. package/esm/document/data-type/extended-types/filter.type.js +26 -21
  99. package/esm/document/data-type/extended-types/object-id.type.js +7 -2
  100. package/esm/document/data-type/extended-types/operation-result.type.js +21 -11
  101. package/esm/document/data-type/extended-types/time.type.js +12 -5
  102. package/esm/document/data-type/extended-types/url.type.js +8 -3
  103. package/esm/document/data-type/extended-types/uuid.type.js +9 -3
  104. package/esm/document/data-type/mapped-type.js +12 -5
  105. package/esm/document/data-type/mixin-type.js +5 -1
  106. package/esm/document/data-type/primitive-types/any.type.js +3 -2
  107. package/esm/document/data-type/primitive-types/bigint.type.js +7 -2
  108. package/esm/document/data-type/primitive-types/boolean.type.js +7 -2
  109. package/esm/document/data-type/primitive-types/integer.type.js +7 -2
  110. package/esm/document/data-type/primitive-types/null.type.js +7 -2
  111. package/esm/document/data-type/primitive-types/number.type.js +11 -4
  112. package/esm/document/data-type/primitive-types/object.type.js +3 -2
  113. package/esm/document/data-type/primitive-types/string.type.js +15 -6
  114. package/esm/document/data-type/simple-type.js +16 -10
  115. package/esm/document/data-type/utils/create-mapped-class.js +2 -1
  116. package/esm/document/decorators/http-controller.decorator.js +25 -0
  117. package/esm/document/decorators/http-operation-entity.decorator.js +59 -34
  118. package/esm/document/decorators/http-operation.decorator.js +11 -4
  119. package/esm/document/factory/api-document.factory.js +14 -6
  120. package/esm/document/factory/data-type.factory.js +98 -57
  121. package/esm/document/factory/http-api.factory.js +4 -2
  122. package/esm/document/http/http-api.js +2 -2
  123. package/esm/document/http/http-controller.js +24 -13
  124. package/esm/document/http/http-media-type.js +4 -2
  125. package/esm/document/http/http-operation-response.js +2 -1
  126. package/esm/document/http/http-operation.js +27 -4
  127. package/esm/document/http/http-parameter.js +4 -0
  128. package/esm/document/http/http-status-range.js +6 -4
  129. package/esm/document/index.js +5 -5
  130. package/esm/exception/index.js +5 -5
  131. package/esm/filter/antlr/OpraFilterParser.js +28 -82
  132. package/esm/filter/ast/index.js +1 -1
  133. package/esm/filter/build.js +1 -3
  134. package/esm/filter/filter-rules.js +4 -2
  135. package/esm/filter/opra-filter.ns.js +2 -2
  136. package/esm/filter/parse.js +1 -3
  137. package/esm/helpers/mixin-utils.js +2 -1
  138. package/esm/helpers/monkey-patches.js +4 -2
  139. package/esm/helpers/parse-fields-projection.js +1 -3
  140. package/esm/helpers/responsive-map.js +5 -4
  141. package/esm/i18n/i18n.js +4 -3
  142. package/esm/i18n/index.js +1 -1
  143. package/esm/index.js +1 -1
  144. package/package.json +9 -8
  145. package/types/document/api-document.d.ts +4 -6
  146. package/types/document/common/document-element.d.ts +1 -0
  147. package/types/document/data-type/api-field.d.ts +2 -0
  148. package/types/document/data-type/complex-type.d.ts +1 -1
  149. package/types/document/data-type/data-type.d.ts +4 -2
  150. package/types/document/data-type/enum-type.d.ts +2 -2
  151. package/types/document/data-type/mapped-type.d.ts +3 -3
  152. package/types/document/data-type/mixin-type.d.ts +2 -2
  153. package/types/document/data-type/simple-type.d.ts +4 -2
  154. package/types/document/decorators/http-controller.decorator.d.ts +1 -0
  155. package/types/document/factory/api-document.factory.d.ts +1 -1
  156. package/types/document/factory/data-type.factory.d.ts +5 -0
  157. package/types/document/http/http-controller.d.ts +1 -0
  158. package/types/document/http/http-operation.d.ts +4 -2
  159. package/types/document/http/http-parameter.d.ts +3 -2
  160. package/types/document/http/http-status-range.d.ts +2 -1
  161. package/types/document/index.d.ts +5 -5
  162. package/types/exception/index.d.ts +5 -5
  163. package/types/filter/ast/index.d.ts +1 -1
  164. package/types/filter/opra-filter.ns.d.ts +2 -2
  165. package/types/helpers/type-guards.d.ts +0 -2
  166. package/types/i18n/i18n.d.ts +21 -19
  167. package/types/index.d.ts +1 -1
  168. package/types/schema/data-type/data-type.interface.d.ts +1 -1
  169. package/types/schema/data-type/mapped-type.interface.d.ts +2 -2
  170. package/types/schema/data-type/simple-type.interface.d.ts +4 -0
  171. package/types/schema/data-type-container.interface.d.ts +1 -1
  172. package/types/schema/document.interface.d.ts +14 -2
  173. package/types/schema/http/http-controller.interface.d.ts +2 -2
  174. package/types/schema/http/http-media-type.interface.d.ts +1 -1
  175. package/types/schema/http/http-operation-response.interface.d.ts +2 -2
  176. package/types/schema/http/http-operation.interface.d.ts +8 -4
  177. package/types/schema/http/http-parameter.interface.d.ts +5 -1
  178. package/types/schema/index.d.ts +1 -0
@@ -1,4 +1,4 @@
1
- import { __decorate } from "tslib";
1
+ import { __decorate, __metadata } from "tslib";
2
2
  import { toString, vg } from 'valgen';
3
3
  import { DATATYPE_METADATA, DECODER, ENCODER } from '../../constants.js';
4
4
  import { SimpleType } from '../simple-type.js';
@@ -30,26 +30,35 @@ let StringType = class StringType {
30
30
  __decorate([
31
31
  SimpleType.Attribute({
32
32
  description: 'Regex pattern to be used for validation',
33
- })
33
+ }),
34
+ __metadata("design:type", Object)
34
35
  ], StringType.prototype, "pattern", void 0);
35
36
  __decorate([
36
37
  SimpleType.Attribute({
37
38
  description: 'Name of the pattern',
38
- })
39
+ }),
40
+ __metadata("design:type", String)
39
41
  ], StringType.prototype, "patternName", void 0);
40
42
  __decorate([
41
43
  SimpleType.Attribute({
42
44
  description: 'Minimum number of characters',
43
- })
45
+ }),
46
+ __metadata("design:type", Number)
44
47
  ], StringType.prototype, "minLength", void 0);
45
48
  __decorate([
46
49
  SimpleType.Attribute({
47
50
  description: 'Minimum number of characters',
48
- })
51
+ }),
52
+ __metadata("design:type", Number)
49
53
  ], StringType.prototype, "maxLength", void 0);
50
54
  StringType = __decorate([
51
55
  SimpleType({
52
56
  description: 'A sequence of characters',
53
- })
57
+ nameMappings: {
58
+ js: 'string',
59
+ json: 'string',
60
+ },
61
+ }),
62
+ __metadata("design:paramtypes", [Object])
54
63
  ], StringType);
55
64
  export { StringType };
@@ -20,11 +20,14 @@ export const SimpleType = function (...args) {
20
20
  _this.kind = OpraSchema.SimpleType.Kind;
21
21
  if (initArgs.base) {
22
22
  // noinspection SuspiciousTypeOfGuard
23
- if (!(initArgs.base instanceof SimpleType))
23
+ if (!(initArgs.base instanceof SimpleType)) {
24
24
  throw new TypeError(`"${initArgs.base.kind}" can't be set as base for a "${this.kind}"`);
25
+ }
25
26
  _this.base = initArgs.base;
26
27
  }
27
28
  _this.properties = initArgs.properties;
29
+ _this.ownNameMappings = { ...initArgs.nameMappings };
30
+ _this.nameMappings = { ..._this.base?.nameMappings, ...initArgs.nameMappings };
28
31
  _this.ownAttributes = cloneObject(initArgs.attributes || {});
29
32
  _this.attributes = _this.base ? cloneObject(_this.base.attributes) : {};
30
33
  if (_this.ownAttributes) {
@@ -43,6 +46,8 @@ export const SimpleType = function (...args) {
43
46
  */
44
47
  class SimpleTypeClass extends DataType {
45
48
  extendsFrom(baseType) {
49
+ if (!(baseType instanceof DataType))
50
+ baseType = this.node.getDataType(baseType);
46
51
  if (!(baseType instanceof SimpleType))
47
52
  return false;
48
53
  if (baseType === this)
@@ -63,15 +68,13 @@ class SimpleTypeClass extends DataType {
63
68
  }
64
69
  return isAny;
65
70
  }
66
- else {
67
- let t = this;
68
- while (t) {
69
- if (t._generateEncoder)
70
- return t._generateEncoder(prop, options?.documentElement || this.owner);
71
- t = this.base;
72
- }
73
- return isAny;
71
+ let t = this;
72
+ while (t) {
73
+ if (t._generateEncoder)
74
+ return t._generateEncoder(prop, options?.documentElement || this.owner);
75
+ t = this.base;
74
76
  }
77
+ return isAny;
75
78
  }
76
79
  toJSON() {
77
80
  const attributes = omitUndefined(this.ownAttributes);
@@ -87,12 +90,15 @@ class SimpleTypeClass extends DataType {
87
90
  return o;
88
91
  }, {});
89
92
  const baseName = this.base ? this.node.getDataTypeNameWithNs(this.base) : undefined;
90
- return omitUndefined({
93
+ const out = omitUndefined({
91
94
  ...DataType.prototype.toJSON.apply(this),
92
95
  base: this.base ? (baseName ? baseName : this.base.toJSON()) : undefined,
93
96
  attributes: attributes && Object.keys(attributes).length ? attributes : undefined,
94
97
  properties: Object.keys(properties).length ? properties : undefined,
95
98
  });
99
+ if (Object.keys(this.ownNameMappings).length)
100
+ out.nameMappings = { ...this.ownNameMappings };
101
+ return out;
96
102
  }
97
103
  }
98
104
  SimpleType.prototype = SimpleTypeClass.prototype;
@@ -23,8 +23,9 @@ export function createMappedClass(source, config, options) {
23
23
  throw new TypeError(`Class "${source}" doesn't have datatype metadata information`);
24
24
  if (!(m.kind === OpraSchema.ComplexType.Kind ||
25
25
  m.kind === OpraSchema.MappedType.Kind ||
26
- m.kind === OpraSchema.MixinType.Kind))
26
+ m.kind === OpraSchema.MixinType.Kind)) {
27
27
  throw new TypeError(`Class "${source}" is not a ${OpraSchema.ComplexType.Kind}`);
28
+ }
28
29
  }
29
30
  const metadata = {
30
31
  ...options,
@@ -98,6 +98,31 @@ export function HttpControllerDecoratorFactory(options) {
98
98
  });
99
99
  return decorator;
100
100
  };
101
+ /**
102
+ *
103
+ */
104
+ decorator.KeyParam = (name, arg1) => {
105
+ decoratorChain.push((meta) => {
106
+ if (!meta.path?.includes(':' + name))
107
+ meta.path = (meta.path || '') + '@:' + name;
108
+ const paramMeta = typeof arg1 === 'string' || typeof arg1 === 'function'
109
+ ? {
110
+ name,
111
+ location: 'path',
112
+ type: arg1,
113
+ keyParam: true,
114
+ }
115
+ : {
116
+ ...arg1,
117
+ name,
118
+ location: 'path',
119
+ keyParam: true,
120
+ };
121
+ meta.parameters = meta.parameters || [];
122
+ meta.parameters.push(paramMeta);
123
+ });
124
+ return decorator;
125
+ };
101
126
  /**
102
127
  *
103
128
  */
@@ -21,8 +21,8 @@ HttpOperation.Entity.Create = function (arg0, arg1) {
21
21
  /** Initialize the decorator and the chain */
22
22
  const decoratorChain = [];
23
23
  const decorator = HttpOperationDecoratorFactory(decoratorChain, omitUndefined({
24
- description: args.description,
25
24
  method: 'POST',
25
+ ...args,
26
26
  composition: 'Entity.Create',
27
27
  requestBody: {
28
28
  immediateFetch: true,
@@ -51,8 +51,6 @@ HttpOperation.Entity.Create = function (arg0, arg1) {
51
51
  description: 'The request was well-formed but was unable to process operation due to one or many errors.',
52
52
  contentType: MimeTypes.opra_response_json,
53
53
  });
54
- if (typeof args.type === 'function')
55
- decorator.UseType(args.type);
56
54
  decoratorChain.push((operationMeta) => {
57
55
  const compositionOptions = (operationMeta.compositionOptions = operationMeta.compositionOptions || {});
58
56
  compositionOptions.type = getDataTypeName(args.type);
@@ -72,8 +70,8 @@ HttpOperation.Entity.Delete = function (arg0, arg1) {
72
70
  /** Initialize the decorator and the chain */
73
71
  const decoratorChain = [];
74
72
  const decorator = HttpOperationDecoratorFactory(decoratorChain, omitUndefined({
75
- description: args.description,
76
73
  method: 'DELETE',
74
+ ...args,
77
75
  composition: 'Entity.Delete',
78
76
  }));
79
77
  decorator
@@ -85,17 +83,28 @@ HttpOperation.Entity.Delete = function (arg0, arg1) {
85
83
  description: 'The request was well-formed but was unable to process operation due to one or many errors.',
86
84
  contentType: MimeTypes.opra_response_json,
87
85
  });
88
- if (typeof args.type === 'function')
89
- decorator.UseType(args.type);
90
86
  /**
91
87
  *
92
88
  */
93
89
  decorator.KeyParam = (name, prmOptions) => {
94
- decorator.PathParam(name, prmOptions);
90
+ const paramMeta = typeof prmOptions === 'string' || typeof prmOptions === 'function'
91
+ ? {
92
+ name,
93
+ location: 'path',
94
+ type: prmOptions,
95
+ keyParam: true,
96
+ }
97
+ : {
98
+ ...prmOptions,
99
+ name,
100
+ location: 'path',
101
+ keyParam: true,
102
+ };
103
+ decorator.PathParam(name, paramMeta);
95
104
  decoratorChain.push((meta) => {
96
- meta.path = (meta.path || '') + '@:' + name;
97
- meta.compositionOptions = meta.compositionOptions || {};
98
- meta.compositionOptions.keyParameter = name;
105
+ if (!meta.path?.includes(':' + name))
106
+ meta.path = (meta.path || '') + '@:' + name;
107
+ meta.mergePath = true;
99
108
  });
100
109
  return decorator;
101
110
  };
@@ -121,8 +130,8 @@ HttpOperation.Entity.DeleteMany = function (arg0, arg1) {
121
130
  const filterType = new FilterType({ dataType: args.type });
122
131
  filterType.rules = {};
123
132
  const decorator = HttpOperationDecoratorFactory(decoratorChain, omitUndefined({
124
- description: args.description,
125
133
  method: 'DELETE',
134
+ ...args,
126
135
  composition: 'Entity.DeleteMany',
127
136
  }));
128
137
  decorator
@@ -138,8 +147,6 @@ HttpOperation.Entity.DeleteMany = function (arg0, arg1) {
138
147
  type: filterType,
139
148
  description: 'Determines filter fields',
140
149
  });
141
- if (typeof args.type === 'function')
142
- decorator.UseType(args.type);
143
150
  decoratorChain.push((operationMeta) => {
144
151
  const compositionOptions = (operationMeta.compositionOptions = operationMeta.compositionOptions || {});
145
152
  compositionOptions.type = getDataTypeName(args.type);
@@ -169,8 +176,8 @@ HttpOperation.Entity.FindMany = function (arg0, arg1) {
169
176
  const filterType = new FilterType({ dataType: args.type });
170
177
  filterType.rules = {};
171
178
  const decorator = HttpOperationDecoratorFactory(decoratorChain, omitUndefined({
172
- description: args.description,
173
179
  method: 'GET',
180
+ ...args,
174
181
  composition: 'Entity.FindMany',
175
182
  }));
176
183
  decorator
@@ -219,8 +226,6 @@ HttpOperation.Entity.FindMany = function (arg0, arg1) {
219
226
  isArray: true,
220
227
  arraySeparator: ',',
221
228
  });
222
- if (typeof args.type === 'function')
223
- decorator.UseType(args.type);
224
229
  decoratorChain.push((operationMeta) => {
225
230
  const compositionOptions = (operationMeta.compositionOptions = operationMeta.compositionOptions || {});
226
231
  compositionOptions.type = getDataTypeName(args.type);
@@ -261,8 +266,8 @@ HttpOperation.Entity.Get = function (arg0, arg1) {
261
266
  /** Initialize the decorator and the chain */
262
267
  const decoratorChain = [];
263
268
  const decorator = HttpOperationDecoratorFactory(decoratorChain, omitUndefined({
264
- description: args.description,
265
269
  method: 'GET',
270
+ ...args,
266
271
  composition: 'Entity.Get',
267
272
  }));
268
273
  decorator
@@ -288,17 +293,28 @@ HttpOperation.Entity.Get = function (arg0, arg1) {
288
293
  description: 'The request was well-formed but was unable to process operation due to one or many errors.',
289
294
  contentType: MimeTypes.opra_response_json,
290
295
  });
291
- if (typeof args.type === 'function')
292
- decorator.UseType(args.type);
293
296
  /**
294
297
  *
295
298
  */
296
299
  decorator.KeyParam = (name, prmOptions) => {
297
- decorator.PathParam(name, prmOptions);
300
+ const paramMeta = typeof prmOptions === 'string' || typeof prmOptions === 'function'
301
+ ? {
302
+ name,
303
+ location: 'path',
304
+ type: prmOptions,
305
+ keyParam: true,
306
+ }
307
+ : {
308
+ ...prmOptions,
309
+ name,
310
+ location: 'path',
311
+ keyParam: true,
312
+ };
313
+ decorator.PathParam(name, paramMeta);
298
314
  decoratorChain.push((meta) => {
299
- meta.path = (meta.path || '') + '@:' + name;
300
- meta.compositionOptions = meta.compositionOptions || {};
301
- meta.compositionOptions.keyParameter = name;
315
+ if (!meta.path?.includes(':' + name))
316
+ meta.path = (meta.path || '') + '@:' + name;
317
+ meta.mergePath = true;
302
318
  });
303
319
  return decorator;
304
320
  };
@@ -324,8 +340,8 @@ HttpOperation.Entity.UpdateMany = function (arg0, arg1) {
324
340
  filterType.rules = {};
325
341
  const filterRules = new FilterRules();
326
342
  const decorator = HttpOperationDecoratorFactory(decoratorChain, omitUndefined({
327
- description: args.description,
328
343
  method: 'PATCH',
344
+ ...args,
329
345
  composition: 'Entity.UpdateMany',
330
346
  requestBody: {
331
347
  immediateFetch: true,
@@ -334,10 +350,8 @@ HttpOperation.Entity.UpdateMany = function (arg0, arg1) {
334
350
  required: true,
335
351
  },
336
352
  }));
337
- decorator.RequestContent(args.requestBody?.type || args.type);
338
- if (typeof args.type === 'function')
339
- decorator.UseType(args.type);
340
353
  decorator
354
+ .RequestContent(args.requestBody?.type || args.type)
341
355
  .Response(HttpStatusCode.OK, {
342
356
  description: 'Operation is successful. Returns OperationResult with "affected" field.',
343
357
  contentType: MimeTypes.opra_response_json,
@@ -379,8 +393,8 @@ HttpOperation.Entity.Update = function (arg0, arg1) {
379
393
  const filterType = new FilterType({ dataType: args.type });
380
394
  filterType.rules = {};
381
395
  const decorator = HttpOperationDecoratorFactory(decoratorChain, omitUndefined({
382
- description: args.description,
383
396
  method: 'PATCH',
397
+ ...args,
384
398
  composition: 'Entity.Update',
385
399
  requestBody: {
386
400
  partial: 'deep',
@@ -417,17 +431,28 @@ HttpOperation.Entity.Update = function (arg0, arg1) {
417
431
  description: 'The request was well-formed but was unable to process operation due to one or many errors.',
418
432
  contentType: MimeTypes.opra_response_json,
419
433
  });
420
- if (typeof args.type === 'function')
421
- decorator.UseType(args.type);
422
434
  /**
423
435
  *
424
436
  */
425
437
  decorator.KeyParam = (name, prmOptions) => {
426
- decorator.PathParam(name, prmOptions);
438
+ const paramMeta = typeof prmOptions === 'string' || typeof prmOptions === 'function'
439
+ ? {
440
+ name,
441
+ location: 'path',
442
+ type: prmOptions,
443
+ keyParam: true,
444
+ }
445
+ : {
446
+ ...prmOptions,
447
+ name,
448
+ location: 'path',
449
+ keyParam: true,
450
+ };
451
+ decorator.PathParam(name, paramMeta);
427
452
  decoratorChain.push((meta) => {
428
- meta.path = (meta.path || '') + '@:' + name;
429
- meta.compositionOptions = meta.compositionOptions || {};
430
- meta.compositionOptions.keyParameter = name;
453
+ if (!meta.path?.includes(':' + name))
454
+ meta.path = (meta.path || '') + '@:' + name;
455
+ meta.mergePath = true;
431
456
  });
432
457
  return decorator;
433
458
  };
@@ -33,8 +33,9 @@ export function HttpOperationDecoratorFactory(decoratorChain, options) {
33
33
  type: arg1,
34
34
  }
35
35
  : { ...arg1, name, location: 'cookie' };
36
- if (meta.parameters)
36
+ if (meta.parameters) {
37
37
  meta.parameters = meta.parameters.filter(p => !(p.location === 'cookie' && String(p.name) === String(name)));
38
+ }
38
39
  else
39
40
  meta.parameters = [];
40
41
  meta.parameters.push(paramMeta);
@@ -53,8 +54,9 @@ export function HttpOperationDecoratorFactory(decoratorChain, options) {
53
54
  type: arg1,
54
55
  }
55
56
  : { ...arg1, name, location: 'header' };
56
- if (meta.parameters)
57
+ if (meta.parameters) {
57
58
  meta.parameters = meta.parameters.filter(p => !(p.location === 'header' && String(p.name) === String(name)));
59
+ }
58
60
  else
59
61
  meta.parameters = [];
60
62
  meta.parameters.push(paramMeta);
@@ -73,8 +75,9 @@ export function HttpOperationDecoratorFactory(decoratorChain, options) {
73
75
  type: arg1,
74
76
  }
75
77
  : { ...arg1, name, location: 'query' };
76
- if (meta.parameters)
78
+ if (meta.parameters) {
77
79
  meta.parameters = meta.parameters.filter(p => !(p.location === 'query' && String(p.name) === String(name)));
80
+ }
78
81
  else
79
82
  meta.parameters = [];
80
83
  meta.parameters.push(paramMeta);
@@ -93,8 +96,9 @@ export function HttpOperationDecoratorFactory(decoratorChain, options) {
93
96
  type: arg1,
94
97
  }
95
98
  : { ...arg1, name, location: 'path' };
96
- if (meta.parameters)
99
+ if (meta.parameters) {
97
100
  meta.parameters = meta.parameters.filter(p => !(p.location === 'path' && String(p.name) === String(name)));
101
+ }
98
102
  else
99
103
  meta.parameters = [];
100
104
  meta.parameters.push(paramMeta);
@@ -110,6 +114,9 @@ export function HttpOperationDecoratorFactory(decoratorChain, options) {
110
114
  responseMeta.contentType = responseMeta.contentType || MimeTypes.opra_response_json;
111
115
  responseMeta.contentEncoding = responseMeta.contentEncoding || 'utf-8';
112
116
  }
117
+ if (responseMeta.contentType === MimeTypes.opra_response_json) {
118
+ responseMeta.contentEncoding = responseMeta.contentEncoding || 'utf-8';
119
+ }
113
120
  decoratorChain.push((meta) => {
114
121
  meta.responses = meta.responses || [];
115
122
  meta.responses.push(responseMeta);
@@ -40,9 +40,7 @@ export class ApiDocumentFactory {
40
40
  context.error.message = `(${l}) error${l > 1 ? 's' : ''} found in document schema.`;
41
41
  if (context.showErrorDetails) {
42
42
  context.error.message += context.error.details
43
- .map(d => {
44
- return `\n\n - ${d.message}` + (d.path ? `\n @${d.path}` : '');
45
- })
43
+ .map(d => `\n\n - ${d.message}` + (d.path ? `\n @${d.path}` : ''))
46
44
  .join('');
47
45
  }
48
46
  }
@@ -64,9 +62,14 @@ export class ApiDocumentFactory {
64
62
  else
65
63
  init = schemaOrUrl;
66
64
  // Add builtin data types if this document is the root
65
+ let builtinDocument;
67
66
  if (!document[BUILTIN]) {
68
- const builtinDocument = await this.createBuiltinDocument(context);
69
- document.references.set('opra', builtinDocument);
67
+ const t = document.node.findDataType('string');
68
+ builtinDocument = t?.node.getDocument();
69
+ if (!builtinDocument) {
70
+ builtinDocument = await this.createBuiltinDocument(context);
71
+ document.references.set('opra', builtinDocument);
72
+ }
70
73
  }
71
74
  init.spec = init.spec || OpraSchema.SpecVersion;
72
75
  document.url = init.url;
@@ -87,8 +90,12 @@ export class ApiDocumentFactory {
87
90
  return;
88
91
  }
89
92
  const refDoc = new ApiDocument();
93
+ if (builtinDocument)
94
+ refDoc.references.set('opra', builtinDocument);
90
95
  await this.initDocument(refDoc, context, r);
91
- document.references.set(ns, refDoc);
96
+ /** If same document already exists in document tree, we use it except the new one */
97
+ const preDoc = document.findDocument(refDoc.id);
98
+ document.references.set(ns, preDoc || refDoc);
92
99
  });
93
100
  }
94
101
  });
@@ -109,6 +116,7 @@ export class ApiDocumentFactory {
109
116
  context.addError(`Unknown service protocol (${init.api.protocol})`);
110
117
  });
111
118
  }
119
+ document.invalidate();
112
120
  }
113
121
  /**
114
122
  *