@opra/client 0.17.1 → 0.17.2

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 (188) hide show
  1. package/cjs/client-error.js +17 -0
  2. package/cjs/constants.js +7 -0
  3. package/cjs/http/batch-request.js +90 -0
  4. package/cjs/http/http-client.js +232 -0
  5. package/cjs/http/http-collection-node.js +110 -0
  6. package/cjs/http/http-request-observable.js +36 -0
  7. package/cjs/http/http-request.js +88 -0
  8. package/cjs/http/http-response.js +24 -0
  9. package/cjs/http/http-service-base.js +9 -0
  10. package/cjs/http/http-singleton-node.js +63 -0
  11. package/cjs/http/http-types.js +2 -0
  12. package/cjs/index.js +12 -0
  13. package/cjs/package.json +3 -0
  14. package/esm/client-error.js +13 -0
  15. package/esm/constants.js +4 -0
  16. package/esm/http/batch-request.js +90 -0
  17. package/esm/http/http-client.js +228 -0
  18. package/esm/http/http-collection-node.js +106 -0
  19. package/esm/http/http-request-observable.js +32 -0
  20. package/esm/http/http-request.js +84 -0
  21. package/esm/http/http-response.js +20 -0
  22. package/esm/http/http-service-base.js +5 -0
  23. package/esm/http/http-singleton-node.js +59 -0
  24. package/esm/http/http-types.js +1 -0
  25. package/esm/index.js +9 -0
  26. package/package.json +32 -12
  27. package/types/client-error.d.ts +1 -1
  28. package/types/http/http-client.d.ts +1 -1
  29. package/types/http/http-collection-node.d.ts +5 -5
  30. package/types/http/http-request-observable.d.ts +1 -1
  31. package/types/http/http-request.d.ts +1 -1
  32. package/types/http/http-response.d.ts +3 -1
  33. package/types/http/http-singleton-node.d.ts +1 -1
  34. package/types/http/http-types.d.ts +1 -1
  35. package/types/index.d.ts +0 -6
  36. package/cjs/content-disposition-d575fee5.js +0 -473
  37. package/cjs/cookie-signature-3e974173.js +0 -64
  38. package/cjs/index.min.mjs +0 -9295
  39. package/cjs/mime-db-49f150d0.js +0 -10719
  40. package/cjs/mime-types-6e2bdb57.js +0 -201
  41. package/cjs/safe-buffer-8acd60c7.js +0 -78
  42. package/esm/content-disposition-65f281a9.js +0 -470
  43. package/esm/cookie-signature-bf274b6b.js +0 -62
  44. package/esm/index.min.mjs +0 -9174
  45. package/esm/mime-db-d0f15d8f.js +0 -10717
  46. package/esm/mime-types-79c091fd.js +0 -199
  47. package/esm/safe-buffer-63383356.js +0 -76
  48. package/types/common/document/api-document.d.ts +0 -102
  49. package/types/common/document/constants.d.ts +0 -3
  50. package/types/common/document/data-type/api-field.d.ts +0 -41
  51. package/types/common/document/data-type/builtin/any.type.d.ts +0 -2
  52. package/types/common/document/data-type/builtin/base64.type.d.ts +0 -6
  53. package/types/common/document/data-type/builtin/bigint.type.d.ts +0 -6
  54. package/types/common/document/data-type/builtin/boolean.type.d.ts +0 -5
  55. package/types/common/document/data-type/builtin/date.type.d.ts +0 -4
  56. package/types/common/document/data-type/builtin/guid.type.d.ts +0 -7
  57. package/types/common/document/data-type/builtin/index.d.ts +0 -10
  58. package/types/common/document/data-type/builtin/integer.type.d.ts +0 -6
  59. package/types/common/document/data-type/builtin/number.type.d.ts +0 -6
  60. package/types/common/document/data-type/builtin/object.type.d.ts +0 -3
  61. package/types/common/document/data-type/builtin/string.type.d.ts +0 -5
  62. package/types/common/document/data-type/builtin/time.type.d.ts +0 -7
  63. package/types/common/document/data-type/builtin/timestamp.type.d.ts +0 -5
  64. package/types/common/document/data-type/complex-type.d.ts +0 -56
  65. package/types/common/document/data-type/data-type.d.ts +0 -33
  66. package/types/common/document/data-type/enum-type.d.ts +0 -32
  67. package/types/common/document/data-type/mapped-type.d.ts +0 -53
  68. package/types/common/document/data-type/simple-type.d.ts +0 -33
  69. package/types/common/document/data-type/union-type.d.ts +0 -42
  70. package/types/common/document/factory/add-references.d.ts +0 -4
  71. package/types/common/document/factory/create-document.d.ts +0 -12
  72. package/types/common/document/factory/factory.d.ts +0 -61
  73. package/types/common/document/factory/import-resource-class.d.ts +0 -10
  74. package/types/common/document/factory/import-type-class.d.ts +0 -17
  75. package/types/common/document/factory/index.d.ts +0 -1
  76. package/types/common/document/factory/process-resources.d.ts +0 -7
  77. package/types/common/document/factory/process-types.d.ts +0 -6
  78. package/types/common/document/index.d.ts +0 -14
  79. package/types/common/document/resource/collection.d.ts +0 -69
  80. package/types/common/document/resource/resource.d.ts +0 -29
  81. package/types/common/document/resource/singleton.d.ts +0 -51
  82. package/types/common/document/utils/inspect.util.d.ts +0 -4
  83. package/types/common/document/utils/string-compare.util.d.ts +0 -1
  84. package/types/common/exception/enums/issue-severity.enum.d.ts +0 -13
  85. package/types/common/exception/error-issue.d.ts +0 -9
  86. package/types/common/exception/http-errors/bad-request.error.d.ts +0 -10
  87. package/types/common/exception/http-errors/failed-dependency.error.d.ts +0 -9
  88. package/types/common/exception/http-errors/forbidden.error.d.ts +0 -11
  89. package/types/common/exception/http-errors/internal-server.error.d.ts +0 -9
  90. package/types/common/exception/http-errors/method-not-allowed.error.d.ts +0 -10
  91. package/types/common/exception/http-errors/not-acceptable.error.d.ts +0 -10
  92. package/types/common/exception/http-errors/not-found.error.d.ts +0 -13
  93. package/types/common/exception/http-errors/unauthorized.error.d.ts +0 -10
  94. package/types/common/exception/http-errors/unprocessable-entity.error.d.ts +0 -9
  95. package/types/common/exception/index.d.ts +0 -15
  96. package/types/common/exception/opra-exception.d.ts +0 -15
  97. package/types/common/exception/resource-errors/resource-conflict.error.d.ts +0 -5
  98. package/types/common/exception/resource-errors/resource-not-found.error.d.ts +0 -8
  99. package/types/common/exception/wrap-exception.d.ts +0 -2
  100. package/types/common/filter/antlr/OpraFilterLexer.d.ts +0 -77
  101. package/types/common/filter/antlr/OpraFilterListener.d.ts +0 -430
  102. package/types/common/filter/antlr/OpraFilterParser.d.ts +0 -437
  103. package/types/common/filter/antlr/OpraFilterVisitor.d.ts +0 -260
  104. package/types/common/filter/ast/abstract/ast.d.ts +0 -5
  105. package/types/common/filter/ast/abstract/expression.d.ts +0 -3
  106. package/types/common/filter/ast/abstract/literal.d.ts +0 -6
  107. package/types/common/filter/ast/abstract/term.d.ts +0 -3
  108. package/types/common/filter/ast/expressions/arithmetic-expression.d.ts +0 -13
  109. package/types/common/filter/ast/expressions/array-expression.d.ts +0 -7
  110. package/types/common/filter/ast/expressions/comparison-expression.d.ts +0 -10
  111. package/types/common/filter/ast/expressions/logical-expression.d.ts +0 -8
  112. package/types/common/filter/ast/expressions/parentheses-expression.d.ts +0 -6
  113. package/types/common/filter/ast/index.d.ts +0 -16
  114. package/types/common/filter/ast/terms/boolean-literal.d.ts +0 -5
  115. package/types/common/filter/ast/terms/date-literal.d.ts +0 -6
  116. package/types/common/filter/ast/terms/external-constant.d.ts +0 -5
  117. package/types/common/filter/ast/terms/null-literal.d.ts +0 -5
  118. package/types/common/filter/ast/terms/number-literal.d.ts +0 -6
  119. package/types/common/filter/ast/terms/qualified-identifier.d.ts +0 -8
  120. package/types/common/filter/ast/terms/string-literal.d.ts +0 -5
  121. package/types/common/filter/ast/terms/time-literal.d.ts +0 -6
  122. package/types/common/filter/build.d.ts +0 -31
  123. package/types/common/filter/errors.d.ts +0 -20
  124. package/types/common/filter/filter-tree-visitor.d.ts +0 -33
  125. package/types/common/filter/index.d.ts +0 -5
  126. package/types/common/filter/opra-error-listener.d.ts +0 -8
  127. package/types/common/filter/parse.d.ts +0 -2
  128. package/types/common/filter/utils.d.ts +0 -2
  129. package/types/common/helpers/function-utils.d.ts +0 -4
  130. package/types/common/helpers/get-stack-filename.d.ts +0 -1
  131. package/types/common/helpers/index.d.ts +0 -8
  132. package/types/common/helpers/is-url.d.ts +0 -1
  133. package/types/common/helpers/mixin-utils.d.ts +0 -3
  134. package/types/common/helpers/object-utils.d.ts +0 -2
  135. package/types/common/helpers/path-to-object-tree.d.ts +0 -4
  136. package/types/common/helpers/responsive-map.d.ts +0 -34
  137. package/types/common/helpers/type-guards.d.ts +0 -11
  138. package/types/common/http/codecs/boolean-codec.d.ts +0 -5
  139. package/types/common/http/codecs/date-codec.d.ts +0 -16
  140. package/types/common/http/codecs/filter-codec.d.ts +0 -6
  141. package/types/common/http/codecs/integer-codec.d.ts +0 -11
  142. package/types/common/http/codecs/number-codec.d.ts +0 -14
  143. package/types/common/http/codecs/string-codec.d.ts +0 -16
  144. package/types/common/http/enums/http-headers-codes.enum.d.ts +0 -388
  145. package/types/common/http/enums/http-status-codes.enum.d.ts +0 -290
  146. package/types/common/http/enums/http-status-messages.d.ts +0 -65
  147. package/types/common/http/http-headers.d.ts +0 -86
  148. package/types/common/http/http-message.host.d.ts +0 -122
  149. package/types/common/http/http-params.d.ts +0 -114
  150. package/types/common/http/http-request-message.d.ts +0 -213
  151. package/types/common/http/http-response-message.d.ts +0 -318
  152. package/types/common/http/index.d.ts +0 -14
  153. package/types/common/http/interfaces/client-http-headers.interface.d.ts +0 -65
  154. package/types/common/http/interfaces/cookie-options.interface.d.ts +0 -4
  155. package/types/common/http/interfaces/server-http-headers.interface.d.ts +0 -1
  156. package/types/common/http/multipart/batch-multipart.d.ts +0 -0
  157. package/types/common/http/multipart/http-request-content.d.ts +0 -0
  158. package/types/common/http/multipart/http-response-content.d.ts +0 -0
  159. package/types/common/http/multipart/index.d.ts +0 -0
  160. package/types/common/i18n/i18n.d.ts +0 -28
  161. package/types/common/i18n/index.d.ts +0 -5
  162. package/types/common/i18n/string-utils.d.ts +0 -2
  163. package/types/common/i18n/translate.d.ts +0 -4
  164. package/types/common/index.d.ts +0 -11
  165. package/types/common/schema/constants.d.ts +0 -2
  166. package/types/common/schema/data-type/complex-type.interface.d.ts +0 -16
  167. package/types/common/schema/data-type/data-type.interface.d.ts +0 -14
  168. package/types/common/schema/data-type/enum-type.interface.d.ts +0 -15
  169. package/types/common/schema/data-type/field.interface.d.ts +0 -21
  170. package/types/common/schema/data-type/mapped-type.interface.d.ts +0 -11
  171. package/types/common/schema/data-type/simple-type.interface.d.ts +0 -18
  172. package/types/common/schema/data-type/union-type.interface.d.ts +0 -10
  173. package/types/common/schema/document.interface.d.ts +0 -34
  174. package/types/common/schema/index.d.ts +0 -51
  175. package/types/common/schema/resource/collection.interface.d.ts +0 -33
  176. package/types/common/schema/resource/container.interface.d.ts +0 -9
  177. package/types/common/schema/resource/endpoint.interface.d.ts +0 -29
  178. package/types/common/schema/resource/resource.interface.d.ts +0 -12
  179. package/types/common/schema/resource/singleton.interface.d.ts +0 -22
  180. package/types/common/schema/type-guards.d.ts +0 -20
  181. package/types/common/types.d.ts +0 -11
  182. package/types/common/url/index.d.ts +0 -5
  183. package/types/common/url/opra-url-path-component.d.ts +0 -15
  184. package/types/common/url/opra-url-path.d.ts +0 -36
  185. package/types/common/url/opra-url.d.ts +0 -70
  186. package/types/common/url/utils/decode-path-component.d.ts +0 -5
  187. package/types/common/url/utils/encode-path-component.d.ts +0 -1
  188. package/types/common/utils/path-utils.d.ts +0 -2
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpSingletonNode = void 0;
4
+ const constants_js_1 = require("../constants.js");
5
+ const http_request_observable_js_1 = require("./http-request-observable.js");
6
+ class HttpSingletonNode {
7
+ constructor(context) {
8
+ this[constants_js_1.kHttpClientContext] = context;
9
+ }
10
+ create(data, options) {
11
+ const context = this[constants_js_1.kHttpClientContext];
12
+ const requestHost = new http_request_observable_js_1.HttpRequestObservable(context, options);
13
+ const request = requestHost[http_request_observable_js_1.HttpRequestObservable.kRequest];
14
+ request.method = 'POST';
15
+ request.url = context.resourceName;
16
+ request.body = data;
17
+ if (options?.include)
18
+ request.params.set('$include', options.include);
19
+ if (options?.pick)
20
+ request.params.set('$pick', options.pick);
21
+ if (options?.omit)
22
+ request.params.set('$omit', options.omit);
23
+ return requestHost;
24
+ }
25
+ delete(options) {
26
+ const context = this[constants_js_1.kHttpClientContext];
27
+ const requestHost = new http_request_observable_js_1.HttpRequestObservable(context, options);
28
+ const request = requestHost[http_request_observable_js_1.HttpRequestObservable.kRequest];
29
+ request.method = 'DELETE';
30
+ request.path.join({ resource: context.resourceName });
31
+ return requestHost;
32
+ }
33
+ get(options) {
34
+ const context = this[constants_js_1.kHttpClientContext];
35
+ const requestHost = new http_request_observable_js_1.HttpRequestObservable(context, options);
36
+ const request = requestHost[http_request_observable_js_1.HttpRequestObservable.kRequest];
37
+ request.method = 'GET';
38
+ request.path.join({ resource: context.resourceName });
39
+ if (options?.include)
40
+ request.params.set('$include', options.include);
41
+ if (options?.pick)
42
+ request.params.set('$pick', options.pick);
43
+ if (options?.omit)
44
+ request.params.set('$omit', options.omit);
45
+ return requestHost;
46
+ }
47
+ update(data, options) {
48
+ const context = this[constants_js_1.kHttpClientContext];
49
+ const requestHost = new http_request_observable_js_1.HttpRequestObservable(context, options);
50
+ const request = requestHost[http_request_observable_js_1.HttpRequestObservable.kRequest];
51
+ request.method = 'PATCH';
52
+ request.path.join({ resource: context.resourceName });
53
+ request.body = data;
54
+ if (options?.include)
55
+ request.params.set('$include', options.include);
56
+ if (options?.pick)
57
+ request.params.set('$pick', options.pick);
58
+ if (options?.omit)
59
+ request.params.set('$omit', options.omit);
60
+ return requestHost;
61
+ }
62
+ }
63
+ exports.HttpSingletonNode = HttpSingletonNode;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/cjs/index.js ADDED
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./client-error.js"), exports);
5
+ tslib_1.__exportStar(require("./http/http-client.js"), exports);
6
+ tslib_1.__exportStar(require("./http/http-collection-node.js"), exports);
7
+ tslib_1.__exportStar(require("./http/http-request.js"), exports);
8
+ tslib_1.__exportStar(require("./http/http-request-observable.js"), exports);
9
+ tslib_1.__exportStar(require("./http/http-response.js"), exports);
10
+ tslib_1.__exportStar(require("./http/http-service-base.js"), exports);
11
+ tslib_1.__exportStar(require("./http/http-singleton-node.js"), exports);
12
+ tslib_1.__exportStar(require("./http/http-types.js"), exports);
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,13 @@
1
+ export class ClientError extends Error {
2
+ constructor(init, cause) {
3
+ super(init.message);
4
+ this.cause = cause;
5
+ this.issues = init.issues || [];
6
+ this.status = init.status;
7
+ if (cause) {
8
+ this.cause = cause;
9
+ if (cause.stack)
10
+ this.stack = cause.stack;
11
+ }
12
+ }
13
+ }
@@ -0,0 +1,4 @@
1
+ export const JSON_CONTENT_TYPE_PATTERN = /^application\/([\w-]+\+)?\bjson\b/i;
2
+ export const TEXT_CONTENT_TYPE_PATTERN = /^text\/.*$/i;
3
+ export const FORMDATA_CONTENT_TYPE_PATTERN = /^multipart\/\bform-data\b/i;
4
+ export const kHttpClientContext = Symbol('kContext');
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ // import { BatchMultipart } from '@opra/common';
3
+ // import { HttpRequestHost } from '../http-request-host.js';
4
+ // import { HttpResponse } from '../http-response.js';
5
+ // import { CommonHttpRequestOptions, HttpRequestHandler, RawHttpRequest } from '../http-types.js';
6
+ //
7
+ // export class BatchRequest extends HttpRequestHost {
8
+ //
9
+ // protected _results = new WeakMap<HttpRequestHost, { error?: Error, response?: HttpResponse }>();
10
+ // protected _listeners = new Set<((error: Error | undefined, response?: HttpResponse) => void)>();
11
+ //
12
+ // constructor(
13
+ // protected _handler: HttpRequestHandler,
14
+ // readonly requests: HttpRequestHost[],
15
+ // public options: CommonHttpRequestOptions = {}
16
+ // ) {
17
+ // super(_handler, options);
18
+ //
19
+ // requests.forEach(request => {
20
+ // // Overwrite the _execute method
21
+ // Object.defineProperty(request, '_execute', {
22
+ // writable: true,
23
+ // enumerable: false,
24
+ // configurable: true,
25
+ // value: () => {
26
+ // return new Promise((resolve, reject) => {
27
+ // const x = this._results.get(request);
28
+ // if (x) {
29
+ // if (x.error)
30
+ // return reject(x.error);
31
+ // return resolve(x.response);
32
+ // }
33
+ // const callback = (error, response) => {
34
+ // this._listeners.delete(callback);
35
+ // if (error)
36
+ // return reject(error);
37
+ // resolve(response);
38
+ // };
39
+ // this._listeners.add(callback);
40
+ // })
41
+ // }
42
+ // })
43
+ // });
44
+ // }
45
+ //
46
+ // prepare(): RawHttpRequest {
47
+ // const batch = this._buildBatchMultipart(this);
48
+ // const headers = {
49
+ // 'content-type': 'multipart/mixed;boundary=' + batch.boundary
50
+ // }
51
+ // return mergeRawHttpRequests({
52
+ // method: 'POST',
53
+ // path: '/$batch',
54
+ // headers,
55
+ // body: batch.stream()
56
+ // },
57
+ // this.options.http
58
+ // );
59
+ // }
60
+ //
61
+ // protected _buildBatchMultipart(batch: BatchRequest): BatchMultipart {
62
+ // const multipart = new BatchMultipart();
63
+ //
64
+ // for (const req of batch.requests) {
65
+ // const prepared = req.prepare();
66
+ //
67
+ // if (req instanceof BatchRequest) {
68
+ // const subMultipart = this._buildBatchMultipart(req);
69
+ // multipart.addBatch(subMultipart);
70
+ // continue;
71
+ // }
72
+ //
73
+ // multipart.addRequestPart({
74
+ // method: prepared.method,
75
+ // url: prepared.path,
76
+ // headers: prepared.headers,
77
+ // data: prepared.body
78
+ // });
79
+ // }
80
+ //
81
+ // return multipart;
82
+ // }
83
+ //
84
+ // protected async _execute(): Promise<HttpResponse> {
85
+ // const req = this.prepare();
86
+ // const resp = await this._handler(req) as HttpResponse;
87
+ // return resp;
88
+ // }
89
+ //
90
+ // }
@@ -0,0 +1,228 @@
1
+ import { lastValueFrom, Observable } from 'rxjs';
2
+ import { isReadableStreamLike } from 'rxjs/internal/util/isReadableStreamLike';
3
+ import { DocumentFactory, HttpHeaderCodes, HttpHeaders, HttpParams, isBlob, joinPath, } from '@opra/common';
4
+ import { ClientError } from '../client-error.js';
5
+ import { FORMDATA_CONTENT_TYPE_PATTERN, JSON_CONTENT_TYPE_PATTERN, TEXT_CONTENT_TYPE_PATTERN } from '../constants.js';
6
+ import { HttpCollectionNode } from './http-collection-node.js';
7
+ import { HttpRequest } from './http-request.js';
8
+ import { HttpResponse } from './http-response.js';
9
+ import { HttpSingletonNode } from './http-singleton-node.js';
10
+ const kAssets = Symbol('kAssets');
11
+ export class OpraHttpClient {
12
+ constructor(serviceUrl, options) {
13
+ Object.defineProperty(this, kAssets, {
14
+ enumerable: false,
15
+ value: {
16
+ serviceUrl,
17
+ api: options?.api,
18
+ requestInterceptors: options?.requestInterceptors || [],
19
+ responseInterceptors: options?.responseInterceptors || []
20
+ }
21
+ });
22
+ this.defaults = {
23
+ ...options?.defaults,
24
+ headers: options?.defaults?.headers instanceof HttpHeaders
25
+ ? options?.defaults?.headers : new HttpHeaders(options?.defaults?.headers),
26
+ params: options?.defaults?.params instanceof HttpParams
27
+ ? options?.defaults?.params : new HttpParams(options?.defaults?.params)
28
+ };
29
+ }
30
+ get serviceUrl() {
31
+ return this[kAssets].serviceUrl;
32
+ }
33
+ async getMetadata() {
34
+ if (this[kAssets].api)
35
+ return this[kAssets].api;
36
+ let promise = this[kAssets].metadataPromise;
37
+ if (promise) {
38
+ return promise;
39
+ }
40
+ this[kAssets].metadataPromise = promise = lastValueFrom(this._sendRequest('body', new HttpRequest({
41
+ method: 'GET',
42
+ url: '$metadata',
43
+ headers: new HttpHeaders({ 'accept': 'application/json' })
44
+ })));
45
+ return await promise
46
+ .then(body => DocumentFactory.createDocument(body))
47
+ .then(api => this[kAssets].api = api)
48
+ .catch((e) => {
49
+ e.message = 'Unable to fetch metadata from ' + this.serviceUrl + '. ' + e.message;
50
+ throw e;
51
+ })
52
+ .finally(() => delete this[kAssets].metadataPromise);
53
+ }
54
+ // batch(requests: HttpRequestHost<any>[]): BatchRequest {
55
+ // this._assertMetadata();
56
+ // return new BatchRequest(request => this._sendRequest('response', request, requests);
57
+ // }
58
+ collection(resourceName) {
59
+ // If name argument is a class, we extract name from the class
60
+ if (typeof resourceName === 'function')
61
+ resourceName = resourceName.name;
62
+ const ctx = {
63
+ client: this,
64
+ resourceName,
65
+ send: (observe, request) => this._sendRequest(observe, request, ctx),
66
+ requestInterceptors: [
67
+ // Validate resource exists and is a collection resource
68
+ async () => {
69
+ const metadata = await this.getMetadata();
70
+ metadata.getCollection(ctx.resourceName);
71
+ }
72
+ ],
73
+ responseInterceptors: []
74
+ };
75
+ return new HttpCollectionNode(ctx);
76
+ }
77
+ singleton(resourceName) {
78
+ // If name argument is a class, we extract name from the class
79
+ if (typeof resourceName === 'function')
80
+ resourceName = resourceName.name;
81
+ const ctx = {
82
+ client: this,
83
+ resourceName,
84
+ send: (observe, request) => this._sendRequest(observe, request, ctx),
85
+ requestInterceptors: [
86
+ // Validate resource exists and is a singleton resource
87
+ async () => {
88
+ const metadata = await this.getMetadata();
89
+ metadata.getSingleton(ctx.resourceName);
90
+ }
91
+ ],
92
+ responseInterceptors: []
93
+ };
94
+ return new HttpSingletonNode(ctx);
95
+ }
96
+ _sendRequest(observe, request, ctx) {
97
+ return new Observable(subscriber => {
98
+ (async () => {
99
+ request.inset(this.defaults);
100
+ const url = request.url.includes('://') ? request.url : joinPath(this.serviceUrl, request.url);
101
+ let body;
102
+ if (request.body) {
103
+ let contentType;
104
+ if (typeof request.body === 'string' || typeof request.body === 'number' || typeof request.body === 'boolean') {
105
+ contentType = 'text/plain;charset=UTF-8"';
106
+ body = String(request.body);
107
+ request.headers.delete('Content-Size');
108
+ delete request.duplex;
109
+ }
110
+ else if (isReadableStreamLike(request.body)) {
111
+ contentType = 'application/octet-stream';
112
+ body = request.body;
113
+ request.duplex = 'half';
114
+ }
115
+ else if (Buffer.isBuffer(request.body)) {
116
+ contentType = 'application/octet-stream';
117
+ body = request.body;
118
+ request.headers.set('Content-Size', request.body.length);
119
+ delete request.duplex;
120
+ }
121
+ else if (isBlob(request.body)) {
122
+ contentType = request.body.type || 'application/octet-stream';
123
+ body = request.body;
124
+ request.headers.set('Content-Size', request.body.length);
125
+ delete request.duplex;
126
+ }
127
+ else {
128
+ contentType = 'application/json';
129
+ body = JSON.stringify(request.body);
130
+ request.headers.delete('Content-Size');
131
+ delete request.duplex;
132
+ }
133
+ if (!request.headers.has('Content-Type') && contentType)
134
+ request.headers.set('Content-Type', contentType);
135
+ request.body = body;
136
+ }
137
+ if (ctx) {
138
+ const requestInterceptors = [
139
+ ...this[kAssets].requestInterceptors,
140
+ ...ctx.requestInterceptors
141
+ ];
142
+ for (const interceptor of requestInterceptors) {
143
+ await interceptor(ctx, request);
144
+ }
145
+ }
146
+ if (observe === 'events')
147
+ subscriber.next({ event: 'sent', request });
148
+ const response = await this._fetch(url, { ...request, headers: request.headers.toObject() });
149
+ await this._handleResponse(observe, subscriber, request, response);
150
+ })().catch(error => subscriber.error(error));
151
+ });
152
+ }
153
+ _fetch(url, init = {}) {
154
+ return fetch(url, init);
155
+ }
156
+ _createResponse(init) {
157
+ return new HttpResponse(init);
158
+ }
159
+ async _handleResponse(observe, subscriber, request, fetchResponse, ctx) {
160
+ const headers = new HttpHeaders(fetchResponse.headers);
161
+ if (observe === 'events') {
162
+ const response = this._createResponse({
163
+ url: fetchResponse.url,
164
+ headers,
165
+ status: fetchResponse.status,
166
+ statusText: fetchResponse.statusText,
167
+ hasBody: !!fetchResponse.body
168
+ });
169
+ subscriber.next({ event: 'headers-received', request, response });
170
+ }
171
+ let body;
172
+ if (fetchResponse.body) {
173
+ if (JSON_CONTENT_TYPE_PATTERN.test(fetchResponse.headers.get('Content-Type') || '')) {
174
+ body = await fetchResponse.json();
175
+ if (typeof body === 'string')
176
+ body = JSON.parse(body);
177
+ }
178
+ else if (TEXT_CONTENT_TYPE_PATTERN.test(fetchResponse.headers.get('Content-Type') || ''))
179
+ body = await fetchResponse.text();
180
+ else if (FORMDATA_CONTENT_TYPE_PATTERN.test(fetchResponse.headers.get('Content-Type') || ''))
181
+ body = await fetchResponse.formData();
182
+ else {
183
+ const buf = await fetchResponse.arrayBuffer();
184
+ if (buf.byteLength)
185
+ body = buf;
186
+ }
187
+ }
188
+ if (observe === 'body' && fetchResponse.status >= 400 && fetchResponse.status < 600) {
189
+ subscriber.error(new ClientError({
190
+ message: fetchResponse.status + ' ' + fetchResponse.statusText,
191
+ status: fetchResponse.status,
192
+ issues: body?.errors
193
+ }));
194
+ subscriber.complete();
195
+ return;
196
+ }
197
+ const responseInit = {
198
+ url: fetchResponse.url,
199
+ headers,
200
+ status: fetchResponse.status,
201
+ statusText: fetchResponse.statusText,
202
+ body
203
+ };
204
+ if (fetchResponse.headers.has(HttpHeaderCodes.X_Opra_Total_Matches))
205
+ responseInit.totalMatches = parseInt(fetchResponse.headers.get(HttpHeaderCodes.X_Opra_Total_Matches), 10);
206
+ const response = this._createResponse(responseInit);
207
+ if (ctx) {
208
+ const responseInterceptors = [
209
+ ...this[kAssets].responseInterceptors,
210
+ ...ctx.responseInterceptors
211
+ ];
212
+ for (const interceptor of responseInterceptors) {
213
+ await interceptor(ctx, observe, request);
214
+ }
215
+ }
216
+ if (observe === 'body') {
217
+ subscriber.next(body);
218
+ }
219
+ else {
220
+ if (observe === 'events')
221
+ subscriber.next({ event: 'response', request, response });
222
+ else
223
+ subscriber.next(response);
224
+ }
225
+ subscriber.complete();
226
+ }
227
+ }
228
+ OpraHttpClient.kAssets = kAssets;
@@ -0,0 +1,106 @@
1
+ import { kHttpClientContext } from '../constants.js';
2
+ import { HttpRequestObservable } from './http-request-observable.js';
3
+ export class HttpCollectionNode {
4
+ constructor(context) {
5
+ this[kHttpClientContext] = context;
6
+ }
7
+ create(data, options) {
8
+ const context = this[kHttpClientContext];
9
+ const requestHost = new HttpRequestObservable(context, options);
10
+ const request = requestHost[HttpRequestObservable.kRequest];
11
+ request.method = 'POST';
12
+ request.url = context.resourceName;
13
+ request.body = data;
14
+ if (options?.include)
15
+ request.params.set('$include', options.include);
16
+ if (options?.pick)
17
+ request.params.set('$pick', options.pick);
18
+ if (options?.omit)
19
+ request.params.set('$omit', options.omit);
20
+ return requestHost;
21
+ }
22
+ delete(id, options) {
23
+ const context = this[kHttpClientContext];
24
+ const requestHost = new HttpRequestObservable(context, options);
25
+ const request = requestHost[HttpRequestObservable.kRequest];
26
+ request.method = 'DELETE';
27
+ request.path.join({ resource: context.resourceName, key: id });
28
+ return requestHost;
29
+ }
30
+ deleteMany(options) {
31
+ const context = this[kHttpClientContext];
32
+ const requestHost = new HttpRequestObservable(context, options);
33
+ const request = requestHost[HttpRequestObservable.kRequest];
34
+ request.method = 'DELETE';
35
+ request.url = context.resourceName;
36
+ if (options?.filter)
37
+ request.params.set('$filter', options.filter);
38
+ return requestHost;
39
+ }
40
+ get(id, options) {
41
+ const context = this[kHttpClientContext];
42
+ const requestHost = new HttpRequestObservable(context, options);
43
+ const request = requestHost[HttpRequestObservable.kRequest];
44
+ request.method = 'GET';
45
+ request.path.join({ resource: context.resourceName, key: id });
46
+ if (options?.include)
47
+ request.params.set('$include', options.include);
48
+ if (options?.pick)
49
+ request.params.set('$pick', options.pick);
50
+ if (options?.omit)
51
+ request.params.set('$omit', options.omit);
52
+ return requestHost;
53
+ }
54
+ findMany(options) {
55
+ const context = this[kHttpClientContext];
56
+ const requestHost = new HttpRequestObservable(context, options);
57
+ const request = requestHost[HttpRequestObservable.kRequest];
58
+ request.method = 'GET';
59
+ request.url = context.resourceName;
60
+ if (options?.include)
61
+ request.params.set('$include', options.include);
62
+ if (options?.pick)
63
+ request.params.set('$pick', options.pick);
64
+ if (options?.omit)
65
+ request.params.set('$omit', options.omit);
66
+ if (options?.sort)
67
+ request.params.set('$sort', options.sort);
68
+ if (options?.filter)
69
+ request.params.set('$filter', options.filter);
70
+ if (options?.limit != null)
71
+ request.params.set('$limit', options.limit);
72
+ if (options?.skip != null)
73
+ request.params.set('$skip', options.skip);
74
+ if (options?.count != null)
75
+ request.params.set('$count', options.count);
76
+ if (options?.distinct != null)
77
+ request.params.set('$distinct', options.distinct);
78
+ return requestHost;
79
+ }
80
+ update(id, data, options) {
81
+ const context = this[kHttpClientContext];
82
+ const requestHost = new HttpRequestObservable(context, options);
83
+ const request = requestHost[HttpRequestObservable.kRequest];
84
+ request.method = 'PATCH';
85
+ request.path.join({ resource: context.resourceName, key: id });
86
+ request.body = data;
87
+ if (options?.include)
88
+ request.params.set('$include', options.include);
89
+ if (options?.pick)
90
+ request.params.set('$pick', options.pick);
91
+ if (options?.omit)
92
+ request.params.set('$omit', options.omit);
93
+ return requestHost;
94
+ }
95
+ updateMany(data, options) {
96
+ const context = this[kHttpClientContext];
97
+ const requestHost = new HttpRequestObservable(context, options);
98
+ const request = requestHost[HttpRequestObservable.kRequest];
99
+ request.method = 'PATCH';
100
+ request.url = context.resourceName;
101
+ request.body = data;
102
+ if (options?.filter)
103
+ request.params.set('$filter', options.filter);
104
+ return requestHost;
105
+ }
106
+ }
@@ -0,0 +1,32 @@
1
+ import { lastValueFrom, Observable } from 'rxjs';
2
+ import { uid } from '@opra/common';
3
+ import { kHttpClientContext } from '../constants.js';
4
+ import { HttpRequest } from './http-request.js';
5
+ const kRequest = Symbol('kRequest');
6
+ export class HttpRequestObservable extends Observable {
7
+ constructor(context, options) {
8
+ super((subscriber) => {
9
+ context.send(options?.observe || 'body', this[kRequest]).subscribe((subscriber));
10
+ });
11
+ this[kHttpClientContext] = context;
12
+ this[kRequest] = new HttpRequest(options?.http);
13
+ this.contentId = uid(6);
14
+ }
15
+ header(name, value) {
16
+ this[kRequest].headers.append(name, value);
17
+ return this;
18
+ }
19
+ param(name, value) {
20
+ this[kRequest].params.append(name, value);
21
+ return this;
22
+ }
23
+ async fetch(observe) {
24
+ return lastValueFrom(this[kHttpClientContext].send(observe || 'body', this[kRequest]));
25
+ }
26
+ with(cb) {
27
+ cb(this);
28
+ return this;
29
+ }
30
+ }
31
+ HttpRequestObservable.kContext = kHttpClientContext;
32
+ HttpRequestObservable.kRequest = kRequest;
@@ -0,0 +1,84 @@
1
+ /// <reference lib="dom" />
2
+ import { HttpHeaders, OpraURL } from '@opra/common';
3
+ const directCopyProperties = ['cache', 'credentials', 'destination', 'headers', 'integrity',
4
+ 'keepalive', 'mode', 'redirect', 'referrer', 'referrerPolicy'];
5
+ export class HttpRequest {
6
+ constructor(init) {
7
+ this.cache = init?.cache || 'default';
8
+ this.credentials = init?.credentials || 'same-origin';
9
+ this.destination = init?.destination || '';
10
+ this.headers = new HttpHeaders(init?.headers);
11
+ this.integrity = init?.integrity || '';
12
+ this.keepalive = init?.keepalive ?? false;
13
+ this.method = (init?.method || 'GET').toUpperCase();
14
+ this.mode = init?.mode || 'cors';
15
+ this.redirect = init?.redirect || 'follow';
16
+ this.mode = init?.mode || 'cors';
17
+ this.referrer = init?.referrer || '';
18
+ this.referrerPolicy = init?.referrerPolicy || '';
19
+ this.signal = init?.signal || new AbortController().signal;
20
+ this.body = init?.body;
21
+ this.urlInstance = new OpraURL(init?.url);
22
+ if (init?.params)
23
+ this.params.appendAll(init.params);
24
+ }
25
+ /** Returns the URL of request as a string. */
26
+ get url() {
27
+ return this.urlInstance.href;
28
+ }
29
+ set url(value) {
30
+ this.urlInstance.parse(value);
31
+ }
32
+ /** Returns the searchParams of the URL as OpraURLSearchParams */
33
+ get params() {
34
+ return this.urlInstance.searchParams;
35
+ }
36
+ /** Returns the path part of URL as OpraURLPath */
37
+ get path() {
38
+ return this.urlInstance.path;
39
+ }
40
+ clone(...update) {
41
+ const out = new HttpRequest();
42
+ out.merge(this);
43
+ for (const upd of update) {
44
+ out.merge(upd);
45
+ }
46
+ return out;
47
+ }
48
+ merge(update) {
49
+ directCopyProperties.forEach(k => {
50
+ if (update[k] != null)
51
+ this[k] = update[k];
52
+ });
53
+ if (update.headers) {
54
+ const h = update.headers instanceof HttpHeaders
55
+ ? update.headers
56
+ : new HttpHeaders(update.headers);
57
+ h.forEach((v, k) => {
58
+ if (k.toLowerCase() === 'set-cookie') {
59
+ this.headers.append(k, v);
60
+ }
61
+ else
62
+ this.headers.set(k, v);
63
+ });
64
+ }
65
+ }
66
+ inset(src) {
67
+ directCopyProperties.forEach(k => {
68
+ if (this[k] == null && src[k] != null)
69
+ this[k] = src[k];
70
+ });
71
+ if (src.headers) {
72
+ const h = src.headers instanceof HttpHeaders
73
+ ? src.headers
74
+ : new HttpHeaders(src.headers);
75
+ h.forEach((v, k) => {
76
+ if (k.toLowerCase() === 'set-cookie') {
77
+ this.headers.append(k, v);
78
+ }
79
+ else if (!this.headers.has(k))
80
+ this.headers.set(k, v);
81
+ });
82
+ }
83
+ }
84
+ }
@@ -0,0 +1,20 @@
1
+ import { HttpHeaders } from '@opra/common';
2
+ export class HttpResponse {
3
+ constructor(init) {
4
+ /**
5
+ * Returns true if response has body to be received
6
+ */
7
+ this.hasBody = false;
8
+ this.headers = new HttpHeaders(init?.headers);
9
+ this.status = init?.status || 200;
10
+ this.statusText = init?.statusText || 'OK';
11
+ this.url = init?.url || null;
12
+ this.ok = this.status >= 200 && this.status < 300;
13
+ this.body = init?.body;
14
+ this.hasBody = init?.body != null || !!init?.hasBody;
15
+ this.totalMatches = init?.totalMatches;
16
+ }
17
+ clone(update) {
18
+ return new HttpResponse({ ...this, ...update });
19
+ }
20
+ }
@@ -0,0 +1,5 @@
1
+ export class HttpServiceBase {
2
+ constructor($client) {
3
+ this.$client = $client;
4
+ }
5
+ }