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