@opra/common 1.4.3 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/browser/index.cjs +5 -5
  2. package/browser/index.mjs +5 -5
  3. package/cjs/document/api-document.js +16 -9
  4. package/cjs/document/common/api-base.js +4 -2
  5. package/cjs/document/common/data-type-map.js +14 -3
  6. package/cjs/document/common/document-init-context.js +5 -0
  7. package/cjs/document/common/document-node.js +25 -29
  8. package/cjs/document/common/value.js +9 -3
  9. package/cjs/document/constants.js +1 -2
  10. package/cjs/document/data-type/api-field.js +19 -4
  11. package/cjs/document/data-type/complex-type-base.js +24 -7
  12. package/cjs/document/data-type/complex-type.js +17 -6
  13. package/cjs/document/data-type/data-type.js +16 -1
  14. package/cjs/document/data-type/enum-type.js +12 -3
  15. package/cjs/document/data-type/extended-types/base64.type.js +1 -0
  16. package/cjs/document/data-type/extended-types/date-string.type.js +1 -0
  17. package/cjs/document/data-type/extended-types/date-time-string.type.js +1 -0
  18. package/cjs/document/data-type/extended-types/date-time.type.js +6 -1
  19. package/cjs/document/data-type/extended-types/date.type.js +6 -1
  20. package/cjs/document/data-type/extended-types/email.type.js +1 -0
  21. package/cjs/document/data-type/extended-types/field-path.type.js +9 -3
  22. package/cjs/document/data-type/extended-types/filter.type.js +14 -5
  23. package/cjs/document/data-type/extended-types/object-id.type.js +1 -0
  24. package/cjs/document/data-type/extended-types/operation-result.type.js +1 -0
  25. package/cjs/document/data-type/extended-types/time.type.js +1 -0
  26. package/cjs/document/data-type/extended-types/url.type.js +1 -0
  27. package/cjs/document/data-type/extended-types/uuid.type.js +1 -0
  28. package/cjs/document/data-type/mapped-type.js +21 -9
  29. package/cjs/document/data-type/mixin-type.js +10 -5
  30. package/cjs/document/data-type/primitive-types/any.type.js +1 -0
  31. package/cjs/document/data-type/primitive-types/bigint.type.js +4 -1
  32. package/cjs/document/data-type/primitive-types/boolean.type.js +1 -0
  33. package/cjs/document/data-type/primitive-types/integer.type.js +4 -1
  34. package/cjs/document/data-type/primitive-types/null.type.js +1 -0
  35. package/cjs/document/data-type/primitive-types/number.type.js +4 -1
  36. package/cjs/document/data-type/primitive-types/string.type.js +4 -1
  37. package/cjs/document/data-type/simple-type.js +17 -5
  38. package/cjs/document/data-type/utils/create-mapped-class.js +3 -1
  39. package/cjs/document/decorators/api-field-decorator.js +2 -1
  40. package/cjs/document/decorators/complex-type.decorator.js +1 -1
  41. package/cjs/document/decorators/http-controller.decorator.js +7 -1
  42. package/cjs/document/decorators/http-operation-entity.decorator.js +20 -10
  43. package/cjs/document/decorators/http-operation.decorator.js +23 -10
  44. package/cjs/document/decorators/rpc-operation.decorator.js +1 -2
  45. package/cjs/document/decorators/simple-type.decorator.js +3 -2
  46. package/cjs/document/factory/api-document.factory.js +12 -3
  47. package/cjs/document/factory/data-type.factory.js +19 -7
  48. package/cjs/document/factory/http-api.factory.js +13 -4
  49. package/cjs/document/http/http-api.js +2 -2
  50. package/cjs/document/http/http-controller.js +7 -6
  51. package/cjs/document/http/http-media-type.js +18 -8
  52. package/cjs/document/http/http-multipart-field.js +2 -2
  53. package/cjs/document/http/http-operation-response.js +11 -6
  54. package/cjs/document/http/http-operation.js +8 -6
  55. package/cjs/document/http/http-parameter.js +2 -2
  56. package/cjs/document/http/http-request-body.js +4 -2
  57. package/cjs/document/http/http-status-range.js +3 -1
  58. package/cjs/document/rpc/rpc-operation-response.js +11 -3
  59. package/cjs/document/rpc/rpc-operation.js +11 -3
  60. package/cjs/document/utils/parse-regexp.util.js +2 -2
  61. package/cjs/exception/opra-exception.js +3 -1
  62. package/cjs/filter/antlr/OpraFilterLexer.js +190 -123
  63. package/cjs/filter/antlr/OpraFilterParser.js +53 -35
  64. package/cjs/filter/ast/expressions/arithmetic-expression.js +3 -1
  65. package/cjs/filter/ast/terms/number-literal.js +3 -1
  66. package/cjs/filter/filter-rules.js +18 -8
  67. package/cjs/filter/filter-tree-visitor.js +2 -1
  68. package/cjs/filter/opra-error-listener.js +7 -1
  69. package/cjs/filter/parse.js +3 -1
  70. package/cjs/filter/utils.js +3 -1
  71. package/cjs/helpers/get-stack-filename.js +6 -2
  72. package/cjs/helpers/mixin-utils.js +7 -2
  73. package/cjs/helpers/object-utils.js +3 -1
  74. package/cjs/helpers/parse-fields-projection.js +4 -2
  75. package/cjs/helpers/type-guards.js +7 -2
  76. package/cjs/i18n/i18n.js +13 -3
  77. package/cjs/i18n/translate.js +3 -1
  78. package/cjs/polifils/array-find-last.js +0 -2
  79. package/esm/document/api-document.js +17 -10
  80. package/esm/document/common/api-base.js +4 -2
  81. package/esm/document/common/data-type-map.js +14 -3
  82. package/esm/document/common/document-init-context.js +5 -0
  83. package/esm/document/common/document-node.js +25 -29
  84. package/esm/document/common/value.js +9 -3
  85. package/esm/document/constants.js +0 -1
  86. package/esm/document/data-type/api-field.js +19 -4
  87. package/esm/document/data-type/complex-type-base.js +25 -8
  88. package/esm/document/data-type/complex-type.js +17 -6
  89. package/esm/document/data-type/data-type.js +17 -2
  90. package/esm/document/data-type/enum-type.js +12 -3
  91. package/esm/document/data-type/extended-types/base64.type.js +1 -0
  92. package/esm/document/data-type/extended-types/date-string.type.js +1 -0
  93. package/esm/document/data-type/extended-types/date-time-string.type.js +1 -0
  94. package/esm/document/data-type/extended-types/date-time.type.js +6 -1
  95. package/esm/document/data-type/extended-types/date.type.js +6 -1
  96. package/esm/document/data-type/extended-types/email.type.js +1 -0
  97. package/esm/document/data-type/extended-types/field-path.type.js +9 -3
  98. package/esm/document/data-type/extended-types/filter.type.js +14 -5
  99. package/esm/document/data-type/extended-types/object-id.type.js +1 -0
  100. package/esm/document/data-type/extended-types/operation-result.type.js +1 -0
  101. package/esm/document/data-type/extended-types/time.type.js +1 -0
  102. package/esm/document/data-type/extended-types/url.type.js +1 -0
  103. package/esm/document/data-type/extended-types/uuid.type.js +1 -0
  104. package/esm/document/data-type/mapped-type.js +21 -9
  105. package/esm/document/data-type/mixin-type.js +11 -6
  106. package/esm/document/data-type/primitive-types/any.type.js +1 -0
  107. package/esm/document/data-type/primitive-types/bigint.type.js +4 -1
  108. package/esm/document/data-type/primitive-types/boolean.type.js +1 -0
  109. package/esm/document/data-type/primitive-types/integer.type.js +4 -1
  110. package/esm/document/data-type/primitive-types/null.type.js +1 -0
  111. package/esm/document/data-type/primitive-types/number.type.js +4 -1
  112. package/esm/document/data-type/primitive-types/string.type.js +4 -1
  113. package/esm/document/data-type/simple-type.js +18 -6
  114. package/esm/document/data-type/utils/create-mapped-class.js +4 -2
  115. package/esm/document/decorators/api-field-decorator.js +2 -1
  116. package/esm/document/decorators/complex-type.decorator.js +2 -2
  117. package/esm/document/decorators/http-controller.decorator.js +7 -1
  118. package/esm/document/decorators/http-operation-entity.decorator.js +22 -12
  119. package/esm/document/decorators/http-operation.decorator.js +23 -10
  120. package/esm/document/decorators/rpc-operation.decorator.js +1 -2
  121. package/esm/document/decorators/simple-type.decorator.js +4 -3
  122. package/esm/document/factory/api-document.factory.js +12 -3
  123. package/esm/document/factory/data-type.factory.js +21 -9
  124. package/esm/document/factory/http-api.factory.js +13 -4
  125. package/esm/document/http/http-api.js +2 -2
  126. package/esm/document/http/http-controller.js +8 -7
  127. package/esm/document/http/http-media-type.js +18 -8
  128. package/esm/document/http/http-multipart-field.js +2 -2
  129. package/esm/document/http/http-operation-response.js +11 -6
  130. package/esm/document/http/http-operation.js +9 -7
  131. package/esm/document/http/http-parameter.js +3 -3
  132. package/esm/document/http/http-request-body.js +4 -2
  133. package/esm/document/http/http-status-range.js +3 -1
  134. package/esm/document/rpc/rpc-controller.js +1 -1
  135. package/esm/document/rpc/rpc-header.js +1 -1
  136. package/esm/document/rpc/rpc-operation-response.js +11 -3
  137. package/esm/document/rpc/rpc-operation.js +12 -4
  138. package/esm/document/utils/parse-regexp.util.js +2 -2
  139. package/esm/exception/opra-exception.js +3 -1
  140. package/esm/filter/antlr/OpraFilterLexer.js +190 -123
  141. package/esm/filter/antlr/OpraFilterParser.js +53 -35
  142. package/esm/filter/ast/expressions/arithmetic-expression.js +3 -1
  143. package/esm/filter/ast/terms/number-literal.js +3 -1
  144. package/esm/filter/filter-rules.js +18 -8
  145. package/esm/filter/filter-tree-visitor.js +2 -1
  146. package/esm/filter/opra-error-listener.js +8 -2
  147. package/esm/filter/parse.js +3 -1
  148. package/esm/filter/utils.js +3 -1
  149. package/esm/helpers/get-stack-filename.js +6 -2
  150. package/esm/helpers/mixin-utils.js +7 -2
  151. package/esm/helpers/object-utils.js +3 -1
  152. package/esm/helpers/parse-fields-projection.js +4 -2
  153. package/esm/helpers/type-guards.js +7 -2
  154. package/esm/i18n/i18n.js +13 -3
  155. package/esm/i18n/translate.js +3 -1
  156. package/esm/polifils/array-find-last.js +0 -2
  157. package/package.json +1 -1
  158. package/types/document/api-document.d.ts +8 -2
  159. package/types/document/common/api-base.d.ts +1 -1
  160. package/types/document/common/document-init-context.d.ts +2 -0
  161. package/types/document/common/document-node.d.ts +8 -14
  162. package/types/document/common/value.d.ts +2 -1
  163. package/types/document/constants.d.ts +0 -1
  164. package/types/document/data-type/api-field.d.ts +6 -11
  165. package/types/document/data-type/complex-type.d.ts +2 -1
  166. package/types/document/data-type/data-type.d.ts +7 -2
  167. package/types/document/data-type/enum-type.d.ts +2 -1
  168. package/types/document/data-type/extended-types/field-path.type.d.ts +2 -1
  169. package/types/document/data-type/extended-types/filter.type.d.ts +2 -1
  170. package/types/document/data-type/mapped-type.d.ts +2 -1
  171. package/types/document/data-type/mixin-type.d.ts +2 -1
  172. package/types/document/data-type/simple-type.d.ts +2 -1
  173. package/types/document/factory/api-document.factory.d.ts +2 -1
  174. package/types/document/http/http-api.d.ts +1 -1
  175. package/types/document/http/http-controller.d.ts +2 -1
  176. package/types/document/http/http-media-type.d.ts +2 -1
  177. package/types/document/http/http-multipart-field.d.ts +2 -1
  178. package/types/document/http/http-operation-response.d.ts +2 -1
  179. package/types/document/http/http-operation.d.ts +2 -1
  180. package/types/document/http/http-parameter.d.ts +2 -1
  181. package/types/document/http/http-request-body.d.ts +2 -1
  182. package/types/filter/filter-rules.d.ts +3 -3
