@opra/common 0.21.0 → 0.23.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 (154) hide show
  1. package/browser.js +810 -1427
  2. package/cjs/document/api-document.js +8 -4
  3. package/cjs/document/data-type/api-field.js +2 -2
  4. package/cjs/document/data-type/complex-type.js +17 -63
  5. package/cjs/document/data-type/data-type.js +0 -9
  6. package/cjs/document/data-type/enum-type.js +2 -8
  7. package/cjs/document/data-type/mapped-type.js +0 -36
  8. package/cjs/document/data-type/simple-type.js +2 -8
  9. package/cjs/document/data-type/union-type.js +0 -36
  10. package/cjs/document/index.js +2 -0
  11. package/cjs/document/resource/collection.js +75 -32
  12. package/cjs/document/resource/singleton.js +31 -20
  13. package/cjs/document/resource/storage.js +6 -20
  14. package/cjs/document/utils/generate-codec.js +39 -0
  15. package/cjs/exception/resource-errors/resource-not-found.error.js +1 -1
  16. package/cjs/helpers/index.js +1 -1
  17. package/cjs/helpers/is-url-string.js +14 -0
  18. package/cjs/helpers/object-utils.js +2 -2
  19. package/cjs/helpers/responsive-map.js +4 -4
  20. package/cjs/helpers/type-guards.js +15 -3
  21. package/cjs/http/enums/http-headers-codes.enum.js +3 -5
  22. package/cjs/http/enums/http-status-codes.enum.js +1 -1
  23. package/cjs/http/index.js +2 -9
  24. package/cjs/http/opra-url-path.js +251 -0
  25. package/cjs/{url → http}/opra-url.js +53 -109
  26. package/cjs/i18n/i18n.js +3 -3
  27. package/cjs/index.js +0 -2
  28. package/cjs/schema/opra-schema.ns.js +1 -1
  29. package/cjs/schema/resource/operation.interface.js +2 -0
  30. package/esm/document/api-document.js +10 -6
  31. package/esm/document/data-type/api-field.js +2 -2
  32. package/esm/document/data-type/complex-type.js +13 -59
  33. package/esm/document/data-type/data-type.js +0 -9
  34. package/esm/document/data-type/enum-type.js +2 -8
  35. package/esm/document/data-type/mapped-type.js +0 -36
  36. package/esm/document/data-type/simple-type.js +2 -8
  37. package/esm/document/data-type/union-type.js +0 -36
  38. package/esm/document/index.js +2 -0
  39. package/esm/document/resource/collection.js +75 -32
  40. package/esm/document/resource/singleton.js +31 -20
  41. package/esm/document/resource/storage.js +6 -20
  42. package/esm/document/utils/generate-codec.js +33 -0
  43. package/esm/exception/resource-errors/resource-not-found.error.js +1 -1
  44. package/esm/helpers/index.js +1 -1
  45. package/esm/helpers/is-url-string.js +9 -0
  46. package/esm/helpers/object-utils.js +2 -2
  47. package/esm/helpers/responsive-map.js +4 -4
  48. package/esm/helpers/type-guards.js +11 -2
  49. package/esm/http/enums/http-headers-codes.enum.js +3 -5
  50. package/esm/http/enums/http-status-codes.enum.js +1 -1
  51. package/esm/http/index.js +2 -9
  52. package/esm/http/opra-url-path.js +246 -0
  53. package/esm/{url → http}/opra-url.js +53 -109
  54. package/esm/i18n/i18n.js +4 -4
  55. package/esm/index.js +0 -2
  56. package/esm/schema/opra-schema.ns.js +1 -1
  57. package/esm/schema/resource/operation.interface.js +1 -0
  58. package/package.json +1 -1
  59. package/types/document/api-document.d.ts +4 -1
  60. package/types/document/data-type/complex-type.d.ts +6 -11
  61. package/types/document/data-type/data-type.d.ts +0 -6
  62. package/types/document/data-type/enum-type.d.ts +2 -4
  63. package/types/document/data-type/mapped-type.d.ts +0 -4
  64. package/types/document/data-type/simple-type.d.ts +2 -4
  65. package/types/document/data-type/union-type.d.ts +0 -5
  66. package/types/document/index.d.ts +2 -0
  67. package/types/document/interfaces/collection-resource.interface.d.ts +10 -0
  68. package/types/document/interfaces/singleton-resource.interface.d.ts +7 -0
  69. package/types/document/interfaces/storage-resource.interface.d.ts +8 -0
  70. package/types/document/resource/collection.d.ts +42 -36
  71. package/types/document/resource/resource.d.ts +2 -1
  72. package/types/document/resource/singleton.d.ts +24 -21
  73. package/types/document/resource/storage.d.ts +14 -17
  74. package/types/document/utils/generate-codec.d.ts +10 -0
  75. package/types/filter/errors.d.ts +2 -2
  76. package/types/helpers/index.d.ts +1 -1
  77. package/types/helpers/is-url-string.d.ts +2 -0
  78. package/types/helpers/object-utils.d.ts +1 -1
  79. package/types/helpers/type-guards.d.ts +3 -0
  80. package/types/http/enums/http-headers-codes.enum.d.ts +2 -4
  81. package/types/http/enums/http-status-codes.enum.d.ts +1 -1
  82. package/types/http/index.d.ts +2 -9
  83. package/types/http/opra-url-path.d.ts +54 -0
  84. package/types/{url → http}/opra-url.d.ts +9 -13
  85. package/types/index.d.ts +0 -2
  86. package/types/schema/opra-schema.ns.d.ts +1 -1
  87. package/types/schema/resource/collection.interface.d.ts +29 -8
  88. package/types/schema/resource/operation.interface.d.ts +3 -0
  89. package/types/schema/resource/resource.interface.d.ts +1 -0
  90. package/types/schema/resource/singleton.interface.d.ts +5 -5
  91. package/types/schema/resource/storage.interface.d.ts +42 -5
  92. package/cjs/helpers/is-url.js +0 -8
  93. package/cjs/http/codecs/boolean-codec.js +0 -24
  94. package/cjs/http/codecs/date-codec.js +0 -41
  95. package/cjs/http/codecs/filter-codec.js +0 -17
  96. package/cjs/http/codecs/integer-codec.js +0 -19
  97. package/cjs/http/codecs/number-codec.js +0 -24
  98. package/cjs/http/codecs/string-codec.js +0 -23
  99. package/cjs/http/http-params.js +0 -353
  100. package/cjs/http/multipart/batch-multipart.js +0 -170
  101. package/cjs/http/multipart/http-request-content.js +0 -17
  102. package/cjs/http/multipart/http-response-content.js +0 -14
  103. package/cjs/http/multipart/index.js +0 -2
  104. package/cjs/url/index.js +0 -8
  105. package/cjs/url/opra-url-path-component.js +0 -30
  106. package/cjs/url/opra-url-path.js +0 -155
  107. package/cjs/url/utils/decode-path-component.js +0 -41
  108. package/cjs/url/utils/encode-path-component.js +0 -27
  109. package/cjs/utils/path-utils.js +0 -24
  110. package/esm/helpers/is-url.js +0 -4
  111. package/esm/http/codecs/boolean-codec.js +0 -20
  112. package/esm/http/codecs/date-codec.js +0 -37
  113. package/esm/http/codecs/filter-codec.js +0 -13
  114. package/esm/http/codecs/integer-codec.js +0 -15
  115. package/esm/http/codecs/number-codec.js +0 -20
  116. package/esm/http/codecs/string-codec.js +0 -19
  117. package/esm/http/http-params.js +0 -348
  118. package/esm/http/multipart/batch-multipart.js +0 -170
  119. package/esm/http/multipart/http-request-content.js +0 -17
  120. package/esm/http/multipart/http-response-content.js +0 -14
  121. package/esm/http/multipart/index.js +0 -2
  122. package/esm/url/index.js +0 -5
  123. package/esm/url/opra-url-path-component.js +0 -26
  124. package/esm/url/opra-url-path.js +0 -151
  125. package/esm/url/utils/decode-path-component.js +0 -37
  126. package/esm/url/utils/encode-path-component.js +0 -22
  127. package/esm/utils/path-utils.js +0 -19
  128. package/types/helpers/is-url.d.ts +0 -1
  129. package/types/http/codecs/boolean-codec.d.ts +0 -5
  130. package/types/http/codecs/date-codec.d.ts +0 -16
  131. package/types/http/codecs/filter-codec.d.ts +0 -6
  132. package/types/http/codecs/integer-codec.d.ts +0 -11
  133. package/types/http/codecs/number-codec.d.ts +0 -14
  134. package/types/http/codecs/string-codec.d.ts +0 -16
  135. package/types/http/http-params.d.ts +0 -114
  136. package/types/http/interfaces/client-http-headers.interface.d.ts +0 -65
  137. package/types/http/interfaces/server-http-headers.interface.d.ts +0 -1
  138. package/types/http/multipart/batch-multipart.d.ts +0 -0
  139. package/types/http/multipart/http-request-content.d.ts +0 -0
  140. package/types/http/multipart/http-response-content.d.ts +0 -0
  141. package/types/http/multipart/index.d.ts +0 -0
  142. package/types/schema/resource/endpoint.interface.d.ts +0 -29
  143. package/types/url/index.d.ts +0 -5
  144. package/types/url/opra-url-path-component.d.ts +0 -15
  145. package/types/url/opra-url-path.d.ts +0 -36
  146. package/types/url/utils/decode-path-component.d.ts +0 -5
  147. package/types/url/utils/encode-path-component.d.ts +0 -1
  148. package/types/utils/path-utils.d.ts +0 -2
  149. /package/cjs/{http/interfaces/client-http-headers.interface.js → document/interfaces/collection-resource.interface.js} +0 -0
  150. /package/cjs/{http/interfaces/server-http-headers.interface.js → document/interfaces/singleton-resource.interface.js} +0 -0
  151. /package/cjs/{schema/resource/endpoint.interface.js → document/interfaces/storage-resource.interface.js} +0 -0
  152. /package/esm/{http/interfaces/client-http-headers.interface.js → document/interfaces/collection-resource.interface.js} +0 -0
  153. /package/esm/{http/interfaces/server-http-headers.interface.js → document/interfaces/singleton-resource.interface.js} +0 -0
  154. /package/esm/{schema/resource/endpoint.interface.js → document/interfaces/storage-resource.interface.js} +0 -0
