@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
@@ -1,5 +1,6 @@
1
1
  import omit from 'lodash.omit';
2
2
  import merge from 'putil-merge';
3
+ import * as vg from 'valgen';
3
4
  import { BadRequestError } from '../../exception/index.js';
4
5
  import { OpraFilter } from '../../filter/index.js';
5
6
  import { omitUndefined } from '../../helpers/index.js';
@@ -7,15 +8,18 @@ import { translate } from '../../i18n/index.js';
7
8
  import { OpraSchema } from '../../schema/index.js';
8
9
  import { METADATA_KEY } from '../constants.js';
9
10
  import { SimpleType } from '../data-type/simple-type.js';
11
+ import { generateCodec } from '../utils/generate-codec.js';
10
12
  import { Resource } from './resource.js';
11
- const NESTJS_INJECTABLE_WATERMARK = '__injectable__';
13
+ const NESTJS_INJECTABLE_WATERMARK = '__injectable__'; // todo, put this in nextjs package wia augmentation
12
14
  const NAME_PATTERN = /^(.*)(Resource|Collection)$/;
13
15
  class CollectionClass extends Resource {
14
16
  constructor(document, init) {
15
17
  super(document, init);
18
+ this._decoders = {};
19
+ this._encoders = {};
16
20
  this.kind = OpraSchema.Collection.Kind;
17
21
  this.controller = init.controller;
18
- const operations = this.operations = init.operations || {};
22
+ this.operations = { ...init.operations };
19
23
  const dataType = this.type = init.type;
20
24
  // Validate key fields
21
25
  this.primaryKey = init.primaryKey
@@ -28,19 +32,6 @@ class CollectionClass extends Resource {
28
32
  if (!(field?.type instanceof SimpleType))
29
33
  throw new TypeError(`Only Simple type allowed for primary keys but "${f}" is a ${field.type.kind}`);
30
34
  });
31
- if (this.controller) {
32
- const instance = typeof this.controller == 'function'
33
- ? new this.controller()
34
- : this.controller;
35
- for (const operation of Object.values(operations)) {
36
- if (!operation.handler && operation.handlerName) {
37
- const fn = instance[operation.handlerName];
38
- if (!fn)
39
- throw new TypeError(`No such operation handler (${operation.handlerName}) found`);
40
- operation.handler = fn.bind(instance);
41
- }
42
- }
43
- }
44
35
  }