@@ -32,7 +32,9 @@ class ApiDocument extends document_element_js_1.DocumentElement {
32
32
  * @param nameOrCtor
33
33
  */
34
34
  getDataTypeNs(nameOrCtor) {
35
- const dt = nameOrCtor instanceof data_type_js_1.DataType ? this._findDataType(nameOrCtor.name || '') : this._findDataType(nameOrCtor);
35
+ const dt = nameOrCtor instanceof data_type_js_1.DataType
36
+ ? this._findDataType(nameOrCtor.name || '')
37
+ : this._findDataType(nameOrCtor);
36
38
  if (dt)
37
39
  return this[constants_js_1.kTypeNSMap].get(dt);
38
40
  }
@@ -65,13 +67,14 @@ class ApiDocument extends document_element_js_1.DocumentElement {
65
67
  /**
66
68
  * Export as Opra schema definition object
67
69
  */
68
- export() {
70
+ export(options) {
69
71
  const out = (0, objects_1.omitUndefined)({
70
72
  spec: index_js_2.OpraSchema.SpecVersion,
71
73
  id: this.id,
72
74
  url: this.url,
73
75
  info: (0, index_js_1.cloneObject)(this.info, true),
74
76
  });
77
+ options = options || { scopes: this.scopes };
75
78
  if (this.references.size) {
76
79
  let i = 0;
77
80
  const references = {};
@@ -91,25 +94,29 @@ class ApiDocument extends document_element_js_1.DocumentElement {
91
94
  if (this.types.size) {
92
95
  out.types = {};
93
96
  for (const v of this.types.values()) {
94
- out.types[v.name] = v.toJSON();
97
+ if (!v.inScope(options.scopes))
98
+ continue;
99
+ out.types[v.name] = v.toJSON(options);
95
100
  }
96
101
  }
97
102
  if (this.api)
98
- out.api = this.api.toJSON();
103
+ out.api = this.api.toJSON(options);
99
104
  return out;
100
105
  }
101
106
  invalidate() {
102
107
  /** Generate id */
103
- const x = this.export();
108
+ const x = this.export({});
104
109
  delete x.id;
105
110
  this.id = (0, super_fast_md5_1.md5)(JSON.stringify(x));
106
111
  /** Clear [kTypeNSMap] */
107
112
  this[constants_js_1.kTypeNSMap] = new WeakMap();
108
113
  }
109
- _findDataType(nameOrCtor, visitedRefs) {
114
+ _findDataType(nameOrCtor, scope, visitedRefs) {
110
115
  let result = this.types.get(nameOrCtor);
111
- if (result || !this.references.size)
116
+ if (result && result.inScope(scope))
112
117
  return result;
118
+ if (!this.references.size)
119
+ return;
113
120
  // Lookup for references
114
121
  if (typeof nameOrCtor === 'string') {
115
122
  // If given string has namespace pattern (ns:type_name)
@@ -123,7 +130,7 @@ class ApiDocument extends document_element_js_1.DocumentElement {
123
130
  visitedRefs = visitedRefs || new WeakMap();
124
131
  visitedRefs.set(this, true);
125
132
  visitedRefs.set(ref, true);
126
- return ref._findDataType(m[2], visitedRefs);
133
+ return ref._findDataType(m[2], scope, visitedRefs);
127
134
  }
128
135
  nameOrCtor = m[2];
129
136
  }
@@ -145,7 +152,7 @@ class ApiDocument extends document_element_js_1.DocumentElement {
145
152
  for (const refNs of references) {
146
153
  const ref = this.references.get(refNs);
147
154
  visitedRefs.set(ref, true);
148
- result = ref._findDataType(nameOrCtor, visitedRefs);
155
+ result = ref._findDataType(nameOrCtor, scope, visitedRefs);
149
156
  if (result) {
150
157
  this[constants_js_1.kTypeNSMap].set(result, ref?.[constants_js_1.BUILTIN] ? '' : refNs);
151
158
  return result;
@@ -11,15 +11,17 @@ class ApiBase extends document_element_js_1.DocumentElement {
11
11
  this.name = init.name;
12
12
  this.description = init.description;
13
13
  }
14
- toJSON() {
14
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
15
+ toJSON(options) {
15
16
  return (0, objects_1.omitUndefined)({
16
17
  transport: this.transport,
17
18
  name: this.name,
18
19
  description: this.description,
19
20
  });
20
21
  }
22
+ async _initialize(init,
21
23
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
22
- async _initialize(init, context) {
24
+ context) {
23
25
  if (!constants_js_1.CLASS_NAME_PATTERN.test(init.name))
24
26
  throw new TypeError(`Invalid api name (${init.name})`);
25
27
  this.name = init.name;
@@ -22,7 +22,9 @@ class DataTypeMap {
22
22
  this[kMap].forEach(callbackFn, thisArg);
23
23
  }
24
24
  get(nameOrCtor) {
25
- let name = typeof nameOrCtor === 'string' ? nameOrCtor : this[kCtorMap].get(nameOrCtor);
25
+ let name = typeof nameOrCtor === 'string'
26
+ ? nameOrCtor
27
+ : this[kCtorMap].get(nameOrCtor);
26
28
  if (!name && typeof nameOrCtor === 'function') {
27
29
  const metadata = Reflect.getMetadata(constants_js_1.DATATYPE_METADATA, nameOrCtor);
28
30
  name = metadata?.name;
@@ -31,7 +33,14 @@ class DataTypeMap {
31
33
  const metadata = nameOrCtor[constants_js_1.DATATYPE_METADATA];
32
34
  name = metadata?.name;
33
35
  }
34
- return name ? this[kMap].get(name) : undefined;
36
+ if (!name)
37
+ return;
38
+ const out = this[kMap].get(name);
39
+ if (!out)
40
+ return;
41
+ if (typeof nameOrCtor === 'function' && out.kind === 'ComplexType')
42
+ return out.ctor === nameOrCtor ? out : undefined;
43
+ return out;
35
44
  }
36
45
  set(name, dataType) {
37
46
  this[kMap].set(name, dataType);
@@ -43,7 +52,9 @@ class DataTypeMap {
43
52
  has(nameOrCtor) {
44
53
  if (nameOrCtor instanceof data_type_js_1.DataType)
45
54
  return !!nameOrCtor.name && this[kMap].has(nameOrCtor.name);
46
- const name = typeof nameOrCtor === 'string' ? nameOrCtor : this[kCtorMap].get(nameOrCtor);
55
+ const name = typeof nameOrCtor === 'string'
56
+ ? nameOrCtor
57
+ : this[kCtorMap].get(nameOrCtor);
47
58
  return name ? this[kMap].has(name) : false;
48
59
  }
49
60
  keys() {
@@ -9,6 +9,11 @@ class DocumentInitContext {
9
9
  this.showErrorDetails = true;
10
10
  this.maxErrors = options?.maxErrors || 0;
11
11
  this.error.message = '';
12
+ this.scopes = options?.scopes
13
+ ? Array.isArray(options.scopes)
14
+ ? options?.scopes
15
+ : [options?.scopes]
16
+ : undefined;
12
17
  }
13
18
  addError(error) {
14
19
  if (!this.error.details.length) {
@@ -21,25 +21,24 @@ class DocumentNode {
21
21
  // istanbul ignore next
22
22
  throw new Error('ApiDocument not found in document tree');
23
23
  }
24
- hasDataType(nameOrCtor) {
25
- const result = this[constants_js_1.kDataTypeMap]?.has(nameOrCtor);
26
- if (result)
27
- return result;
28
- return this.parent ? this.parent.hasDataType(nameOrCtor) : false;
24
+ hasDataType(nameOrCtor, scope) {
25
+ return !!this.findDataType(nameOrCtor, scope);
29
26
  }
30
- findDataType(nameOrCtor) {
31
- const result = this[constants_js_1.kDataTypeMap]?.get(nameOrCtor);
32
- if (result)
33
- return result;
34
- return this.parent ? this.parent.findDataType(nameOrCtor) : undefined;
27
+ findDataType(nameOrCtor, scope) {
28
+ scope = scope || this.getDocument().scopes;
29
+ const dt = this[constants_js_1.kDataTypeMap]?.get(nameOrCtor);
30
+ if (dt && dt.inScope(scope))
31
+ return dt;
32
+ return this.parent
33
+ ? this.parent.findDataType(nameOrCtor, scope)
34
+ : undefined;
35
35
  }
36
36
  /**
37
37
  * Returns DataType instance by name or Constructor. Returns undefined if not found
38
- * @param nameOrCtor
39
38
  */
40
- getDataType(nameOrCtor) {
39
+ getDataType(nameOrCtor, scope) {
41
40
  const dt = this.findDataType(nameOrCtor);
42
- if (dt)
41
+ if (dt && dt.inScope(scope))
43
42
  return dt;
44
43
  let name = '';
45
44
  if (typeof nameOrCtor === 'function') {
@@ -56,7 +55,9 @@ class DocumentNode {
56
55
  else if (typeof nameOrCtor === 'function')
57
56
  name = nameOrCtor.name;
58
57
  }
59
- throw new TypeError(`Unknown data type` + (name ? ' (' + name + ')' : ''));
58
+ if (dt)
59
+ throw new TypeError(`Data type${name ? ' (' + name + ')' : ''} is not in requested scope (${scope})`);
60
+ throw new TypeError(`Unknown data type${name ? ' (' + name + ')' : ''}`);
60
61
  }
61
62
  getDataTypeNameWithNs(dataType) {
62
63
  if (!dataType.name)
@@ -68,10 +69,9 @@ class DocumentNode {
68
69
  * Returns ComplexType instance by name or Constructor.
69
70
  * Returns undefined if not found
70
71
  * Throws error if data type is not a ComplexType
71
- * @param nameOrCtor
72
72
  */
73
- getComplexType(nameOrCtor) {
74
- const t = this.getDataType(nameOrCtor);
73
+ getComplexType(nameOrCtor, scope) {
74
+ const t = this.getDataType(nameOrCtor, scope);
75
75
  if (t.kind === index_js_1.OpraSchema.ComplexType.Kind)
76
76
  return t;
77
77
  throw new TypeError(`Data type "${t.name}" is not a ComplexType`);
@@ -80,10 +80,9 @@ class DocumentNode {
80
80
  * Returns SimpleType instance by name or Constructor.
81
81
  * Returns undefined if not found
82
82
  * Throws error if data type is not a SimpleType
83
- * @param nameOrCtor
84
83
  */
85
- getSimpleType(nameOrCtor) {
86
- const t = this.getDataType(nameOrCtor);
84
+ getSimpleType(nameOrCtor, scope) {
85
+ const t = this.getDataType(nameOrCtor, scope);
87
86
  if (t.kind === index_js_1.OpraSchema.SimpleType.Kind)
88
87
  return t;
89
88
  throw new TypeError(`Data type "${t.name || t}" is not a SimpleType`);
@@ -92,10 +91,9 @@ class DocumentNode {
92
91
  * Returns EnumType instance by name or Constructor.
93
92
  * Returns undefined if not found
94
93
  * Throws error if data type is not a EnumType
95
- * @param nameOrCtor
96
94
  */
97
- getEnumType(nameOrCtor) {
98
- const t = this.getDataType(nameOrCtor);
95
+ getEnumType(nameOrCtor, scope) {
96
+ const t = this.getDataType(nameOrCtor, scope);
99
97
  if (t.kind === index_js_1.OpraSchema.EnumType.Kind)
100
98
  return t;
101
99
  throw new TypeError(`Data type "${t.name || t}" is not a EnumType`);
@@ -104,10 +102,9 @@ class DocumentNode {
104
102
  * Returns EnumType instance by name or Constructor.
105
103
  * Returns undefined if not found
106
104
  * Throws error if data type is not a MappedType
107
- * @param nameOrCtor
108
105
  */
109
- getMappedType(nameOrCtor) {
110
- const t = this.getDataType(nameOrCtor);
106
+ getMappedType(nameOrCtor, scope) {
107
+ const t = this.getDataType(nameOrCtor, scope);
111
108
  if (t.kind === index_js_1.OpraSchema.MappedType.Kind)
112
109
  return t;
113
110
  throw new TypeError(`Data type "${t.name || t}" is not a MappedType`);
@@ -116,10 +113,9 @@ class DocumentNode {
116
113
  * Returns EnumType instance by name or Constructor.
117
114
  * Returns undefined if not found
118
115
  * Throws error if data type is not a MixinType
119
- * @param nameOrCtor
120
116
  */
121
- getMixinType(nameOrCtor) {
122
- const t = this.getDataType(nameOrCtor);
117
+ getMixinType(nameOrCtor, scope) {
118
+ const t = this.getDataType(nameOrCtor, scope);
123
119
  if (t.kind === index_js_1.OpraSchema.MixinType.Kind)
124
120
  return t;
125
121
  throw new TypeError(`Data type "${t.name || t}" is not a MixinType`);
@@ -20,10 +20,16 @@ exports.Value = function (owner, initArgs) {
20
20
  * @class Value
21
21
  */
22
22
  class ValueClass extends document_element_js_1.DocumentElement {
23
- toJSON() {
24
- const typeName = this.type ? this.node.getDataTypeNameWithNs(this.type) : undefined;
23
+ toJSON(options) {
24
+ const typeName = this.type
25
+ ? this.node.getDataTypeNameWithNs(this.type)
26
+ : undefined;
25
27
  return (0, objects_1.omitUndefined)({
26
- type: this.type ? (typeName ? typeName : this.type.toJSON()) : 'any',
28
+ type: this.type
29
+ ? typeName
30
+ ? typeName
31
+ : this.type.toJSON(options)
32
+ : 'any',
27
33
  description: this.description,
28
34
  isArray: this.isArray,
29
35
  examples: this.examples,
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.kTypeNSMap = exports.kCtorMap = exports.kDataTypeMap = exports.EXTRACT_TYPENAME_PATTERN = exports.CLASS_NAME_PATTERN = exports.NAMESPACE_PATTERN = exports.BUILTIN = exports.DECORATOR = exports.ENCODER = exports.DECODER = exports.RPC_CONTROLLER_METADATA = exports.HTTP_CONTROLLER_METADATA = exports.DATATYPE_METADATA = void 0;
3
+ exports.kTypeNSMap = exports.kCtorMap = exports.kDataTypeMap = exports.CLASS_NAME_PATTERN = exports.NAMESPACE_PATTERN = exports.BUILTIN = exports.DECORATOR = exports.ENCODER = exports.DECODER = exports.RPC_CONTROLLER_METADATA = exports.HTTP_CONTROLLER_METADATA = exports.DATATYPE_METADATA = void 0;
4
4
  exports.DATATYPE_METADATA = Symbol.for('opra.type.metadata');
5
5
  exports.HTTP_CONTROLLER_METADATA = Symbol('opra.http-controller.metadata');
6
6
  exports.RPC_CONTROLLER_METADATA = Symbol('opra.rpc-controller.metadata');
@@ -10,7 +10,6 @@ exports.DECORATOR = Symbol.for('DECORATOR');
10
10
  exports.BUILTIN = Symbol.for('BUILTIN');
11
11
  exports.NAMESPACE_PATTERN = /([a-z$_]\w+):(.+)/i;
12
12
  exports.CLASS_NAME_PATTERN = /^[a-z][\w_]*$/i;
13
- exports.EXTRACT_TYPENAME_PATTERN = /^(.*)Type(\d*)$/;
14
13
  exports.kDataTypeMap = Symbol.for('kDataTypeMap');
15
14
  exports.kCtorMap = Symbol.for('kCtorMap');
16
15
  exports.kTypeNSMap = Symbol.for('kTypeNSMap');
@@ -28,6 +28,7 @@ exports.ApiField = function (...args) {
28
28
  throw new Error('Field origin should be one of ComplexType, MappedType or MixinType');
29
29
  }
30
30
  _this.origin = origin;
31
+ _this.scopes = initArgs.scopes;
31
32
  _this.type = initArgs.type || owner.node.getDataType('any');
32
33
  _this.description = initArgs.description;
33
34
  _this.isArray = initArgs.isArray;
@@ -41,17 +42,31 @@ exports.ApiField = function (...args) {
41
42
  _this.readonly = initArgs.readonly;
42
43
  _this.writeonly = initArgs.writeonly;
43
44
  _this.examples = initArgs.examples;
44
- _this.hidden = initArgs.hidden;
45
45
  };
46
46
  /**
47
47
  *
48
48
  * @class ApiField
49
49
  */
50
50
  class ApiFieldClass extends document_element_js_1.DocumentElement {
51
- toJSON() {
52
- const typeName = this.type ? this.node.getDataTypeNameWithNs(this.type) : undefined;
51
+ inScope(scopes) {
52
+ if (!this.scopes?.length || !scopes)
53
+ return true;
54
+ /** this.scope should match all required scopes */
55
+ scopes = Array.isArray(scopes) ? scopes : [scopes];
56
+ for (const scope of scopes) {
57
+ if (!this.scopes.some(s => {
58
+ return typeof s === 'string' ? scope === s : s.test(scope);
59
+ }))
60
+ return false;
61
+ }
62
+ return true;
63
+ }
64
+ toJSON(options) {
65
+ const typeName = this.type
66
+ ? this.node.getDataTypeNameWithNs(this.type)
67
+ : undefined;
53
68
  return (0, objects_1.omitUndefined)({
54
- type: typeName ? typeName : this.type?.toJSON(),
69
+ type: typeName ? typeName : this.type?.toJSON(options),
55
70
  description: this.description,
56
71
  isArray: this.isArray || undefined,
57
72
  default: this.default,
@@ -86,7 +86,8 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
86
86
  dataType = undefined;
87
87
  continue;
88
88
  }
89
- if (dataType.additionalFields?.[0] === 'type' && dataType.additionalFields?.[1] instanceof data_type_js_1.DataType) {
89
+ if (dataType.additionalFields?.[0] === 'type' &&
90
+ dataType.additionalFields?.[1] instanceof data_type_js_1.DataType) {
90
91
  item.additionalField = true;
91
92
  item.dataType = dataType.additionalFields[1];
92
93
  dataType = dataType.additionalFields[1];
@@ -116,7 +117,11 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
116
117
  const projection = Array.isArray(options?.projection)
117
118
  ? (0, index_js_1.parseFieldsProjection)(options.projection)
118
119
  : options?.projection;
119
- const schema = this._generateSchema(codec, { ...options, projection, currentPath: '' });
120
+ const schema = this._generateSchema(codec, {
121
+ ...options,
122
+ projection,
123
+ currentPath: '',
124
+ });
120
125
  let additionalFields;
121
126
  if (this.additionalFields instanceof data_type_js_1.DataType) {
122
127
  additionalFields = this.additionalFields.generateCodec(codec, options);
@@ -144,12 +149,21 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
144
149
  const schema = {};
145
150
  const { currentPath, projection } = context;
146
151
  const pickList = !!(projection && Object.values(projection).find(p => !p.sign));
152
+ const scope = context.scope
153
+ ? Array.isArray(context.scope)
154
+ ? context.scope
155
+ : [context.scope]
156
+ : undefined;
147
157
  // Process fields
148
158
  let fieldName;
149
159
  for (const field of this.fields.values()) {
150
- if ((context.ignoreReadonlyFields && field.readonly) ||
151
- (context.ignoreWriteonlyFields && field.writeonly) ||
152
- (context.ignoreHiddenFields && field.hidden)) {
160
+ if (
161
+ /** Ignore field if required scope(s) do not match field scopes */
162
+ (scope && !field.inScope(scope)) ||
163
+ /** Ignore field if readonly and ignoreReadonlyFields option true */
164
+ (context.ignoreReadonlyFields && field.readonly) ||
165
+ /** Ignore field if writeonly and ignoreWriteonlyFields option true */
166
+ (context.ignoreWriteonlyFields && field.writeonly)) {
153
167
  schema[field.name] = valgen_1.vg.isUndefined({ coerce: true });
154
168
  continue;
155
169
  }
@@ -171,10 +185,13 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
171
185
  const fn = this._generateFieldCodec(codec, field, {
172
186
  ...context,
173
187
  partial: context.partial === 'deep' ? context.partial : undefined,
174
- projection: typeof projection === 'object' ? projection[fieldName]?.projection || '*' : projection,
188
+ projection: typeof projection === 'object'
189
+ ? projection[fieldName]?.projection || '*'
190
+ : projection,
175
191
  currentPath: currentPath + (currentPath ? '.' : '') + fieldName,
176
192
  });
177
- schema[fieldName] = context.partial || !field.required ? valgen_1.vg.optional(fn) : valgen_1.vg.required(fn);
193
+ schema[fieldName] =
194
+ context.partial || !field.required ? valgen_1.vg.optional(fn) : valgen_1.vg.required(fn);
178
195
  }
179
196
  if (context.allowPatchOperators) {
180
197
  schema._$pull = valgen_1.vg.optional(valgen_1.vg.isAny());
@@ -71,17 +71,28 @@ class ComplexTypeClass extends complex_type_base_js_1.ComplexTypeBase {
71
71
  return true;
72
72
  return !!this.base?.extendsFrom(baseType);
73
73
  }
74
- toJSON() {
75
- const baseName = this.base ? this.node.getDataTypeNameWithNs(this.base) : undefined;
74
+ toJSON(options) {
75
+ const baseName = this.base
76
+ ? this.node.getDataTypeNameWithNs(this.base)
77
+ : undefined;
78
+ if (options?.scopes && !this.base?.inScope(options?.scopes))
79
+ throw new TypeError(`Base type ${baseName ? '(' + baseName + ')' : ''} of ${this.name ? +this.name : 'embedded'} type ` +
80
+ `is not in required scope(s) [${options.scopes}`);
76
81
  const out = (0, objects_1.omitUndefined)({
77
82
  ...complex_type_base_js_1.ComplexTypeBase.prototype.toJSON.call(this),
78
83
  kind: this.kind,
79
- base: this.base ? (baseName ? baseName : this.base.toJSON()) : undefined,
84
+ base: this.base
85
+ ? baseName
86
+ ? baseName
87
+ : this.base.toJSON(options)
88
+ : undefined,
80
89
  });
81
90
  if (this.additionalFields) {
82
91
  if (this.additionalFields instanceof data_type_js_1.DataType) {
83
92
  const typeName = this.node.getDataTypeNameWithNs(this.additionalFields);
84
- out.additionalFields = typeName ? typeName : this.additionalFields.toJSON();
93
+ out.additionalFields = typeName
94
+ ? typeName
95
+ : this.additionalFields.toJSON(options);
85
96
  }
86
97
  else
87
98
  out.additionalFields = this.additionalFields;
@@ -90,8 +101,8 @@ class ComplexTypeClass extends complex_type_base_js_1.ComplexTypeBase {
90
101
  const fields = {};
91
102
  let i = 0;
92
103
  for (const field of this.fields.values()) {
93
- if (field.origin === this) {
94
- fields[field.name] = field.toJSON();
104
+ if (field.origin === this && field.inScope(options?.scopes)) {
105
+ fields[field.name] = field.toJSON(options);
95
106
  i++;
96
107
  }
97
108
  }
@@ -20,6 +20,7 @@ context) {
20
20
  document_element_js_1.DocumentElement.call(this, owner);
21
21
  const _this = (0, ts_gems_1.asMutable)(this);
22
22
  _this.kind = initArgs.kind;
23
+ _this.scopes = initArgs.scopes;
23
24
  _this.name = initArgs.name;
24
25
  _this.description = initArgs.description;
25
26
  _this.abstract = initArgs.abstract;
@@ -33,7 +34,21 @@ class DataTypeClass extends document_element_js_1.DocumentElement {
33
34
  get embedded() {
34
35
  return !this.name;
35
36
  }
36
- toJSON() {
37
+ inScope(scopes) {
38
+ if (!this.scopes?.length || !scopes)
39
+ return true;
40
+ /** this.scope should match all required scopes */
41
+ scopes = Array.isArray(scopes) ? scopes : [scopes];
42
+ for (const scope of scopes) {
43
+ if (!this.scopes.some(s => {
44
+ return typeof s === 'string' ? scope === s : s.test(scope);
45
+ }))
46
+ return false;
47
+ }
48
+ return true;
49
+ }
50
+ // eslint-disable-next-line
51
+ toJSON(options) {
37
52
  return (0, objects_1.omitUndefined)({
38
53
  kind: this.kind,
39
54
  description: this.description,
@@ -51,11 +51,20 @@ class EnumTypeClass extends data_type_js_1.DataType {
51
51
  generateCodec() {
52
52
  return valgen_1.vg.isEnum(Object.keys(this.attributes));
53
53
  }
54
- toJSON() {
55
- const baseName = this.base ? this.node.getDataTypeNameWithNs(this.base) : undefined;
54
+ toJSON(options) {
55
+ const baseName = this.base
56
+ ? this.node.getDataTypeNameWithNs(this.base)
57
+ : undefined;
58
+ if (options?.scopes && !this.base?.inScope(options?.scopes))
59
+ throw new TypeError(`Base type ${baseName ? '(' + baseName + ')' : ''} of ${this.name ? +this.name : 'embedded'} type ` +
60
+ `is not in required scope(s) [${options.scopes}`);
56
61
  return (0, objects_1.omitUndefined)({
57
62
  ...data_type_js_1.DataType.prototype.toJSON.call(this),
58
- base: this.base ? (baseName ? baseName : this.base.toJSON()) : undefined,
63
+ base: this.base
64
+ ? baseName
65
+ ? baseName
66
+ : this.base.toJSON(options)
67
+ : undefined,
59
68
  attributes: (0, index_js_1.cloneObject)(this.ownAttributes),
60
69
  });
61
70
  }
@@ -20,6 +20,7 @@ let Base64Type = class Base64Type {
20
20
  exports.Base64Type = Base64Type;
21
21
  exports.Base64Type = Base64Type = tslib_1.__decorate([
22
22
  (0, simple_type_js_1.SimpleType)({
23
+ name: 'base64',
23
24
  description: 'A stream of bytes, base64 encoded',
24
25
  nameMappings: {
25
26
  js: 'string',
@@ -38,6 +38,7 @@ tslib_1.__decorate([
38
38
  ], DateStringType.prototype, "maxValue", void 0);
39
39
  exports.DateStringType = DateStringType = tslib_1.__decorate([
40
40
  ((0, simple_type_js_1.SimpleType)({
41
+ name: 'datestring',
41
42
  description: 'Date string value',
42
43
  nameMappings: {
43
44
  js: 'string',
@@ -38,6 +38,7 @@ tslib_1.__decorate([
38
38
  ], DateTimeStringType.prototype, "maxValue", void 0);
39
39
  exports.DateTimeStringType = DateTimeStringType = tslib_1.__decorate([
40
40
  ((0, simple_type_js_1.SimpleType)({
41
+ name: 'datetimestring',
41
42
  description: 'DateTime string value',
42
43
  nameMappings: {
43
44
  js: 'string',
@@ -24,7 +24,11 @@ let DateTimeType = class DateTimeType {
24
24
  return x.length > 0 ? valgen_1.vg.pipe([fn, ...x], { returnIndex: 0 }) : fn;
25
25
  }
26
26
  [constants_js_1.ENCODER](properties) {
27
- const fn = valgen_1.vg.isDateString({ precision: 'time', trim: 'time', coerce: true });
27
+ const fn = valgen_1.vg.isDateString({
28
+ precision: 'time',
29
+ trim: 'time',
30
+ coerce: true,
31
+ });
28
32
  const x = [];
29
33
  if (properties.minValue) {
30
34
  (0, valgen_1.isDateString)(properties.minValue);
@@ -52,6 +56,7 @@ tslib_1.__decorate([
52
56
  ], DateTimeType.prototype, "maxValue", void 0);
53
57
  exports.DateTimeType = DateTimeType = tslib_1.__decorate([
54
58
  ((0, simple_type_js_1.SimpleType)({
59
+ name: 'datetime',
55
60
  description: 'A full datetime value',
56
61
  nameMappings: {
57
62
  js: 'string',
@@ -24,7 +24,11 @@ let DateType = class DateType {
24
24
  return x.length > 0 ? valgen_1.vg.pipe([fn, ...x], { returnIndex: 0 }) : fn;
25
25
  }
26
26
  [constants_js_1.ENCODER](properties) {
27
- const fn = valgen_1.vg.isDateString({ precision: 'date', trim: 'date', coerce: true });
27
+ const fn = valgen_1.vg.isDateString({
28
+ precision: 'date',
29
+ trim: 'date',
30
+ coerce: true,
31
+ });
28
32
  const x = [];
29
33
  if (properties.minValue) {
30
34
  (0, valgen_1.isDateString)(properties.minValue);
@@ -52,6 +56,7 @@ tslib_1.__decorate([
52
56
  ], DateType.prototype, "maxValue", void 0);
53
57
  exports.DateType = DateType = tslib_1.__decorate([
54
58
  ((0, simple_type_js_1.SimpleType)({
59
+ name: 'date',
55
60
  description: 'A date without time',
56
61
  nameMappings: {
57
62
  js: 'Date',
@@ -84,6 +84,7 @@ tslib_1.__decorate([
84
84
  ], EmailType.prototype, "blacklistedChars", void 0);
85
85
  exports.EmailType = EmailType = tslib_1.__decorate([
86
86
  ((0, simple_type_js_1.SimpleType)({
87
+ name: 'email',
87
88
  description: 'An email value',
88
89
  nameMappings: {
89
90
  js: 'string',
@@ -21,13 +21,18 @@ let FieldPathType = class FieldPathType {
21
21
  [constants_js_1.ENCODER](properties, element) {
22
22
  return this[constants_js_1.DECODER](properties, element);
23
23
  }
24
- toJSON(properties, element) {
24
+ toJSON(properties, element, options) {
25
25
  const dataType = properties.dataType
26
26
  ? element.node.getComplexType(properties.dataType)
27
27
  : element.node.getComplexType('object');
28
- const typeName = dataType ? element.node.getDataTypeNameWithNs(dataType) : undefined;
28
+ const typeName = dataType
29
+ ? element.node.getDataTypeNameWithNs(dataType)
30
+ : undefined;
31
+ if (options?.scopes && !dataType.inScope(options?.scopes))
32
+ throw new TypeError(`Data type ${typeName ? '(' + typeName + ')' : ''} ` +
33
+ `is not in required scope(s) [${options.scopes}`);
29
34
  return {
30
- dataType: typeName ? typeName : dataType.toJSON(),
35
+ dataType: typeName ? typeName : dataType.toJSON(options),
31
36
  allowSigns: properties.allowSigns,
32
37
  };
33
38
  }
@@ -49,6 +54,7 @@ tslib_1.__decorate([
49
54
  ], FieldPathType.prototype, "allowSigns", void 0);
50
55
  exports.FieldPathType = FieldPathType = tslib_1.__decorate([
51
56
  (0, simple_type_js_1.SimpleType)({
57
+ name: 'fieldpath',
52
58
  description: 'Field path',
53
59
  nameMappings: {
54
60
  js: 'string',