@opra/common 1.4.4 → 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 (120) hide show
  1. package/browser/index.cjs +5 -5
  2. package/browser/index.mjs +5 -5
  3. package/cjs/document/api-document.js +13 -8
  4. package/cjs/document/common/api-base.js +2 -1
  5. package/cjs/document/common/document-init-context.js +5 -0
  6. package/cjs/document/common/document-node.js +25 -29
  7. package/cjs/document/common/value.js +6 -2
  8. package/cjs/document/constants.js +1 -2
  9. package/cjs/document/data-type/api-field.js +16 -3
  10. package/cjs/document/data-type/complex-type-base.js +12 -3
  11. package/cjs/document/data-type/complex-type.js +12 -5
  12. package/cjs/document/data-type/data-type.js +16 -1
  13. package/cjs/document/data-type/enum-type.js +9 -2
  14. package/cjs/document/data-type/extended-types/base64.type.js +1 -0
  15. package/cjs/document/data-type/extended-types/date-string.type.js +1 -0
  16. package/cjs/document/data-type/extended-types/date-time-string.type.js +1 -0
  17. package/cjs/document/data-type/extended-types/date-time.type.js +1 -0
  18. package/cjs/document/data-type/extended-types/date.type.js +1 -0
  19. package/cjs/document/data-type/extended-types/email.type.js +1 -0
  20. package/cjs/document/data-type/extended-types/field-path.type.js +6 -2
  21. package/cjs/document/data-type/extended-types/filter.type.js +11 -4
  22. package/cjs/document/data-type/extended-types/object-id.type.js +1 -0
  23. package/cjs/document/data-type/extended-types/operation-result.type.js +1 -0
  24. package/cjs/document/data-type/extended-types/time.type.js +1 -0
  25. package/cjs/document/data-type/extended-types/url.type.js +1 -0
  26. package/cjs/document/data-type/extended-types/uuid.type.js +1 -0
  27. package/cjs/document/data-type/mapped-type.js +6 -3
  28. package/cjs/document/data-type/mixin-type.js +7 -4
  29. package/cjs/document/data-type/primitive-types/any.type.js +1 -0
  30. package/cjs/document/data-type/primitive-types/bigint.type.js +1 -0
  31. package/cjs/document/data-type/primitive-types/boolean.type.js +1 -0
  32. package/cjs/document/data-type/primitive-types/integer.type.js +1 -0
  33. package/cjs/document/data-type/primitive-types/null.type.js +1 -0
  34. package/cjs/document/data-type/primitive-types/number.type.js +1 -0
  35. package/cjs/document/data-type/primitive-types/string.type.js +1 -0
  36. package/cjs/document/data-type/simple-type.js +10 -3
  37. package/cjs/document/decorators/complex-type.decorator.js +1 -1
  38. package/cjs/document/decorators/simple-type.decorator.js +1 -1
  39. package/cjs/document/factory/api-document.factory.js +1 -0
  40. package/cjs/document/http/http-api.js +2 -2
  41. package/cjs/document/http/http-controller.js +5 -5
  42. package/cjs/document/http/http-media-type.js +3 -3
  43. package/cjs/document/http/http-multipart-field.js +2 -2
  44. package/cjs/document/http/http-operation-response.js +3 -3
  45. package/cjs/document/http/http-operation.js +5 -5
  46. package/cjs/document/http/http-parameter.js +2 -2
  47. package/cjs/document/http/http-request-body.js +4 -2
  48. package/cjs/filter/filter-rules.js +5 -4
  49. package/esm/document/api-document.js +13 -8
  50. package/esm/document/common/api-base.js +2 -1
  51. package/esm/document/common/document-init-context.js +5 -0
  52. package/esm/document/common/document-node.js +25 -29
  53. package/esm/document/common/value.js +6 -2
  54. package/esm/document/constants.js +0 -1
  55. package/esm/document/data-type/api-field.js +16 -3
  56. package/esm/document/data-type/complex-type-base.js +12 -3
  57. package/esm/document/data-type/complex-type.js +12 -5
  58. package/esm/document/data-type/data-type.js +16 -1
  59. package/esm/document/data-type/enum-type.js +9 -2
  60. package/esm/document/data-type/extended-types/base64.type.js +1 -0
  61. package/esm/document/data-type/extended-types/date-string.type.js +1 -0
  62. package/esm/document/data-type/extended-types/date-time-string.type.js +1 -0
  63. package/esm/document/data-type/extended-types/date-time.type.js +1 -0
  64. package/esm/document/data-type/extended-types/date.type.js +1 -0
  65. package/esm/document/data-type/extended-types/email.type.js +1 -0
  66. package/esm/document/data-type/extended-types/field-path.type.js +6 -2
  67. package/esm/document/data-type/extended-types/filter.type.js +11 -4
  68. package/esm/document/data-type/extended-types/object-id.type.js +1 -0
  69. package/esm/document/data-type/extended-types/operation-result.type.js +1 -0
  70. package/esm/document/data-type/extended-types/time.type.js +1 -0
  71. package/esm/document/data-type/extended-types/url.type.js +1 -0
  72. package/esm/document/data-type/extended-types/uuid.type.js +1 -0
  73. package/esm/document/data-type/mapped-type.js +6 -3
  74. package/esm/document/data-type/mixin-type.js +7 -4
  75. package/esm/document/data-type/primitive-types/any.type.js +1 -0
  76. package/esm/document/data-type/primitive-types/bigint.type.js +1 -0
  77. package/esm/document/data-type/primitive-types/boolean.type.js +1 -0
  78. package/esm/document/data-type/primitive-types/integer.type.js +1 -0
  79. package/esm/document/data-type/primitive-types/null.type.js +1 -0
  80. package/esm/document/data-type/primitive-types/number.type.js +1 -0
  81. package/esm/document/data-type/primitive-types/string.type.js +1 -0
  82. package/esm/document/data-type/simple-type.js +10 -3
  83. package/esm/document/decorators/complex-type.decorator.js +2 -2
  84. package/esm/document/decorators/simple-type.decorator.js +2 -2
  85. package/esm/document/factory/api-document.factory.js +1 -0
  86. package/esm/document/http/http-api.js +2 -2
  87. package/esm/document/http/http-controller.js +5 -5
  88. package/esm/document/http/http-media-type.js +3 -3
  89. package/esm/document/http/http-multipart-field.js +2 -2
  90. package/esm/document/http/http-operation-response.js +3 -3
  91. package/esm/document/http/http-operation.js +5 -5
  92. package/esm/document/http/http-parameter.js +2 -2
  93. package/esm/document/http/http-request-body.js +4 -2
  94. package/esm/filter/filter-rules.js +5 -4
  95. package/package.json +1 -1
  96. package/types/document/api-document.d.ts +8 -2
  97. package/types/document/common/api-base.d.ts +1 -1
  98. package/types/document/common/document-init-context.d.ts +2 -0
  99. package/types/document/common/document-node.d.ts +8 -14
  100. package/types/document/common/value.d.ts +2 -1
  101. package/types/document/constants.d.ts +0 -1
  102. package/types/document/data-type/api-field.d.ts +6 -11
  103. package/types/document/data-type/complex-type.d.ts +2 -1
  104. package/types/document/data-type/data-type.d.ts +7 -2
  105. package/types/document/data-type/enum-type.d.ts +2 -1
  106. package/types/document/data-type/extended-types/field-path.type.d.ts +2 -1
  107. package/types/document/data-type/extended-types/filter.type.d.ts +2 -1
  108. package/types/document/data-type/mapped-type.d.ts +2 -1
  109. package/types/document/data-type/mixin-type.d.ts +2 -1
  110. package/types/document/data-type/simple-type.d.ts +2 -1
  111. package/types/document/factory/api-document.factory.d.ts +2 -1
  112. package/types/document/http/http-api.d.ts +1 -1
  113. package/types/document/http/http-controller.d.ts +2 -1
  114. package/types/document/http/http-media-type.d.ts +2 -1
  115. package/types/document/http/http-multipart-field.d.ts +2 -1
  116. package/types/document/http/http-operation-response.d.ts +2 -1
  117. package/types/document/http/http-operation.d.ts +2 -1
  118. package/types/document/http/http-parameter.d.ts +2 -1
  119. package/types/document/http/http-request-body.d.ts +2 -1
  120. package/types/filter/filter-rules.d.ts +3 -3