@@ -3,48 +3,37 @@ var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.OpraURL = void 0;
5
5
  const fast_tokenizer_1 = require("fast-tokenizer");
6
- const index_js_1 = require("../http/index.js");
7
- const path_utils_js_1 = require("../utils/path-utils.js");
8
6
  const opra_url_path_js_1 = require("./opra-url-path.js");
9
- const decode_path_component_js_1 = require("./utils/decode-path-component.js");
10
7
  const nodeInspectCustom = Symbol.for('nodejs.util.inspect.custom');
11
8
  const urlRegEx = /^(?:((?:[A-Z][A-Z+-.]+:)+)\/\/([^/?]+))?(.*)?$/i;
12
9
  const schemeRegEx = /^([A-Z][A-Z+-.]+:?)+$/i;
13
10
  const hostRegEx = /^([^/:]+)(?::(\d+))?$/;
14
11
  const hostnameRegEx = /^([^/:]+)$/;
15
- const kContext = Symbol('kContext');
16
- const kPath = Symbol('kPath');
17
- const kParams = Symbol('kParams');
12
+ const kContext = Symbol.for('kContext');
13
+ const kPath = Symbol.for('kPath');
14
+ const kSearchParams = Symbol.for('kSearchParams');
18
15
  class OpraURL {
19
16
  constructor(input, base) {
20
17
  this[_a] = {
21
18
  protocol: '',
22
19
  username: '',
23
- prefix: '',
24
20
  hostname: '',
25
21
  port: '',
26
22
  hash: '',
27
23
  password: ''
28
24
  };
29
- this[kPath] = new opra_url_path_js_1.OpraURLPath('', {
30
- onChange: () => {
31
- this[kContext].pathname = undefined;
32
- this[kContext].address = undefined;
33
- }
34
- });
35
- this[kParams] = new index_js_1.HttpParams('', {
36
- onChange: () => {
37
- this[kContext].search = undefined;
38
- }
39
- });
25
+ this[kSearchParams] = new URLSearchParams();
26
+ this[kPath] = new opra_url_path_js_1.OpraURLPath();
40
27
  if (input)
41
- this.parse(typeof input === 'object' ? input.toString() : input);
42
- if (base) {
28
+ this._parse(String(input));
29
+ if (base && !this.host) {
43
30
  const baseUrl = base instanceof OpraURL ? base : new OpraURL(base);
44
31
  this[kContext].protocol = baseUrl.protocol;
45
32
  this[kContext].hostname = baseUrl.hostname;
33
+ this[kContext].username = baseUrl.username;
34
+ this[kContext].password = baseUrl.password;
46
35
  this[kContext].port = baseUrl.port;
47
- this[kContext].prefix = baseUrl.pathname;
36
+ this.path = opra_url_path_js_1.OpraURLPath.join(baseUrl.path, this.path);
48
37
  }
49
38
  }
50
39
  get address() {
@@ -58,7 +47,6 @@ class OpraURL {
58
47
  : '') + this.host;
59
48
  }
60
49
  this[kContext].address = address +
61
- (this.prefix !== '/' ? this.prefix : '') +
62
50
  (this.pathname !== '/' ? this.pathname : '');
63
51
  }
64
52
  return this[kContext].address;
@@ -96,7 +84,7 @@ class OpraURL {
96
84
  }
97
85
  else
98
86
  this[kContext].hostname = '';
99
- this[kContext].address = undefined;
87
+ this.invalidate();
100
88
  }