45
36
  exportSchema() {
46
37
  const out = Resource.prototype.exportSchema.call(this);
@@ -66,7 +57,8 @@ class CollectionClass extends Resource {
66
57
  // decode values
67
58
  for (const [k, v] of Object.entries(obj)) {
68
59
  const el = dataType.getField(k);
69
- obj[k] = el.type.decode(v);
60
+ if (el.type instanceof SimpleType)
61
+ obj[k] = el.type.decode(v);
70
62
  if (obj[k] == null)
71
63
  throw new TypeError(`You must provide value of primary field(s) (${k})`);
72
64
  }
@@ -76,7 +68,9 @@ class CollectionClass extends Resource {
76
68
  if (typeof value === 'object')
77
69
  value = value[primaryKey];
78
70
  const el = dataType.getField(primaryKey);
79
- const result = el.type.decode(value);
71
+ let result;
72
+ if (el.type instanceof SimpleType)
73
+ result = el.type.decode(value);
80
74
  if (result == null)
81
75
  throw new TypeError(`You must provide value of primary field(s) (${primaryKey})`);
82
76
  return result;
@@ -87,12 +81,14 @@ class CollectionClass extends Resource {
87
81
  }
88
82
  normalizeSortFields(fields) {
89
83
  const normalized = this.type.normalizeFieldPath(fields);
90
- const findManyEndpoint = this.operations.findMany;
91
- const sortFields = findManyEndpoint && findManyEndpoint.sortFields;
84
+ if (!normalized)
85
+ return;
86
+ const findManyOp = this.operations.findMany;
87
+ const sortFields = findManyOp && findManyOp.sortFields;
92
88
  (Array.isArray(normalized) ? normalized : [normalized]).forEach(field => {
93
89
  if (!sortFields?.find(x => x === field))
94
90
  throw new BadRequestError({
95
- message: translate('error:UNACCEPTED_SORT_FIELD', { field }, `Field '${field}' is not available for sort operation`),
91
+ message: translate('error:UNACCEPTED_SORT_FIELD', { field }),
96
92
  });
97
93
  });
98
94
  return normalized;
@@ -105,27 +101,75 @@ class CollectionClass extends Resource {
105
101
  this.normalizeFilter(ast.left);
106
102
  if (!(ast.left instanceof OpraFilter.QualifiedIdentifier && ast.left.field))
107
103
  throw new TypeError(`Invalid filter query. Left side should be a data field.`);
104
+ // Check if filtering accepted for given field
105
+ const findManyOp = this.operations.findMany;
106
+ const fieldLower = ast.left.value.toLowerCase();
107
+ const filterDef = (findManyOp && findManyOp.filters || [])
108
+ .find(f => f.field.toLowerCase() === fieldLower);
109
+ if (!filterDef) {
110
+ throw new BadRequestError({
111
+ message: translate('error:UNACCEPTED_FILTER_FIELD', { field: ast.left.value }),
112
+ });
113
+ }
114
+ // Check if filtering operation accepted for given field
115
+ if (!filterDef.operators?.includes(ast.op))
116
+ throw new BadRequestError({
117
+ message: translate('error:UNACCEPTED_FILTER_OPERATION', { field: ast.left.value }),
118
+ });
108
119
  this.normalizeFilter(ast.right);
120
+ return ast;
109
121
  }
110
- else if (ast instanceof OpraFilter.LogicalExpression) {
122
+ if (ast instanceof OpraFilter.LogicalExpression) {
111
123
  ast.items.forEach(item => this.normalizeFilter(item));
124
+ return ast;
112
125
  }
113
- else if (ast instanceof OpraFilter.ArithmeticExpression) {
126
+ if (ast instanceof OpraFilter.ArithmeticExpression) {
114
127
  ast.items.forEach(item => this.normalizeFilter(item.expression));
128
+ return ast;
115
129
  }
116
- else if (ast instanceof OpraFilter.ArrayExpression) {
130
+ if (ast instanceof OpraFilter.ArrayExpression) {
117
131
  ast.items.forEach(item => this.normalizeFilter(item));
132
+ return ast;
118
133
  }
119
- else if (ast instanceof OpraFilter.ParenthesizedExpression) {
134
+ if (ast instanceof OpraFilter.ParenthesizedExpression) {
120
135
  this.normalizeFilter(ast.expression);
136
+ return ast;
121
137
  }
122
- else if (ast instanceof OpraFilter.QualifiedIdentifier) {
123
- ast.field = this.type.findField(ast.value);
138
+ if (ast instanceof OpraFilter.QualifiedIdentifier) {
139
+ const normalizedFieldPath = this.type.normalizeFieldPath(ast.value)?.join('.');
140
+ ast.field = this.type.getField(normalizedFieldPath);
124
141
  ast.dataType = ast.field?.type || this.document.getDataType('any');
125
- ast.value = this.type.normalizeFieldPath(ast.value);
142
+ ast.value = normalizedFieldPath;
143
+ return ast;
126
144
  }
127
145
  return ast;
128
146
  }
147
+ getDecoder(operation) {
148
+ let decoder = this._decoders[operation];
149
+ if (decoder)
150
+ return decoder;
151
+ const options = {
152
+ partial: operation !== 'create'
153
+ };
154
+ if (operation !== 'create')
155
+ options.omit = [...this.primaryKey];
156
+ decoder = generateCodec(this.type, 'decode', options);
157
+ this._decoders[operation] = decoder;
158
+ return decoder;
159
+ }
160
+ getEncoder(operation) {
161
+ let encoder = this._encoders[operation];
162
+ if (encoder)
163
+ return encoder;
164
+ const options = {
165
+ partial: true
166
+ };
167
+ encoder = generateCodec(this.type, 'encode', options);
168
+ if (operation === 'findMany')
169
+ return vg.isArray(encoder);
170
+ this._encoders[operation] = encoder;
171
+ return encoder;
172
+ }
129
173
  }
130
174
  /**
131
175
  *
@@ -163,13 +207,12 @@ export const Collection = function (...args) {
163
207
  Collection.prototype = CollectionClass.prototype;
164
208
  function createOperationDecorator(operation) {
165
209
  return (options) => ((target, propertyKey) => {
166
- const metadata = {
167
- ...options,
168
- handlerName: propertyKey
169
- };
210
+ if (propertyKey !== operation)
211
+ throw new TypeError(`Name of the handler name should be '${operation}'`);
212
+ const operationMeta = { ...options };
170
213
  const resourceMetadata = (Reflect.getOwnMetadata(METADATA_KEY, target.constructor) || {});
171
214
  resourceMetadata.operations = resourceMetadata.operations || {};
172
- resourceMetadata.operations[operation] = metadata;
215
+ resourceMetadata.operations[operation] = operationMeta;
173
216
  Reflect.defineMetadata(METADATA_KEY, resourceMetadata, target.constructor);
174
217
  });
175
218
  }
@@ -3,29 +3,19 @@ import merge from 'putil-merge';
3
3
  import { omitUndefined } from '../../helpers/index.js';
4
4
  import { OpraSchema } from '../../schema/index.js';
5
5
  import { METADATA_KEY } from '../constants.js';
6
+ import { generateCodec } from '../utils/generate-codec.js';
6
7
  import { Resource } from './resource.js';
7
- const NESTJS_INJECTABLE_WATERMARK = '__injectable__';
8
+ const NESTJS_INJECTABLE_WATERMARK = '__injectable__'; // todo, put this in nextjs package wia augmentation
8
9
  const NAME_PATTERN = /^(.*)(Resource|Singleton)$/;
9
10
  class SingletonClass extends Resource {
10
11
  constructor(document, init) {
11
12
  super(document, init);
13
+ this._decoders = {};
14
+ this._encoders = {};
12
15
  this.kind = OpraSchema.Singleton.Kind;
13
16
  this.controller = init.controller;
14
- const operations = this.operations = init.operations || {};
17
+ this.operations = { ...init.operations };
15
18
  this.type = init.type;
16
- if (this.controller) {
17
- const instance = typeof this.controller == 'function'
18
- ? new this.controller()
19
- : this.controller;
20
- for (const operation of Object.values(operations)) {
21
- if (!operation.handler && operation.handlerName) {
22
- const fn = instance[operation.handlerName];
23
- if (!fn)
24
- throw new TypeError(`No such operation handler (${operation.handlerName}) found`);
25
- operation.handler = fn.bind(instance);
26
- }
27
- }
28
- }
29
19
  }
30
20
  exportSchema() {
31
21
  const out = Resource.prototype.exportSchema.call(this);
@@ -38,6 +28,28 @@ class SingletonClass extends Resource {
38
28
  normalizeFieldPath(path) {
39
29
  return this.type.normalizeFieldPath(path);
40
30
  }
31
+ getDecoder(operation) {
32
+ let decoder = this._decoders[operation];
33
+ if (decoder)
34
+ return decoder;
35
+ const options = {
36
+ partial: operation !== 'create'
37
+ };
38
+ decoder = generateCodec(this.type, 'decode', options);
39
+ this._decoders[operation] = decoder;
40
+ return decoder;
41
+ }
42
+ getEncoder(operation) {
43
+ let encoder = this._encoders[operation];
44
+ if (encoder)
45
+ return encoder;
46
+ const options = {
47
+ partial: true
48
+ };
49
+ encoder = generateCodec(this.type, 'encode', options);
50
+ this._encoders[operation] = encoder;
51
+ return encoder;
52
+ }
41
53
  }
42
54
  export const Singleton = function (...args) {
43
55
  // ClassDecorator
@@ -68,13 +80,12 @@ export const Singleton = function (...args) {
68
80
  Singleton.prototype = SingletonClass.prototype;
69
81
  function createOperationDecorator(operation) {
70
82
  return (options) => ((target, propertyKey) => {
71
- const metadata = {
72
- ...options,
73
- handlerName: propertyKey
74
- };
83
+ if (propertyKey !== operation)
84
+ throw new TypeError(`Name of the handler name should be '${operation}'`);
85
+ const operationMeta = { ...options };
75
86
  const resourceMetadata = (Reflect.getOwnMetadata(METADATA_KEY, target.constructor) || {});
76
87
  resourceMetadata.operations = resourceMetadata.operations || {};
77
- resourceMetadata.operations[operation] = metadata;
88
+ resourceMetadata.operations[operation] = operationMeta;
78
89
  Reflect.defineMetadata(METADATA_KEY, resourceMetadata, target.constructor);
79
90
  });
80
91
  }
@@ -11,20 +11,7 @@ class StorageClass extends Resource {
11
11
  super(document, init);
12
12
  this.kind = OpraSchema.Storage.Kind;
13
13
  this.controller = init.controller;
14
- const operations = this.operations = init.operations || {};
15
- if (this.controller) {
16
- const instance = typeof this.controller == 'function'
17
- ? new this.controller()
18
- : this.controller;
19
- for (const operation of Object.values(operations)) {
20
- if (!operation.handler && operation.handlerName) {
21
- const fn = instance[operation.handlerName];
22
- if (!fn)
23
- throw new TypeError(`No such operation handler (${operation.handlerName}) found`);
24
- operation.handler = fn.bind(instance);
25
- }
26
- }
27
- }
14
+ this.operations = { ...init.operations };
28
15
  }
29
16
  exportSchema() {
30
17
  const out = Resource.prototype.exportSchema.call(this);
@@ -62,16 +49,15 @@ export const Storage = function (...args) {
62
49
  Storage.prototype = StorageClass.prototype;
63
50
  function createOperationDecorator(operation) {
64
51
  return (options) => ((target, propertyKey) => {
65
- const metadata = {
66
- ...options,
67
- handlerName: propertyKey
68
- };
52
+ if (propertyKey !== operation)
53
+ throw new TypeError(`Name of the handler name should be '${operation}'`);
54
+ const operationMeta = { ...options };
69
55
  const resourceMetadata = (Reflect.getOwnMetadata(METADATA_KEY, target.constructor) || {});
70
56
  resourceMetadata.operations = resourceMetadata.operations || {};
71
- resourceMetadata.operations[operation] = metadata;
57
+ resourceMetadata.operations[operation] = operationMeta;
72
58
  Reflect.defineMetadata(METADATA_KEY, resourceMetadata, target.constructor);
73
59
  });
74
60
  }
75
61
  Storage.Delete = createOperationDecorator('delete');
76
62
  Storage.Get = createOperationDecorator('get');
77
- Storage.Put = createOperationDecorator('put');
63
+ Storage.Post = createOperationDecorator('post');
@@ -0,0 +1,33 @@
1
+ import * as vg from 'valgen';
2
+ import { ComplexType } from '../data-type/complex-type.js';
3
+ import { EnumType } from '../data-type/enum-type.js';
4
+ import { MappedType } from '../data-type/mapped-type.js';
5
+ import { SimpleType } from '../data-type/simple-type.js';
6
+ import { UnionType } from '../data-type/union-type.js';
7
+ export function generateCodec(type, codec, options) {
8
+ return _generateDecoder(type, codec, options);
9
+ }
10
+ export function _generateDecoder(type, codec, options) {
11
+ const schema = {};
12
+ for (const f of type.fields.values()) {
13
+ let fn;
14
+ if (f.type instanceof SimpleType || f.type instanceof EnumType) {
15
+ fn = f.type[codec];
16
+ }
17
+ else if (f.type instanceof ComplexType || f.type instanceof MappedType || f.type instanceof UnionType) {
18
+ fn = _generateDecoder(f.type, codec, options);
19
+ }
20
+ /* istanbul ignore next */
21
+ if (!fn)
22
+ throw new TypeError(`Can't generate codec for (${f.type})`);
23
+ if (f.isArray)
24
+ fn = vg.isArray(fn);
25
+ schema[f.name] = !options.partial && f.required ? vg.required(fn) : vg.optional(fn);
26
+ }
27
+ return vg.isObject(schema, {
28
+ ctor: type.ctor,
29
+ additionalFields: type.additionalFields ?? 'ignore',
30
+ name: type.name,
31
+ caseInSensitive: true,
32
+ });
33
+ }
@@ -7,7 +7,7 @@ import { OpraException } from '../opra-exception.js';
7
7
  export class ResourceNotFoundError extends OpraException {
8
8
  constructor(resource, keyValue, cause) {
9
9
  super({
10
- message: translate(`error:RESOURCE_NOT_FOUND`, { resource: resource + (keyValue ? '@' + keyValue : '') }, `The resource '{{resource}}' could not be found`),
10
+ message: translate(`error:RESOURCE_NOT_FOUND`, { resource: resource + (keyValue ? '@' + keyValue : '') }, `The resource '{{resource}}' not found`),
11
11
  severity: 'error',
12
12
  code: 'RESOURCE_NOT_FOUND',
13
13
  details: {
@@ -1,6 +1,6 @@
1
1
  export * from './function-utils.js';
2
2
  export * from './get-stack-filename.js';
3
- export * from './is-url.js';
3
+ export * from './is-url-string.js';
4
4
  export * from './mixin-utils.js';
5
5
  export * from './object-utils.js';
6
6
  export * from './path-to-object-tree.js';
@@ -0,0 +1,9 @@
1
+ import { URL } from 'url';
2
+ const URL_PATTERN = /^(https?:\/\/.)[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/i;
3
+ export function isUrlString(url) {
4
+ return URL_PATTERN.test(url);
5
+ }
6
+ export const isAbsoluteUrl = (urlString) => {
7
+ return !urlString.includes('://') &&
8
+ (new URL(urlString, 'http://tempuri.org/')).host !== 'tempuri.org';
9
+ };
@@ -12,13 +12,13 @@ export function cloneObject(obj, jsonOnly) {
12
12
  }
13
13
  });
14
14
  }
15
- export function omitUndefined(obj) {
15
+ export function omitUndefined(obj, recursive) {
16
16
  if (!(obj && typeof obj === 'object'))
17
17
  return obj;
18
18
  for (const k of Object.keys(obj)) {
19
19
  if (obj[k] === undefined)
20
20
  delete obj[k];
21
- else if (typeof obj[k] === 'object')
21
+ else if (recursive && typeof obj[k] === 'object')
22
22
  omitUndefined(obj[k]);
23
23
  }
24
24
  return obj;
@@ -2,10 +2,10 @@ var _a, _b, _c, _d;
2
2
  function isMap(v) {
3
3
  return v && typeof v.forEach === 'function';
4
4
  }
5
- const kKeyMap = Symbol('kKeyMap');
6
- const kKeyOrder = Symbol('kKeyOrder');
7
- const kWellKnownKeys = Symbol('kWellKnownKeys');
8
- const kOptions = Symbol('kOptions');
5
+ const kKeyMap = Symbol.for('kKeyMap');
6
+ const kKeyOrder = Symbol.for('kKeyOrder');
7
+ const kWellKnownKeys = Symbol.for('kWellKnownKeys');
8
+ const kOptions = Symbol.for('kOptions');
9
9
  /**
10
10
  * A Map implementation that supports case-insensitivity and ordered keys
11
11
  */
@@ -11,13 +11,15 @@ export function isStream(stream) {
11
11
  }
12
12
  export function isReadable(x) {
13
13
  return isStream(x)
14
- && x.readable !== false
15
14
  && typeof x._read === 'function'
16
15
  && typeof x._readableState === 'object';
17
16
  }
17
+ export function isWritable(x) {
18
+ return isStream(x)
19
+ && typeof x._write === 'function';
20
+ }
18
21
  export function isReadableStream(x) {
19
22
  return isStream(x)
20
- && x.readable !== false
21
23
  && typeof x.getReader === 'function'
22
24
  && typeof x.pipeThrough === 'function'
23
25
  && typeof x.pipeTo === 'function';
@@ -38,6 +40,13 @@ export function isFormData(x) {
38
40
  }
39
41
  export function isURL(x) {
40
42
  return x !== null
43
+ && typeof x == 'object'
41
44
  && typeof x.host === 'string'
42
45
  && typeof x.href === 'string';
43
46
  }
47
+ export function isIterable(x) {
48
+ return Symbol.iterator in x;
49
+ }
50
+ export function isAsyncIterable(x) {
51
+ return Symbol.asyncIterator in x;
52
+ }
@@ -4,11 +4,9 @@
4
4
  */
5
5
  export var HttpHeaderCodes;
6
6
  (function (HttpHeaderCodes) {
7
- /* *** Opra Headers *** */
8
- HttpHeaderCodes["X_Opra_Version"] = "X-OPRA-Version";
9
- HttpHeaderCodes["X_Opra_Data_Type"] = "X-OPRA-Data-Type";
10
- HttpHeaderCodes["X_Opra_Operation"] = "X-OPRA-Operation";
11
- HttpHeaderCodes["X_Opra_Total_Matches"] = "X-OPRA-Total-Matches";
7
+ /* *** Opra Custom Headers *** */
8
+ HttpHeaderCodes["X_Opra_Version"] = "X-Opra-Version";
9
+ HttpHeaderCodes["X_Total_Count"] = "X-Total-Count";
12
10
  /* *** Authentication *** */
13
11
  /**
14
12
  * Defines the authentication method that should be used to access a resource.
@@ -225,7 +225,7 @@ export var HttpStatusCodes;
225
225
  * to do so after the client upgrades to a different protocol. The server sends an Upgrade
226
226
  * header in a 426 response to indicate the required protocol(s).
227
227
  */
228
- HttpStatusCodes[HttpStatusCodes["UPGRADE_REQUIRED"] = 428] = "UPGRADE_REQUIRED";
228
+ HttpStatusCodes[HttpStatusCodes["UPGRADE_REQUIRED"] = 426] = "UPGRADE_REQUIRED";
229
229
  /**
230
230
  * The origin server requires the request to be conditional. This response is intended to prevent
231
231
  * the 'lost update' problem, where a client GETs a resource's state, modifies it and PUTs
package/esm/http/index.js CHANGED
@@ -1,12 +1,5 @@
1
- export * from './http-params.js';
1
+ export * from './opra-url.js';
2
+ export * from './opra-url-path.js';
2
3
  export * from './enums/http-headers-codes.enum.js';
3
4
  export * from './enums/http-status-codes.enum.js';
4
5
  export * from './enums/http-status-messages.js';
5
- export * from './interfaces/client-http-headers.interface.js';
6
- export * from './interfaces/server-http-headers.interface.js';
7
- export * from './codecs/date-codec.js';
8
- export * from './codecs/boolean-codec.js';
9
- export * from './codecs/filter-codec.js';
10
- export * from './codecs/integer-codec.js';
11
- export * from './codecs/number-codec.js';
12
- export * from './codecs/string-codec.js';