@@ -67,13 +67,14 @@ class ApiDocument extends document_element_js_1.DocumentElement {
67
67
  /**
68
68
  * Export as Opra schema definition object
69
69
  */
70
- export() {
70
+ export(options) {
71
71
  const out = (0, objects_1.omitUndefined)({
72
72
  spec: index_js_2.OpraSchema.SpecVersion,
73
73
  id: this.id,
74
74
  url: this.url,
75
75
  info: (0, index_js_1.cloneObject)(this.info, true),
76
76
  });
77
+ options = options || { scopes: this.scopes };
77
78
  if (this.references.size) {
78
79
  let i = 0;
79
80
  const references = {};
@@ -93,25 +94,29 @@ class ApiDocument extends document_element_js_1.DocumentElement {
93
94
  if (this.types.size) {
94
95
  out.types = {};
95
96
  for (const v of this.types.values()) {
96
- out.types[v.name] = v.toJSON();
97
+ if (!v.inScope(options.scopes))
98
+ continue;
99
+ out.types[v.name] = v.toJSON(options);
97
100
  }
98
101
  }
99
102
  if (this.api)
100
- out.api = this.api.toJSON();
103
+ out.api = this.api.toJSON(options);
101
104
  return out;
102
105
  }
103
106
  invalidate() {
104
107
  /** Generate id */
105
- const x = this.export();
108
+ const x = this.export({});
106
109
  delete x.id;
107
110
  this.id = (0, super_fast_md5_1.md5)(JSON.stringify(x));
108
111
  /** Clear [kTypeNSMap] */
109
112
  this[constants_js_1.kTypeNSMap] = new WeakMap();
110
113
  }
111
- _findDataType(nameOrCtor, visitedRefs) {
114
+ _findDataType(nameOrCtor, scope, visitedRefs) {
112
115
  let result = this.types.get(nameOrCtor);
113
- if (result || !this.references.size)
116
+ if (result && result.inScope(scope))
114
117
  return result;
118
+ if (!this.references.size)
119
+ return;
115
120
  // Lookup for references
116
121
  if (typeof nameOrCtor === 'string') {
117
122
  // If given string has namespace pattern (ns:type_name)
@@ -125,7 +130,7 @@ class ApiDocument extends document_element_js_1.DocumentElement {
125
130
  visitedRefs = visitedRefs || new WeakMap();
126
131
  visitedRefs.set(this, true);
127
132
  visitedRefs.set(ref, true);
128
- return ref._findDataType(m[2], visitedRefs);
133
+ return ref._findDataType(m[2], scope, visitedRefs);
129
134
  }
130
135
  nameOrCtor = m[2];
131
136
  }
@@ -147,7 +152,7 @@ class ApiDocument extends document_element_js_1.DocumentElement {
147
152
  for (const refNs of references) {
148
153
  const ref = this.references.get(refNs);
149
154
  visitedRefs.set(ref, true);
150
- result = ref._findDataType(nameOrCtor, visitedRefs);
155
+ result = ref._findDataType(nameOrCtor, scope, visitedRefs);
151
156
  if (result) {
152
157
  this[constants_js_1.kTypeNSMap].set(result, ref?.[constants_js_1.BUILTIN] ? '' : refNs);
153
158
  return result;
@@ -11,7 +11,8 @@ 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,
@@ -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,12 +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() {
23
+ toJSON(options) {
24
24
  const typeName = this.type
25
25
  ? this.node.getDataTypeNameWithNs(this.type)
26
26
  : undefined;
27
27
  return (0, objects_1.omitUndefined)({
28
- type: this.type ? (typeName ? typeName : this.type.toJSON()) : 'any',
28
+ type: this.type
29
+ ? typeName
30
+ ? typeName
31
+ : this.type.toJSON(options)
32
+ : 'any',
29
33
  description: this.description,
30
34
  isArray: this.isArray,
31
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,19 +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() {
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) {
52
65
  const typeName = this.type
53
66
  ? this.node.getDataTypeNameWithNs(this.type)
54
67
  : undefined;
55
68
  return (0, objects_1.omitUndefined)({
56
- type: typeName ? typeName : this.type?.toJSON(),
69
+ type: typeName ? typeName : this.type?.toJSON(options),
57
70
  description: this.description,
58
71
  isArray: this.isArray || undefined,
59
72
  default: this.default,
@@ -149,12 +149,21 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
149
149
  const schema = {};
150
150
  const { currentPath, projection } = context;
151
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;
152
157
  // Process fields
153
158
  let fieldName;
154
159
  for (const field of this.fields.values()) {
155
- if ((context.ignoreReadonlyFields && field.readonly) ||
156
- (context.ignoreWriteonlyFields && field.writeonly) ||
157
- (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)) {
158
167
  schema[field.name] = valgen_1.vg.isUndefined({ coerce: true });
159
168
  continue;
160
169
  }
@@ -71,21 +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() {
74
+ toJSON(options) {
75
75
  const baseName = this.base
76
76
  ? this.node.getDataTypeNameWithNs(this.base)
77
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}`);
78
81
  const out = (0, objects_1.omitUndefined)({
79
82
  ...complex_type_base_js_1.ComplexTypeBase.prototype.toJSON.call(this),
80
83
  kind: this.kind,
81
- base: this.base ? (baseName ? baseName : this.base.toJSON()) : undefined,
84
+ base: this.base
85
+ ? baseName
86
+ ? baseName
87
+ : this.base.toJSON(options)
88
+ : undefined,
82
89
  });
83
90
  if (this.additionalFields) {
84
91
  if (this.additionalFields instanceof data_type_js_1.DataType) {
85
92
  const typeName = this.node.getDataTypeNameWithNs(this.additionalFields);
86
93
  out.additionalFields = typeName
87
94
  ? typeName
88
- : this.additionalFields.toJSON();
95
+ : this.additionalFields.toJSON(options);
89
96
  }
90
97
  else
91
98
  out.additionalFields = this.additionalFields;
@@ -94,8 +101,8 @@ class ComplexTypeClass extends complex_type_base_js_1.ComplexTypeBase {
94
101
  const fields = {};
95
102
  let i = 0;
96
103
  for (const field of this.fields.values()) {
97
- if (field.origin === this) {
98
- fields[field.name] = field.toJSON();
104
+ if (field.origin === this && field.inScope(options?.scopes)) {
105
+ fields[field.name] = field.toJSON(options);
99
106
  i++;
100
107
  }
101
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,13 +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() {
54
+ toJSON(options) {
55
55
  const baseName = this.base
56
56
  ? this.node.getDataTypeNameWithNs(this.base)
57
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}`);
58
61
  return (0, objects_1.omitUndefined)({
59
62
  ...data_type_js_1.DataType.prototype.toJSON.call(this),
60
- base: this.base ? (baseName ? baseName : this.base.toJSON()) : undefined,
63
+ base: this.base
64
+ ? baseName
65
+ ? baseName
66
+ : this.base.toJSON(options)
67
+ : undefined,
61
68
  attributes: (0, index_js_1.cloneObject)(this.ownAttributes),
62
69
  });
63
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',
@@ -56,6 +56,7 @@ tslib_1.__decorate([
56
56
  ], DateTimeType.prototype, "maxValue", void 0);
57
57
  exports.DateTimeType = DateTimeType = tslib_1.__decorate([
58
58
  ((0, simple_type_js_1.SimpleType)({
59
+ name: 'datetime',
59
60
  description: 'A full datetime value',
60
61
  nameMappings: {
61
62
  js: 'string',
@@ -56,6 +56,7 @@ tslib_1.__decorate([
56
56
  ], DateType.prototype, "maxValue", void 0);
57
57
  exports.DateType = DateType = tslib_1.__decorate([
58
58
  ((0, simple_type_js_1.SimpleType)({
59
+ name: 'date',
59
60
  description: 'A date without time',
60
61
  nameMappings: {
61
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,15 +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
28
  const typeName = dataType
29
29
  ? element.node.getDataTypeNameWithNs(dataType)
30
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}`);
31
34
  return {
32
- dataType: typeName ? typeName : dataType.toJSON(),
35
+ dataType: typeName ? typeName : dataType.toJSON(options),
33
36
  allowSigns: properties.allowSigns,
34
37
  };
35
38
  }
@@ -51,6 +54,7 @@ tslib_1.__decorate([
51
54
  ], FieldPathType.prototype, "allowSigns", void 0);
52
55
  exports.FieldPathType = FieldPathType = tslib_1.__decorate([
53
56
  (0, simple_type_js_1.SimpleType)({
57
+ name: 'fieldpath',
54
58
  description: 'Field path',
55
59
  nameMappings: {
56
60
  js: 'string',
@@ -24,12 +24,18 @@ let FilterType = class FilterType {
24
24
  [constants_js_1.ENCODER]() {
25
25
  return encodeFilter;
26
26
  }
27
- toJSON(properties, element) {
27
+ toJSON(properties, element, options) {
28
28
  const dataType = properties.dataType
29
29
  ? element.node.getComplexType(properties.dataType)
30
30
  : element.node.getComplexType('object');
31
+ const typeName = dataType
32
+ ? element.node.getDataTypeNameWithNs(dataType)
33
+ : undefined;
34
+ if (options?.scopes && !dataType.inScope(options?.scopes))
35
+ throw new TypeError(`Data type ${typeName ? '(' + typeName + ')' : ''} ` +
36
+ `is not in required scope(s) [${options.scopes}`);
31
37
  return {
32
- dataType: dataType.name ? dataType.name : dataType.toJSON(),
38
+ dataType: typeName ? typeName : dataType.toJSON(options),
33
39
  rules: properties.rules,
34
40
  };
35
41
  }
@@ -50,6 +56,7 @@ tslib_1.__decorate([
50
56
  ], FilterType.prototype, "rules", void 0);
51
57
  exports.FilterType = FilterType = tslib_1.__decorate([
52
58
  (0, simple_type_js_1.SimpleType)({
59
+ name: 'filter',
53
60
  description: 'A query filter',
54
61
  nameMappings: {
55
62
  js: 'object',
@@ -58,12 +65,12 @@ exports.FilterType = FilterType = tslib_1.__decorate([
58
65
  }),
59
66
  tslib_1.__metadata("design:paramtypes", [Object])
60
67
  ], FilterType);
61
- const decodeFilter = (dataType, rules) => (0, valgen_1.validator)('decodeFilter', (input, context, _this) => {
68
+ const decodeFilter = (dataType, rules, element) => (0, valgen_1.validator)('decodeFilter', (input, context, _this) => {
62
69
  if (typeof input === 'string') {
63
70
  try {
64
71
  const filter = index_js_1.OpraFilter.parse(input);
65
72
  if (rules)
66
- return rules.normalizeFilter(filter, dataType);
73
+ return rules.normalizeFilter(filter, dataType, element);
67
74
  return filter;
68
75
  }
69
76
  catch (e) {
@@ -20,6 +20,7 @@ let ObjectIdType = class ObjectIdType {
20
20
  exports.ObjectIdType = ObjectIdType;
21
21
  exports.ObjectIdType = ObjectIdType = tslib_1.__decorate([
22
22
  (0, simple_type_js_1.SimpleType)({
23
+ name: 'ObjectId',
23
24
  description: 'A MongoDB ObjectID value',
24
25
  nameMappings: {
25
26
  js: 'object',
@@ -41,6 +41,7 @@ tslib_1.__decorate([
41
41
  ], OperationResult.prototype, "errors", void 0);
42
42
  exports.OperationResult = OperationResult = tslib_1.__decorate([
43
43
  (0, complex_type_js_1.ComplexType)({
44
+ name: 'OperationResult',
44
45
  description: 'Operation result',
45
46
  }),
46
47
  tslib_1.__metadata("design:paramtypes", [Object])
@@ -42,6 +42,7 @@ tslib_1.__decorate([
42
42
  ], TimeType.prototype, "maxValue", void 0);
43
43
  exports.TimeType = TimeType = tslib_1.__decorate([
44
44
  ((0, simple_type_js_1.SimpleType)({
45
+ name: 'time',
45
46
  description: 'Time string in 24h format',
46
47
  nameMappings: {
47
48
  js: 'string',
@@ -20,6 +20,7 @@ let UrlType = class UrlType {
20
20
  exports.UrlType = UrlType;
21
21
  exports.UrlType = UrlType = tslib_1.__decorate([
22
22
  ((0, simple_type_js_1.SimpleType)({
23
+ name: 'url',
23
24
  description: 'A Uniform Resource Identifier Reference (RFC 3986 icon) value',
24
25
  nameMappings: {
25
26
  js: 'string',
@@ -26,6 +26,7 @@ tslib_1.__decorate([
26
26
  ], UuidType.prototype, "version", void 0);
27
27
  exports.UuidType = UuidType = tslib_1.__decorate([
28
28
  (0, simple_type_js_1.SimpleType)({
29
+ name: 'uuid',
29
30
  description: 'A Universal Unique Identifier (UUID) value',
30
31
  nameMappings: {
31
32
  js: 'string',
@@ -88,13 +88,16 @@ class MappedTypeClass extends complex_type_base_js_1.ComplexTypeBase {
88
88
  return true;
89
89
  return !!this.base?.extendsFrom(baseType);
90
90
  }
91
- toJSON() {
91
+ toJSON(options) {
92
92
  const baseName = this.base
93
93
  ? this.node.getDataTypeNameWithNs(this.base)
94
94
  : undefined;
95
+ if (options?.scopes && !this.base?.inScope(options?.scopes))
96
+ throw new TypeError(`Base type ${baseName ? '(' + baseName + ')' : ''} of ${this.name ? +this.name : 'embedded'} type ` +
97
+ `is not in required scope(s) [${options.scopes}`);
95
98
  return (0, objects_1.omitUndefined)({
96
- ...complex_type_base_js_1.ComplexTypeBase.prototype.toJSON.call(this),
97
- base: baseName ? baseName : this.base.toJSON(),
99
+ ...complex_type_base_js_1.ComplexTypeBase.prototype.toJSON.call(this, options),
100
+ base: baseName ? baseName : this.base.toJSON(options),
98
101
  kind: this.kind,
99
102
  pick: this.pick,
100
103
  omit: this.omit,
@@ -57,13 +57,16 @@ class MixinTypeClass extends complex_type_base_js_1.ComplexTypeBase {
57
57
  }
58
58
  return false;
59
59
  }
60
- toJSON() {
60
+ toJSON(options) {
61
61
  return (0, objects_1.omitUndefined)({
62
62
  ...complex_type_base_js_1.ComplexTypeBase.prototype.toJSON.call(this),
63
63
  kind: this.kind,
64
- types: this.types.map(t => {
65
- const baseName = this.node.getDataTypeNameWithNs(t);
66
- return baseName ? baseName : t.toJSON();
64
+ types: this.types.map(base => {
65
+ const baseName = this.node.getDataTypeNameWithNs(base);
66
+ if (options?.scopes && !base?.inScope(options?.scopes))
67
+ throw new TypeError(`Base type ${baseName ? '(' + baseName + ')' : ''} of ${this.name ? +this.name : 'embedded'} type ` +
68
+ `is not in required scope(s) [${options.scopes}`);
69
+ return baseName ? baseName : base.toJSON(options);
67
70
  }),
68
71
  });
69
72
  }
@@ -20,6 +20,7 @@ let AnyType = class AnyType {
20
20
  exports.AnyType = AnyType;
21
21
  exports.AnyType = AnyType = tslib_1.__decorate([
22
22
  (0, simple_type_js_1.SimpleType)({
23
+ name: 'any',
23
24
  description: 'Represents any value',
24
25
  }),
25
26
  tslib_1.__metadata("design:paramtypes", [Object])
@@ -27,6 +27,7 @@ let BigintType = class BigintType extends number_type_js_1.NumberType {
27
27
  exports.BigintType = BigintType;
28
28
  exports.BigintType = BigintType = tslib_1.__decorate([
29
29
  (0, simple_type_js_1.SimpleType)({
30
+ name: 'bigint',
30
31
  description: 'BigInt number',
31
32
  nameMappings: {
32
33
  js: 'bigint',