101
89
  get href() {
102
90
  return this.address + this.search + this.hash;
@@ -106,7 +94,7 @@ class OpraURL {
106
94
  }
107
95
  set password(v) {
108
96
  this[kContext].password = v ?? '';
109
- this[kContext].address = undefined;
97
+ this.invalidate();
110
98
  }
111
99
  get port() {
112
100
  return this[kContext].port;
@@ -115,8 +103,8 @@ class OpraURL {
115
103
  if (value) {
116
104
  // noinspection SuspiciousTypeOfGuard
117
105
  const v = typeof value === 'number' ? value : parseInt(value, 10);
118
- if (isNaN(v) || v < 1 || v > 35535 || v % 1 > 0)
119
- throw Object.assign(new TypeError('Invalid port'), {
106
+ if (isNaN(v) || v < 1 || v > 65535 || v % 1 > 0)
107
+ throw Object.assign(new TypeError(`Invalid port number (${value})`), {
120
108
  hostname: v,
121
109
  code: 'ERR_INVALID_URL'
122
110
  });
@@ -124,18 +112,7 @@ class OpraURL {
124
112
  }
125
113
  else
126
114
  this[kContext].port = '';
127
- }
128
- get prefix() {
129
- return this[kContext].prefix;
130
- }
131
- set prefix(value) {
132
- if (value) {
133
- const url = new OpraURL(value);
134
- this[kContext].prefix = url.pathname;
135
- }
136
- else
137
- this[kContext].prefix = '';
138
- this[kContext].address = undefined;
115
+ this.invalidate();
139
116
  }
140
117
  get protocol() {
141
118
  return this[kContext].protocol;
@@ -151,14 +128,14 @@ class OpraURL {
151
128
  }
152
129
  else
153
130
  this[kContext].protocol = '';
154
- this[kContext].address = undefined;
131
+ this.invalidate();
155
132
  }
156
133
  get username() {
157
134
  return this[kContext].username;
158
135
  }
159
136
  set username(v) {
160
137
  this[kContext].username = v ?? '';
161
- this[kContext].address = undefined;
138
+ this.invalidate();
162
139
  }
163
140
  get origin() {
164
141
  return this.hostname ? (this.protocol + '//' + this.hostname) : '';
@@ -166,13 +143,20 @@ class OpraURL {
166
143
  get path() {
167
144
  return this[kPath];
168
145
  }
146
+ set path(path) {
147
+ // noinspection SuspiciousTypeOfGuard
148
+ this[kPath] = path instanceof opra_url_path_js_1.OpraURLPath ? path : new opra_url_path_js_1.OpraURLPath(path);
149
+ this[kContext].pathname = String(this[kPath]);
150
+ this.invalidate();
151
+ }
169
152
  get pathname() {
170
153
  if (this[kContext].pathname == null)
171
- this[kContext].pathname = '/' + this[kPath].toString();
154
+ this[kContext].pathname = this.path.toString() || '/';
172
155
  return this[kContext].pathname;
173
156
  }
174
157
  set pathname(v) {
175
- this._setPathname(v, false);
158
+ this[kPath] = new opra_url_path_js_1.OpraURLPath(v);
159
+ this.invalidate();
176
160
  }
177
161
  get hash() {
178
162
  return this[kContext].hash;
@@ -181,23 +165,36 @@ class OpraURL {
181
165
  this[kContext].hash = v ? (v.startsWith('#') ? v : '#' + v) : '';
182
166
  }
183
167
  get search() {
184
- if (this[kContext].search == null) {
185
- const s = this[kParams].toString();
186
- this[kContext].search = s ? ('?' + s) : '';
187
- }
188
- return this[kContext].search;
168
+ const s = this[kSearchParams].toString();
169
+ return s ? '?' + s : '';
189
170
  }
190
171
  set search(v) {
191
- if (v) {
192
- this[kParams].clear();
193
- this[kParams].appendAll(v);
194
- }
195
- this[kContext].search = undefined;
172
+ this[kSearchParams] = new URLSearchParams(v);
196
173
  }
197
174
  get searchParams() {
198
- return this[kParams];
175
+ return this[kSearchParams];
176
+ }
177
+ set setSearchParams(v) {
178
+ this[kSearchParams] = v;
179
+ }
180
+ invalidate() {
181
+ this[kContext].address = undefined;
182
+ this[kContext].pathname = undefined;
183
+ }
184
+ join(...items) {
185
+ this.path = this.path.join(...items);
186
+ this.invalidate();
187
+ return this;
188
+ }
189
+ resolve(...items) {
190
+ this.path = this.path.resolve(...items);
191
+ this.invalidate();
192
+ return this;
199
193
  }
200
- parse(input) {
194
+ toString() {
195
+ return this.href;
196
+ }
197
+ _parse(input) {
201
198
  const m = urlRegEx.exec(input);
202
199
  if (!m)
203
200
  throw Object.assign(new TypeError('Invalid URL'), {
@@ -227,16 +224,9 @@ class OpraURL {
227
224
  input = tokenizer.next() || '';
228
225
  this.hash = tokenizer.join('#');
229
226
  tokenizer = (0, fast_tokenizer_1.tokenize)(input, { delimiters: '?', quotes: true, brackets: true });
230
- this._setPathname(tokenizer.next() || '', isAbsolute);
227
+ this.path = new opra_url_path_js_1.OpraURLPath(tokenizer.next());
231
228
  this.search = tokenizer.join('&');
232
229
  }
233
- join(...source) {
234
- this.path.join(...source);
235
- return this;
236
- }
237
- toString() {
238
- return this.href;
239
- }
240
230
  /* istanbul ignore next */
241
231
  [(_a = kContext, nodeInspectCustom)]() {
242
232
  // this._update();
@@ -247,60 +237,14 @@ class OpraURL {
247
237
  host: this.host,
248
238
  hostname: this.hostname,
249
239
  origin: this.origin,
250
- pathPrefix: this.prefix,
251
240
  path: this.path,
252
241
  pathname: this.pathname,
253
242
  search: this.search,
254
243
  hash: this.hash,
255
244
  };
256
245
  }
257
- //
258
- // protected _update() {
259
- // if (!this[kContext].needUpdate)
260
- // return;
261
- // const ctx = this[kContext];
262
- // ctx.needUpdate = false;
263
- // let s = this.path.toString();
264
- // ctx.pathname = s ? '/' + s : '';
265
- // s = this.searchParams.toString();
266
- // ctx.search = s ? '?' + s : '';
267
- //
268
- // let address = '';
269
- // if (ctx.hostname) {
270
- // address += (ctx.protocol || 'http:') + '//' +
271
- // (ctx.username || ctx.password
272
- // ? (
273
- // (ctx.username ? encodeURIComponent(ctx.username) : '') +
274
- // (ctx.password ? ':' + encodeURIComponent(ctx.password) : '') + '@'
275
- // )
276
- // : '') + this.host;
277
- // }
278
- // ctx.address = address + ctx.prefix + ctx.pathname;
279
- // }
280
- _setPathname(v, trimPrefix) {
281
- this.path.clear();
282
- if (!v)
283
- return;
284
- const pathTokenizer = (0, fast_tokenizer_1.tokenize)((0, path_utils_js_1.normalizePath)(v, true), {
285
- delimiters: '/', quotes: true, brackets: true,
286
- });
287
- if (trimPrefix && this.prefix) {
288
- const prefixTokenizer = (0, fast_tokenizer_1.tokenize)((0, path_utils_js_1.normalizePath)(this.prefix, true), {
289
- delimiters: '/', quotes: true, brackets: true,
290
- });
291
- for (const a of prefixTokenizer) {
292
- const b = pathTokenizer.next();
293
- if (a !== b)
294
- throw Object.assign(new Error('Invalid URL path. pathPrefix does not match'), { path: v, code: 'ERR_INVALID_URL_PATH' });
295
- }
296
- }
297
- for (const x of pathTokenizer) {
298
- const p = (0, decode_path_component_js_1.decodePathComponent)(x);
299
- this.path.join(p);
300
- }
301
- }
302
246
  }
303
247
  exports.OpraURL = OpraURL;
304
248
  OpraURL.kContext = kContext;
305
249
  OpraURL.kPath = kPath;
306
- OpraURL.kParams = kParams;
250
+ OpraURL.kParams = kSearchParams;
package/cjs/i18n/i18n.js CHANGED
@@ -58,7 +58,7 @@ class I18n extends exports.BaseI18n {
58
58
  }
59
59
  async loadResourceBundle(lang, ns, filePath, deep, overwrite) {
60
60
  let obj;
61
- if ((0, index_js_1.isUrl)(filePath)) {
61
+ if ((0, index_js_1.isUrlString)(filePath)) {
62
62
  obj = (await fetch(filePath, { headers: { accept: 'application/json' } })).json();
63
63
  }
64
64
  else {
@@ -126,9 +126,9 @@ class I18n extends exports.BaseI18n {
126
126
  keys.push(token2);
127
127
  }
128
128
  const k = keys.length > 1 ? '$t(' + keys.join(',') + ')' : keys[0];
129
- s += fallback
129
+ s += (fallback
130
130
  ? this.t(k, fallback, { ...options, ...opts })
131
- : this.t(k, { ...options, ...opts });
131
+ : this.t(k, { ...options, ...opts }));
132
132
  continue;
133
133
  }
134
134
  s += token;
package/cjs/index.js CHANGED
@@ -10,7 +10,5 @@ tslib_1.__exportStar(require("./helpers/index.js"), exports);
10
10
  tslib_1.__exportStar(require("./http/index.js"), exports);
11
11
  tslib_1.__exportStar(require("./i18n/index.js"), exports);
12
12
  tslib_1.__exportStar(require("./schema/index.js"), exports);
13
- tslib_1.__exportStar(require("./url/index.js"), exports);
14
- tslib_1.__exportStar(require("./utils/path-utils.js"), exports);
15
13
  var uid_1 = require("uid");
16
14
  Object.defineProperty(exports, "uid", { enumerable: true, get: function () { return uid_1.uid; } });
@@ -10,7 +10,7 @@ tslib_1.__exportStar(require("./data-type/mapped-type.interface.js"), exports);
10
10
  tslib_1.__exportStar(require("./data-type/union-type.interface.js"), exports);
11
11
  tslib_1.__exportStar(require("./resource/collection.interface.js"), exports);
12
12
  tslib_1.__exportStar(require("./resource/container.interface.js"), exports);
13
- tslib_1.__exportStar(require("./resource/endpoint.interface.js"), exports);
13
+ tslib_1.__exportStar(require("./resource/operation.interface.js"), exports);
14
14
  tslib_1.__exportStar(require("./resource/resource.interface.js"), exports);
15
15
  tslib_1.__exportStar(require("./resource/singleton.interface.js"), exports);
16
16
  tslib_1.__exportStar(require("./resource/storage.interface.js"), exports);
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,5 +1,5 @@
1
- import { NotAcceptableError, NotFoundError } from '../exception/index.js';
2
- import { cloneObject, omitUndefined, ResponsiveMap } from '../helpers/index.js';
1
+ import { NotAcceptableError, NotFoundError, ResourceNotFoundError } from '../exception/index.js';
2
+ import { cloneObject, ResponsiveMap } from '../helpers/index.js';
3
3
  import { OpraSchema } from '../schema/index.js';
4
4
  import { NAMESPACE_PATTERN } from './constants.js';
5
5
  import { ComplexType } from './data-type/complex-type.js';
@@ -32,7 +32,7 @@ export class ApiDocument {
32
32
  */
33
33
  getDataType(arg0, silent) {
34
34
  let dataType;
35
- const name = typeof arg0 === 'function' ? arg0.name : arg0;
35
+ const name = typeof arg0 === 'function' ? arg0.name : String(arg0);
36
36
  // Try to get instance from cache
37
37
  const t = typeof arg0 === 'string'
38
38
  ? this._typeCache.get(arg0)
@@ -164,7 +164,7 @@ export class ApiDocument {
164
164
  }
165
165
  if (silent)
166
166
  return;
167
- throw new NotFoundError(`Resource not found (${path})`);
167
+ throw new ResourceNotFoundError(path);
168
168
  }
169
169
  getCollection(path, silent) {
170
170
  const t = this.getResource(path);
@@ -193,7 +193,9 @@ export class ApiDocument {
193
193
  /**
194
194
  * Export as Opra schema definition object
195
195
  */
196
- exportSchema() {
196
+ exportSchema(options) {
197
+ if (this._metadataCache)
198
+ return cloneObject(this._metadataCache, options?.webSafe);
197
199
  const schema = {
198
200
  version: OpraSchema.SpecVersion,
199
201
  url: this.url,
@@ -223,9 +225,11 @@ export class ApiDocument {
223
225
  types[name] = r.exportSchema();
224
226
  }
225
227
  }
226
- return omitUndefined(schema);
228
+ this._metadataCache = schema;
229
+ return this._metadataCache;
227
230
  }
228
231
  invalidate() {
232
+ this._metadataCache = undefined;
229
233
  this._typeCache.clear();
230
234
  this._typesCacheByCtor.clear();
231
235
  }
@@ -67,14 +67,14 @@ export const ApiField = function (...args) {
67
67
  };
68
68
  const proto = {
69
69
  exportSchema() {
70
- return {
70
+ return omitUndefined({
71
71
  type: this.type.name ? this.type.name : this.type.exportSchema(),
72
72
  description: this.description,
73
73
  isArray: this.isArray,
74
74
  default: this.default,
75
75
  fixed: this.fixed,
76
76
  required: this.required
77
- };
77
+ });
78
78
  }
79
79
  };
80
80
  Object.assign(ApiField.prototype, proto);
@@ -1,8 +1,8 @@
1
1
  import 'reflect-metadata';
2
2
  import omit from 'lodash.omit';
3
3
  import merge from 'putil-merge';
4
- import * as vg from 'valgen';
5
4
  import { omitUndefined, ResponsiveMap } from '../../helpers/index.js';
5
+ import { translate } from '../../i18n/index.js';
6
6
  import { OpraSchema } from '../../schema/index.js';
7
7
  import { METADATA_KEY, TYPENAME_PATTERN } from '../constants.js';
8
8
  import { ApiField } from './api-field.js';
@@ -15,7 +15,7 @@ class ComplexTypeClass extends DataType {
15
15
  super(document, init);
16
16
  this.kind = OpraSchema.ComplexType.Kind;
17
17
  const own = this.own = {};
18
- own.ctor = init?.ctor;
18
+ own.ctor = init?.ctor || init?.base?.ctor;
19
19
  own.abstract = init?.abstract;
20
20
  own.additionalFields = init?.additionalFields;
21
21
  own.fields = new ResponsiveMap();
@@ -28,8 +28,6 @@ class ComplexTypeClass extends DataType {
28
28
  if (this.base) {
29
29
  if (this.additionalFields == null)
30
30
  this.additionalFields = this.base.additionalFields;
31
- if (own.ctor == null && this.base instanceof ComplexType)
32
- this.ctor = this.base.ctor;
33
31
  if (this.base.fields)
34
32
  for (const [k, el] of this.base.fields.entries()) {
35
33
  const newEl = new ApiField(this, el);
@@ -65,7 +63,7 @@ class ComplexTypeClass extends DataType {
65
63
  else
66
64
  field = this.fields.get(nameOrPath);
67
65
  if (!field)
68
- throw new Error(`Unknown field "${nameOrPath}"`);
66
+ throw new Error(translate('error:UNKNOWN_FIELD', { field: nameOrPath }));
69
67
  return field;
70
68
  }
71
69
  iteratePath(path, silent) {
@@ -99,7 +97,7 @@ class ComplexTypeClass extends DataType {
99
97
  if (dataType && !dataType.additionalFields) {
100
98
  if (silent)
101
99
  return { done: true, value: [] };
102
- throw new Error(`Unknown or Invalid field (${curPath})`);
100
+ throw new Error(translate('error:UNKNOWN_FIELD', { field: curPath }));
103
101
  }
104
102
  }
105
103
  }
@@ -111,13 +109,15 @@ class ComplexTypeClass extends DataType {
111
109
  };
112
110
  }
113
111
  normalizeFieldPath(fieldPaths) {
114
- if (Array.isArray(fieldPaths))
115
- return fieldPaths.map((s) => this.normalizeFieldPath(s));
116
- let curPath = '';
117
- for (const [, , p] of this.iteratePath(fieldPaths)) {
118
- curPath = p;
119
- }
120
- return curPath;
112
+ const array = (Array.isArray(fieldPaths) ? fieldPaths : [fieldPaths])
113
+ .map(s => {
114
+ let curPath = '';
115
+ for (const [, , p] of this.iteratePath(s)) {
116
+ curPath = p;
117
+ }
118
+ return curPath;
119
+ }).flat();
120
+ return array.length ? array : undefined;
121
121
  }
122
122
  exportSchema() {
123
123
  const out = super.exportSchema();
@@ -147,52 +147,6 @@ class ComplexTypeClass extends DataType {
147
147
  }
148
148
  return false;
149
149
  }
150
- decode(v) {
151
- return this._getDecoder()(v, { coerce: true });
152
- }
153
- encode(v) {
154
- return this._getEncoder()(v, { coerce: true });
155
- }
156
- validate(v) {
157
- return this._getEncoder()(v);
158
- }
159
- _getDecoder() {
160
- if (this._decoder)
161
- return this._decoder;
162
- const schema = {};
163
- for (const f of this.fields.values()) {
164
- let t = f.type._getDecoder();
165
- if (f.isArray)
166
- t = vg.isArray(t);
167
- schema[f.name] = f.required ? vg.required(t) : vg.optional(t);
168
- }
169
- this._decoder = vg.isObject(schema, {
170
- ctor: this.ctor,
171
- additionalFields: this.additionalFields ?? 'ignore',
172
- name: this.name,
173
- caseInSensitive: true,
174
- });
175
- return this._decoder;
176
- }
177
- _getEncoder() {
178
- if (this._encoder)
179
- return this._encoder;
180
- const schema = {};
181
- for (const f of this.fields.values()) {
182
- let t = f.type._getEncoder();
183
- if (f.isArray)
184
- t = vg.isArray(t);
185
- schema[f.name] = t;
186
- }
187
- this._encoder = vg.isObject(schema, {
188
- ctor: this.ctor,
189
- additionalFields: this.additionalFields,
190
- name: this.name,
191
- caseInSensitive: true,
192
- detectCircular: true
193
- });
194
- return this._encoder;
195
- }
196
150
  }
197
151
  /**
198
152
  * @class ComplexType
@@ -8,15 +8,6 @@ export class DataType {
8
8
  this.description = init?.description;
9
9
  this.isAnonymous = !this.name;
10
10
  }
11
- decode(v) {
12
- return this._getDecoder()(v, { coerce: true });
13
- }
14
- encode(v) {
15
- return this._getEncoder()(v, { coerce: true });
16
- }
17
- validate(v) {
18
- return this._getEncoder()(v);
19
- }
20
11
  exportSchema() {
21
12
  return omitUndefined({
22
13
  kind: this.kind,
@@ -15,6 +15,8 @@ class EnumTypeClass extends DataType {
15
15
  this.ownMeanings = init.meanings || {};
16
16
  this.values = { ...this.base?.values, ...this.ownValues };
17
17
  this.meanings = { ...this.base?.meanings, ...this.ownMeanings };
18
+ this.decode = vg.isEnum(Object.values(this.values));
19
+ this.encode = vg.isEnum(Object.values(this.values));
18
20
  }
19
21
  exportSchema() {
20
22
  const out = DataType.prototype.exportSchema.call(this);
@@ -26,14 +28,6 @@ class EnumTypeClass extends DataType {
26
28
  }));
27
29
  return out;
28
30
  }
29
- _getDecoder() {
30
- if (!this._decoder)
31
- this._decoder = vg.isEnum(Object.values(this.values), { enumName: this.name });
32
- return this._decoder;
33
- }
34
- _getEncoder() {
35
- return this._getDecoder();
36
- }
37
31
  }
38
32
  /**
39
33
  * @class EnumType
@@ -1,6 +1,5 @@
1
1
  import 'reflect-metadata';
2
2
  import merge from 'putil-merge';
3
- import * as vg from 'valgen';
4
3
  import { inheritPropertyInitializers, mergePrototype, omitUndefined, ResponsiveMap } from '../../helpers/index.js';
5
4
  import { OpraSchema } from '../../schema/index.js';
6
5
  import { METADATA_KEY } from '../constants.js';
@@ -33,41 +32,6 @@ class MappedTypeClass extends DataType {
33
32
  }));
34
33
  return out;
35
34
  }
36
- _getDecoder() {
37
- if (this._decoder)
38
- return this._decoder;
39
- const schema = {};
40
- for (const f of this.fields.values()) {
41
- let t = f.type.getDecoder();
42
- if (f.isArray)
43
- t = vg.isArray(t);
44
- schema[f.name] = t;
45
- }
46
- this._decoder = vg.isObject(schema, {
47
- additionalFields: this.additionalFields,
48
- name: this.name,
49
- caseInSensitive: true
50
- });
51
- return this._decoder;
52
- }
53
- _getEncoder() {
54
- if (this._encoder)
55
- return this._encoder;
56
- const schema = {};
57
- for (const f of this.fields.values()) {
58
- let t = f.type.getEncoder();
59
- if (f.isArray)
60
- t = vg.isArray(t);
61
- schema[f.name] = t;
62
- }
63
- this._encoder = vg.isObject(schema, {
64
- additionalFields: this.additionalFields,
65
- name: this.name,
66
- caseInSensitive: true,
67
- detectCircular: true
68
- });
69
- return this._encoder;
70
- }
71
35
  }
72
36
  /**
73
37
  * @class MappedType
@@ -13,14 +13,8 @@ class SimpleTypeClass extends DataType {
13
13
  super(document, init);
14
14
  this.kind = OpraSchema.SimpleType.Kind;
15
15
  this.base = init.base;
16
- this._decoder = init.decoder || init.base?._decoder || vg.isAny();
17
- this._encoder = init.encoder || init.base?._encoder || vg.isAny();
18
- }
19
- _getDecoder() {
20
- return this._decoder;
21
- }
22
- _getEncoder() {
23
- return this._encoder;
16
+ this.decode = init.decoder || init.base?.decode || vg.isAny();
17
+ this.encode = init.encoder || init.base?.encode || vg.isAny();
24
18
  }
25
19
  exportSchema() {
26
20
  // noinspection UnnecessaryLocalVariableJS
@@ -1,6 +1,5 @@
1
1
  import 'reflect-metadata';
2
2
  import merge from 'putil-merge';
3
- import * as vg from 'valgen';
4
3
  import { inheritPropertyInitializers, mergePrototype, omitUndefined, ResponsiveMap } from '../../helpers/index.js';
5
4
  import { OpraSchema } from '../../schema/index.js';
6
5
  import { METADATA_KEY } from '../constants.js';
@@ -32,41 +31,6 @@ class UnionTypeClass extends DataType {
32
31
  }));
33
32
  return out;
34
33
  }
35
- _getDecoder() {
36
- if (this._decoder)
37
- return this._decoder;
38
- const schema = {};
39
- for (const f of this.fields.values()) {
40
- let t = f.type.getDecoder();
41
- if (f.isArray)
42
- t = vg.isArray(t);
43
- schema[f.name] = t;
44
- }
45
- this._decoder = vg.isObject(schema, {
46
- additionalFields: this.additionalFields,
47
- name: this.name,
48
- caseInSensitive: true
49
- });
50
- return this._decoder;
51
- }
52
- _getEncoder() {
53
- if (this._encoder)
54
- return this._encoder;
55
- const schema = {};
56
- for (const f of this.fields.values()) {
57
- let t = f.type.getEncoder();
58
- if (f.isArray)
59
- t = vg.isArray(t);
60
- schema[f.name] = t;
61
- }
62
- this._encoder = vg.isObject(schema, {
63
- additionalFields: this.additionalFields,
64
- name: this.name,
65
- caseInSensitive: true,
66
- detectCircular: true
67
- });
68
- return this._encoder;
69
- }
70
34
  }
71
35
  /**
72
36
  * @class UnionType
@@ -13,3 +13,5 @@ export * from './resource/resource.js';
13
13
  export * from './resource/collection.js';
14
14
  export * from './resource/singleton.js';
15
15
  export * from './resource/storage.js';
16
+ export * from './interfaces/collection-resource.interface.js';
17
+ export * from './interfaces/singleton-resource.interface.js';