@opra/client 0.4.0 → 0.6.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 (100) hide show
  1. package/cjs/constants.js +6 -0
  2. package/cjs/http/http-client.js +164 -0
  3. package/cjs/http/http-collection-service.js +40 -0
  4. package/cjs/http/http-request.js +66 -0
  5. package/cjs/{response.js → http/http-response.js} +0 -0
  6. package/cjs/http/http-singleton-service.js +16 -0
  7. package/cjs/http/http-types.js +2 -0
  8. package/cjs/http/requests/batch-request.js +80 -0
  9. package/cjs/http/requests/collection-create-request.js +35 -0
  10. package/cjs/http/requests/collection-delete-many-request.js +28 -0
  11. package/cjs/http/requests/collection-delete-request.js +29 -0
  12. package/cjs/http/requests/collection-get-request.js +37 -0
  13. package/cjs/http/requests/collection-search-request.js +44 -0
  14. package/cjs/http/requests/collection-update-many-request.js +31 -0
  15. package/cjs/http/requests/collection-update-request.js +40 -0
  16. package/cjs/http/requests/http-singleton-get-request.js +31 -0
  17. package/cjs/http/utils/merge-raw-http-requests.util.js +29 -0
  18. package/cjs/index.js +16 -4
  19. package/cjs/interfaces/http-options.interface.js +2 -0
  20. package/cjs/interfaces/http-request-config.interface.js +2 -0
  21. package/cjs/types.js +0 -9
  22. package/esm/client-error.d.ts +1 -1
  23. package/esm/constants.d.ts +3 -0
  24. package/esm/constants.js +3 -0
  25. package/esm/http/http-client.d.ts +26 -0
  26. package/esm/http/http-client.js +160 -0
  27. package/esm/http/http-collection-service.d.ts +22 -0
  28. package/esm/http/http-collection-service.js +36 -0
  29. package/esm/http/http-request.d.ts +25 -0
  30. package/esm/http/http-request.js +62 -0
  31. package/esm/http/http-response.d.ts +14 -0
  32. package/esm/{response.js → http/http-response.js} +0 -0
  33. package/esm/http/http-singleton-service.d.ts +10 -0
  34. package/esm/http/http-singleton-service.js +12 -0
  35. package/esm/http/http-types.d.ts +26 -0
  36. package/esm/http/http-types.js +1 -0
  37. package/esm/http/requests/batch-request.d.ts +18 -0
  38. package/esm/http/requests/batch-request.js +76 -0
  39. package/esm/http/requests/collection-create-request.d.ts +12 -0
  40. package/esm/http/requests/collection-create-request.js +31 -0
  41. package/esm/http/requests/collection-delete-many-request.d.ts +11 -0
  42. package/esm/http/requests/collection-delete-many-request.js +24 -0
  43. package/esm/http/requests/collection-delete-request.d.ts +12 -0
  44. package/esm/http/requests/collection-delete-request.js +25 -0
  45. package/esm/http/requests/collection-get-request.d.ts +12 -0
  46. package/esm/http/requests/collection-get-request.js +33 -0
  47. package/esm/http/requests/collection-search-request.d.ts +11 -0
  48. package/esm/http/requests/collection-search-request.js +40 -0
  49. package/esm/http/requests/collection-update-many-request.d.ts +12 -0
  50. package/esm/http/requests/collection-update-many-request.js +27 -0
  51. package/esm/http/requests/collection-update-request.d.ts +13 -0
  52. package/esm/http/requests/collection-update-request.js +36 -0
  53. package/esm/http/requests/http-singleton-get-request.d.ts +11 -0
  54. package/esm/http/requests/http-singleton-get-request.js +27 -0
  55. package/esm/http/utils/merge-raw-http-requests.util.d.ts +2 -0
  56. package/esm/http/utils/merge-raw-http-requests.util.js +25 -0
  57. package/esm/index.d.ts +16 -4
  58. package/esm/index.js +16 -4
  59. package/esm/interfaces/http-options.interface.d.ts +20 -0
  60. package/esm/interfaces/http-options.interface.js +1 -0
  61. package/esm/interfaces/http-request-config.interface.d.ts +23 -0
  62. package/esm/interfaces/http-request-config.interface.js +1 -0
  63. package/esm/types.d.ts +7 -10
  64. package/esm/types.js +0 -9
  65. package/package.json +25 -16
  66. package/umd/opra-client.umd.min.js +1 -0
  67. package/cjs/client.js +0 -96
  68. package/cjs/observable-promise.js +0 -10
  69. package/cjs/requests/collection-create-request.js +0 -22
  70. package/cjs/requests/collection-delete-many-request.js +0 -14
  71. package/cjs/requests/collection-get-request.js +0 -22
  72. package/cjs/requests/collection-search-request.js +0 -46
  73. package/cjs/requests/collection-update-many-request.js +0 -14
  74. package/cjs/requests/collection-update-request.js +0 -22
  75. package/cjs/requests/singleton-get-request.js +0 -22
  76. package/cjs/services/collection-service.js +0 -192
  77. package/cjs/services/singleton-service.js +0 -43
  78. package/esm/client.d.ts +0 -25
  79. package/esm/client.js +0 -91
  80. package/esm/observable-promise.d.ts +0 -2
  81. package/esm/observable-promise.js +0 -6
  82. package/esm/requests/collection-create-request.d.ts +0 -8
  83. package/esm/requests/collection-create-request.js +0 -18
  84. package/esm/requests/collection-delete-many-request.d.ts +0 -7
  85. package/esm/requests/collection-delete-many-request.js +0 -10
  86. package/esm/requests/collection-get-request.d.ts +0 -8
  87. package/esm/requests/collection-get-request.js +0 -18
  88. package/esm/requests/collection-search-request.d.ts +0 -15
  89. package/esm/requests/collection-search-request.js +0 -42
  90. package/esm/requests/collection-update-many-request.d.ts +0 -7
  91. package/esm/requests/collection-update-many-request.js +0 -10
  92. package/esm/requests/collection-update-request.d.ts +0 -8
  93. package/esm/requests/collection-update-request.js +0 -18
  94. package/esm/requests/singleton-get-request.d.ts +0 -8
  95. package/esm/requests/singleton-get-request.js +0 -18
  96. package/esm/response.d.ts +0 -9
  97. package/esm/services/collection-service.d.ts +0 -31
  98. package/esm/services/collection-service.js +0 -188
  99. package/esm/services/singleton-service.d.ts +0 -14
  100. package/esm/services/singleton-service.js +0 -39
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mergeRawHttpRequests = void 0;
4
+ const common_1 = require("@opra/common");
5
+ function mergeRawHttpRequests(target, ...other) {
6
+ let params;
7
+ const arr = [target, ...other];
8
+ let headers;
9
+ for (let i = arr.length - 1; i >= 0; i--) {
10
+ const o = arr[i];
11
+ if (o?.headers) {
12
+ headers = headers || {};
13
+ Object.assign(headers, (0, common_1.normalizeHeaders)(o.headers));
14
+ }
15
+ }
16
+ for (const o of arr) {
17
+ if (!o)
18
+ continue;
19
+ Object.assign(target, o);
20
+ if (o?.params) {
21
+ params = params || new common_1.OpraURLSearchParams();
22
+ o.params.forEach((v, n) => params?.append(n, v));
23
+ }
24
+ }
25
+ target.headers = headers;
26
+ target.params = params;
27
+ return target;
28
+ }
29
+ exports.mergeRawHttpRequests = mergeRawHttpRequests;
package/cjs/index.js CHANGED
@@ -1,8 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
- tslib_1.__exportStar(require("./client.js"), exports);
5
- tslib_1.__exportStar(require("./response.js"), exports);
4
+ tslib_1.__exportStar(require("./http/http-client.js"), exports);
5
+ tslib_1.__exportStar(require("./http/http-request.js"), exports);
6
+ tslib_1.__exportStar(require("./http/http-response.js"), exports);
7
+ tslib_1.__exportStar(require("./http/http-collection-service.js"), exports);
8
+ tslib_1.__exportStar(require("./http/http-singleton-service.js"), exports);
9
+ tslib_1.__exportStar(require("./http/http-types.js"), exports);
6
10
  tslib_1.__exportStar(require("./types.js"), exports);
7
- tslib_1.__exportStar(require("./services/collection-service.js"), exports);
8
- tslib_1.__exportStar(require("./services/singleton-service.js"), exports);
11
+ tslib_1.__exportStar(require("./client-error.js"), exports);
12
+ tslib_1.__exportStar(require("./http/requests/batch-request.js"), exports);
13
+ tslib_1.__exportStar(require("./http/requests/collection-create-request.js"), exports);
14
+ tslib_1.__exportStar(require("./http/requests/collection-delete-request.js"), exports);
15
+ tslib_1.__exportStar(require("./http/requests/collection-delete-many-request.js"), exports);
16
+ tslib_1.__exportStar(require("./http/requests/collection-get-request.js"), exports);
17
+ tslib_1.__exportStar(require("./http/requests/collection-search-request.js"), exports);
18
+ tslib_1.__exportStar(require("./http/requests/collection-update-request.js"), exports);
19
+ tslib_1.__exportStar(require("./http/requests/collection-update-many-request.js"), exports);
20
+ tslib_1.__exportStar(require("./http/requests/http-singleton-get-request.js"), exports);
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/cjs/types.js CHANGED
@@ -1,11 +1,2 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- // export type CollectionCreateRequestOptions = CollectionCreateQueryOptions & CommonRequestOptions;
4
- // export type CollectionDeleteRequestOptions = CommonRequestOptions;
5
- // export type CollectionDeleteManyRequestOptions = CollectionDeleteManyQueryOptions & CommonRequestOptions;
6
- // export type CollectionGetRequestOptions = CollectionGetQueryOptions & CommonRequestOptions;
7
- // export type CollectionUpdateRequestOptions = CollectionUpdateQueryOptions & CommonRequestOptions;
8
- // export type CollectionUpdateManyRequestOptions = CollectionUpdateManyQueryOptions & CommonRequestOptions;
9
- // export type CollectionSearchRequestOptions = CollectionSearchQueryOptions & CommonRequestOptions;
10
- //
11
- // export type SingletonGetRequestOptions = SingletonGetQueryOptions & CommonRequestOptions;
@@ -1,4 +1,4 @@
1
- import { ErrorIssue } from '@opra/exception';
1
+ import { ErrorIssue } from '@opra/common';
2
2
  export declare class ClientError extends Error {
3
3
  cause?: Error | undefined;
4
4
  issues: ErrorIssue[];
@@ -0,0 +1,3 @@
1
+ export declare const JSON_CONTENT_TYPE_PATTERN: RegExp;
2
+ export declare const TEXT_CONTENT_TYPE_PATTERN: RegExp;
3
+ export declare const FORMDATA_CONTENT_TYPE_PATTERN: RegExp;
@@ -0,0 +1,3 @@
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;
@@ -0,0 +1,26 @@
1
+ import { Type } from 'ts-gems';
2
+ import { OpraDocument } from '@opra/common';
3
+ import { HttpCollectionService } from './http-collection-service.js';
4
+ import { HttpRequest } from './http-request.js';
5
+ import { HttpResponse } from './http-response.js';
6
+ import { HttpSingletonService } from './http-singleton-service.js';
7
+ import { HttpRequestDefaults, OpraHttpClientOptions, RawHttpRequest } from './http-types.js';
8
+ import { BatchRequest } from './requests/batch-request.js';
9
+ export declare class OpraHttpClient {
10
+ protected _serviceUrl: string;
11
+ protected _metadata?: OpraDocument;
12
+ defaults: HttpRequestDefaults;
13
+ constructor(serviceUrl: string, options?: OpraHttpClientOptions);
14
+ get serviceUrl(): string;
15
+ get initialized(): boolean;
16
+ get metadata(): OpraDocument;
17
+ init(forceRefresh?: boolean): Promise<void>;
18
+ batch(requests: HttpRequest[]): BatchRequest;
19
+ collection<T = any>(name: string | Type<T>): HttpCollectionService<T>;
20
+ singleton<T = any>(name: string | Type<T>): HttpSingletonService<T>;
21
+ protected _resolveMetadata(): Promise<void>;
22
+ protected _handleRequest<TResponse extends HttpResponse = HttpResponse>(req: RawHttpRequest): Promise<TResponse>;
23
+ protected _fetch<TResponse extends HttpResponse = HttpResponse>(url: string, req: RequestInit): Promise<TResponse>;
24
+ protected _assertMetadata(): void;
25
+ static create<T extends OpraHttpClient>(this: Type<T>, serviceUrl: string, options?: OpraHttpClientOptions): Promise<T>;
26
+ }
@@ -0,0 +1,160 @@
1
+ import { isReadable, isReadableStream, joinPath, OpraDocument } from '@opra/common';
2
+ import { ClientError } from '../client-error.js';
3
+ import { FORMDATA_CONTENT_TYPE_PATTERN, JSON_CONTENT_TYPE_PATTERN, TEXT_CONTENT_TYPE_PATTERN } from '../constants.js';
4
+ import { HttpCollectionService } from './http-collection-service.js';
5
+ import { HttpSingletonService } from './http-singleton-service.js';
6
+ import { BatchRequest } from './requests/batch-request.js';
7
+ import { mergeRawHttpRequests } from './utils/merge-raw-http-requests.util.js';
8
+ const documentCache = new Map();
9
+ const documentResolverCaches = new Map();
10
+ export class OpraHttpClient {
11
+ _serviceUrl;
12
+ _metadata;
13
+ defaults;
14
+ constructor(serviceUrl, options) {
15
+ this._serviceUrl = serviceUrl;
16
+ this._metadata = options?.document;
17
+ if (!this._metadata) {
18
+ const document = documentCache.get(this.serviceUrl.toLowerCase());
19
+ if (document)
20
+ this._metadata = document;
21
+ }
22
+ this.defaults = options?.defaults || {};
23
+ }
24
+ get serviceUrl() {
25
+ return this._serviceUrl;
26
+ }
27
+ get initialized() {
28
+ return !!this._metadata;
29
+ }
30
+ get metadata() {
31
+ this._assertMetadata();
32
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
33
+ return this._metadata;
34
+ }
35
+ async init(forceRefresh) {
36
+ if (!forceRefresh && this.initialized)
37
+ return;
38
+ const cacheName = this.serviceUrl.toLowerCase();
39
+ let promise = documentResolverCaches.get(cacheName);
40
+ if (promise) {
41
+ await promise;
42
+ return;
43
+ }
44
+ promise = this._resolveMetadata();
45
+ documentResolverCaches.set(cacheName, promise);
46
+ return promise
47
+ .catch(() => void 0)
48
+ .finally(() => documentResolverCaches.delete(cacheName));
49
+ }
50
+ batch(requests) {
51
+ this._assertMetadata();
52
+ return new BatchRequest(req => this._handleRequest(req), requests);
53
+ }
54
+ collection(name) {
55
+ this._assertMetadata();
56
+ // If name argument is a class, we extract name from the class
57
+ if (typeof name === 'function')
58
+ name = name.name;
59
+ const resource = this.metadata.getCollectionResource(name);
60
+ return new HttpCollectionService(resource, req => this._handleRequest(req));
61
+ }
62
+ singleton(name) {
63
+ this._assertMetadata();
64
+ // If name argument is a class, we extract name from the class
65
+ if (typeof name === 'function')
66
+ name = name.name;
67
+ const resource = this.metadata.getSingletonResource(name);
68
+ return new HttpSingletonService(resource, req => this._handleRequest(req));
69
+ }
70
+ async _resolveMetadata() {
71
+ const resp = await this._handleRequest({
72
+ method: 'GET',
73
+ path: '/$metadata',
74
+ headers: { 'accept': 'application/json' }
75
+ });
76
+ this._metadata = new OpraDocument(resp.data);
77
+ }
78
+ async _handleRequest(req) {
79
+ mergeRawHttpRequests(req, this.defaults);
80
+ let url = joinPath(this.serviceUrl, req.path);
81
+ if (req.params)
82
+ url += '?' + req.params.toString();
83
+ if (req.body) {
84
+ if (typeof req.body === 'object') {
85
+ if (!(isReadable(req.body) || isReadableStream(req.body) || Buffer.isBuffer(req.body))) {
86
+ if (!req.headers?.['content-type']) {
87
+ req.headers = req.headers || {};
88
+ req.headers['content-type'] = 'application/json';
89
+ }
90
+ req.body = JSON.stringify(req.body);
91
+ }
92
+ }
93
+ }
94
+ return this._fetch(url, req);
95
+ }
96
+ async _fetch(url, req) {
97
+ const resp = await fetch(url, req);
98
+ let data;
99
+ if (resp.body) {
100
+ if (JSON_CONTENT_TYPE_PATTERN.test(resp.headers.get('Content-Type') || '')) {
101
+ data = await resp.json();
102
+ if (typeof data === 'string')
103
+ data = JSON.parse(data);
104
+ }
105
+ else if (TEXT_CONTENT_TYPE_PATTERN.test(resp.headers.get('Content-Type') || ''))
106
+ data = await resp.text();
107
+ else if (FORMDATA_CONTENT_TYPE_PATTERN.test(resp.headers.get('Content-Type') || ''))
108
+ data = await resp.formData();
109
+ else
110
+ data = await resp.arrayBuffer();
111
+ }
112
+ if (resp.status >= 400 && resp.status < 600) {
113
+ throw new ClientError({
114
+ message: resp.status + ' ' + resp.statusText,
115
+ status: resp.status,
116
+ issues: data?.errors
117
+ });
118
+ }
119
+ const out = {
120
+ get headers() {
121
+ return resp.headers;
122
+ },
123
+ get ok() {
124
+ return resp.ok;
125
+ },
126
+ get redirected() {
127
+ return resp.redirected;
128
+ },
129
+ get status() {
130
+ return resp.status;
131
+ },
132
+ get statusText() {
133
+ return resp.statusText;
134
+ },
135
+ get type() {
136
+ return resp.type;
137
+ },
138
+ get url() {
139
+ return resp.url;
140
+ },
141
+ get contentId() {
142
+ return resp.headers.get('Content-ID');
143
+ },
144
+ get data() {
145
+ return data;
146
+ }
147
+ };
148
+ return out;
149
+ }
150
+ _assertMetadata() {
151
+ if (!this._metadata)
152
+ throw new Error('You must call init() to before using the client instance');
153
+ }
154
+ static async create(serviceUrl, options) {
155
+ const client = new this(serviceUrl, options);
156
+ if (!client._metadata)
157
+ await client.init();
158
+ return client;
159
+ }
160
+ }
@@ -0,0 +1,22 @@
1
+ import type { CollectionCreateQueryOptions, CollectionDeleteManyQueryOptions, CollectionGetQueryOptions, CollectionResourceInfo, CollectionSearchQueryOptions, CollectionUpdateManyQueryOptions, CollectionUpdateQueryOptions, PartialInput } from '@opra/common';
2
+ import { HttpResponse } from './http-response.js';
3
+ import { CommonHttpRequestOptions, HttpRequestHandler } from './http-types.js';
4
+ import { CollectionCreateRequest } from './requests/collection-create-request.js';
5
+ import { CollectionDeleteManyRequest } from './requests/collection-delete-many-request.js';
6
+ import { CollectionDeleteRequest } from './requests/collection-delete-request.js';
7
+ import { CollectionGetRequest } from './requests/collection-get-request.js';
8
+ import { CollectionSearchRequest } from './requests/collection-search-request.js';
9
+ import { CollectionUpdateManyRequest } from './requests/collection-update-many-request.js';
10
+ import { CollectionUpdateRequest } from './requests/collection-update-request.js';
11
+ export declare class HttpCollectionService<T, TResponse extends HttpResponse<T> = HttpResponse<T>> {
12
+ readonly resource: CollectionResourceInfo;
13
+ protected _handler: HttpRequestHandler;
14
+ constructor(resource: CollectionResourceInfo, _handler: HttpRequestHandler);
15
+ create(data: PartialInput<T>, options?: CollectionCreateQueryOptions & CommonHttpRequestOptions): CollectionCreateRequest<T, TResponse>;
16
+ delete(keyValue: any, options?: CommonHttpRequestOptions): CollectionDeleteRequest<T, TResponse>;
17
+ deleteMany(options?: CollectionDeleteManyQueryOptions & CommonHttpRequestOptions): CollectionDeleteManyRequest<T, TResponse>;
18
+ get(keyValue: any, options?: CollectionGetQueryOptions & CommonHttpRequestOptions): CollectionGetRequest<T, TResponse>;
19
+ search(options?: CollectionSearchQueryOptions & CommonHttpRequestOptions): CollectionSearchRequest<T, TResponse>;
20
+ update(keyValue: any, data: PartialInput<T>, options?: CollectionUpdateQueryOptions & CommonHttpRequestOptions): CollectionUpdateRequest<T, TResponse>;
21
+ updateMany(data: PartialInput<T>, options?: CollectionUpdateManyQueryOptions & CommonHttpRequestOptions): CollectionUpdateManyRequest<T, TResponse>;
22
+ }
@@ -0,0 +1,36 @@
1
+ import { CollectionCreateRequest } from './requests/collection-create-request.js';
2
+ import { CollectionDeleteManyRequest } from './requests/collection-delete-many-request.js';
3
+ import { CollectionDeleteRequest } from './requests/collection-delete-request.js';
4
+ import { CollectionGetRequest } from './requests/collection-get-request.js';
5
+ import { CollectionSearchRequest } from './requests/collection-search-request.js';
6
+ import { CollectionUpdateManyRequest } from './requests/collection-update-many-request.js';
7
+ import { CollectionUpdateRequest } from './requests/collection-update-request.js';
8
+ export class HttpCollectionService {
9
+ resource;
10
+ _handler;
11
+ constructor(resource, _handler) {
12
+ this.resource = resource;
13
+ this._handler = _handler;
14
+ }
15
+ create(data, options) {
16
+ return new CollectionCreateRequest(this._handler, this.resource, data, options);
17
+ }
18
+ delete(keyValue, options) {
19
+ return new CollectionDeleteRequest(this._handler, this.resource, keyValue, options);
20
+ }
21
+ deleteMany(options) {
22
+ return new CollectionDeleteManyRequest(this._handler, this.resource, options);
23
+ }
24
+ get(keyValue, options) {
25
+ return new CollectionGetRequest(this._handler, this.resource, keyValue, options);
26
+ }
27
+ search(options) {
28
+ return new CollectionSearchRequest(this._handler, this.resource, options);
29
+ }
30
+ update(keyValue, data, options) {
31
+ return new CollectionUpdateRequest(this._handler, this.resource, keyValue, data, options);
32
+ }
33
+ updateMany(data, options) {
34
+ return new CollectionUpdateManyRequest(this._handler, this.resource, data, options);
35
+ }
36
+ }
@@ -0,0 +1,25 @@
1
+ import { Observable } from 'rxjs';
2
+ import { ClientHttpHeaders } from '@opra/common';
3
+ import { HttpResponse } from './http-response.js';
4
+ import { CommonHttpRequestOptions, HttpRequestHandler, RawHttpRequest } from './http-types.js';
5
+ export declare abstract class HttpRequest<TResult = any, TResponse extends HttpResponse<TResult> = HttpResponse<TResult>> extends Observable<TResult | TResponse> {
6
+ protected _handler: HttpRequestHandler<TResult>;
7
+ options: CommonHttpRequestOptions;
8
+ readonly contentId: string;
9
+ protected _promise?: Promise<TResponse>;
10
+ protected _headers?: ClientHttpHeaders;
11
+ protected constructor(_handler: HttpRequestHandler<TResult>, options?: CommonHttpRequestOptions);
12
+ abstract prepare(): RawHttpRequest;
13
+ header<K extends keyof ClientHttpHeaders>(name: K, value: ClientHttpHeaders[K]): this;
14
+ /**
15
+ * Sends the request
16
+ */
17
+ fetch(): Promise<TResponse>;
18
+ /**
19
+ * Sends the request and returns response data
20
+ */
21
+ resolve(): Promise<TResult | undefined>;
22
+ with(cb: (_this: this) => void): this;
23
+ binding(): any;
24
+ protected _execute(): Promise<TResponse>;
25
+ }
@@ -0,0 +1,62 @@
1
+ import { Observable } from 'rxjs';
2
+ import { uid } from '@opra/common';
3
+ export class HttpRequest extends Observable {
4
+ _handler;
5
+ options;
6
+ contentId;
7
+ _promise;
8
+ _headers;
9
+ constructor(_handler, options = {}) {
10
+ super((subscriber) => {
11
+ if (options.observe === 'response') {
12
+ this.fetch().then(v => {
13
+ subscriber.next(v);
14
+ subscriber.complete();
15
+ }).catch(e => subscriber.error(e));
16
+ return;
17
+ }
18
+ this.resolve().then(v => {
19
+ subscriber.next(v);
20
+ subscriber.complete();
21
+ }).catch(e => subscriber.error(e));
22
+ });
23
+ this._handler = _handler;
24
+ this.options = options;
25
+ this.contentId = uid(6);
26
+ this.options = options;
27
+ }
28
+ header(name, value) {
29
+ this._headers = this._headers || {};
30
+ this._headers[name] = value;
31
+ return this;
32
+ }
33
+ /**
34
+ * Sends the request
35
+ */
36
+ async fetch() {
37
+ const promise = this._promise || (this._promise = new Promise((resolve, reject) => {
38
+ setTimeout(() => {
39
+ this._execute().then(resolve).catch(reject);
40
+ }, 0);
41
+ }));
42
+ return await promise;
43
+ }
44
+ /**
45
+ * Sends the request and returns response data
46
+ */
47
+ async resolve() {
48
+ const resp = await this.fetch();
49
+ return resp.data;
50
+ }
51
+ with(cb) {
52
+ cb(this);
53
+ return this;
54
+ }
55
+ binding() {
56
+ return {};
57
+ }
58
+ async _execute() {
59
+ const req = this.prepare();
60
+ return await this._handler(req);
61
+ }
62
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Opra Client Response Class
3
+ */
4
+ export interface HttpResponse<TData = any> {
5
+ readonly headers: Headers;
6
+ readonly ok: boolean;
7
+ readonly redirected: boolean;
8
+ readonly status: number;
9
+ readonly statusText: string;
10
+ readonly type: ResponseType;
11
+ readonly url: string;
12
+ readonly contentId?: string | null;
13
+ readonly data: TData;
14
+ }
File without changes
@@ -0,0 +1,10 @@
1
+ import { SingletonGetQueryOptions, SingletonResourceInfo } from '@opra/common';
2
+ import { HttpResponse } from './http-response.js';
3
+ import { HttpRequestHandler } from './http-types.js';
4
+ import { HttpSingletonGetRequest } from './requests/http-singleton-get-request.js';
5
+ export declare class HttpSingletonService<T, TResponse extends HttpResponse<T> = HttpResponse<T>> {
6
+ readonly resource: SingletonResourceInfo;
7
+ protected _handler: HttpRequestHandler;
8
+ constructor(resource: SingletonResourceInfo, _handler: HttpRequestHandler);
9
+ get(options?: SingletonGetQueryOptions): HttpSingletonGetRequest<T, TResponse>;
10
+ }
@@ -0,0 +1,12 @@
1
+ import { HttpSingletonGetRequest } from './requests/http-singleton-get-request.js';
2
+ export class HttpSingletonService {
3
+ resource;
4
+ _handler;
5
+ constructor(resource, _handler) {
6
+ this.resource = resource;
7
+ this._handler = _handler;
8
+ }
9
+ get(options) {
10
+ return new HttpSingletonGetRequest(this._handler, this.resource, options);
11
+ }
12
+ }
@@ -0,0 +1,26 @@
1
+ /// <reference types="node" />
2
+ /// <reference lib="dom" />
3
+ import { StrictOmit } from 'ts-gems';
4
+ import { URLSearchParams } from 'url';
5
+ import { ClientHttpHeaders, OpraDocument, OpraURLSearchParams } from '@opra/common';
6
+ import type { HttpResponse } from './http-response';
7
+ export declare type CommonHttpRequestOptions = {
8
+ observe?: 'body' | 'response';
9
+ http?: HttpRequestDefaults;
10
+ };
11
+ export declare type RawHttpRequest = StrictOmit<RequestInit, 'headers' | 'body' | 'method'> & {
12
+ method: string;
13
+ path: string;
14
+ headers?: ClientHttpHeaders;
15
+ params?: URLSearchParams | OpraURLSearchParams;
16
+ body?: any;
17
+ };
18
+ export declare type HttpRequestDefaults = Pick<RawHttpRequest, 'headers' | 'params' | 'mode' | 'credentials' | 'cache' | 'redirect' | 'referrer' | 'referrerPolicy' | 'integrity' | 'keepalive' | 'signal'>;
19
+ export declare type HttpRequestHandler<TResult = any> = (req: RawHttpRequest) => Promise<HttpResponse<TResult>>;
20
+ export interface OpraHttpClientOptions {
21
+ /**
22
+ * Opra Service Metadata Document
23
+ */
24
+ document?: OpraDocument;
25
+ defaults?: HttpRequestDefaults;
26
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,18 @@
1
+ import { BatchMultipart } from '@opra/common';
2
+ import { HttpRequest } from '../http-request.js';
3
+ import { HttpResponse } from '../http-response.js';
4
+ import { CommonHttpRequestOptions, HttpRequestHandler, RawHttpRequest } from '../http-types.js';
5
+ export declare class BatchRequest extends HttpRequest {
6
+ protected _handler: HttpRequestHandler;
7
+ readonly requests: HttpRequest[];
8
+ options: CommonHttpRequestOptions;
9
+ protected _results: WeakMap<HttpRequest<any, HttpResponse<any>>, {
10
+ error?: Error | undefined;
11
+ response?: HttpResponse<any> | undefined;
12
+ }>;
13
+ protected _listeners: Set<(error: Error | undefined, response?: HttpResponse) => void>;
14
+ constructor(_handler: HttpRequestHandler, requests: HttpRequest[], options?: CommonHttpRequestOptions);
15
+ prepare(): RawHttpRequest;
16
+ protected _buildBatchMultipart(batch: BatchRequest): BatchMultipart;
17
+ protected _execute(): Promise<HttpResponse>;
18
+ }
@@ -0,0 +1,76 @@
1
+ import { BatchMultipart } from '@opra/common';
2
+ import { HttpRequest } from '../http-request.js';
3
+ import { mergeRawHttpRequests } from '../utils/merge-raw-http-requests.util.js';
4
+ export class BatchRequest extends HttpRequest {
5
+ _handler;
6
+ requests;
7
+ options;
8
+ _results = new WeakMap();
9
+ _listeners = new Set();
10
+ constructor(_handler, requests, options = {}) {
11
+ super(_handler, options);
12
+ this._handler = _handler;
13
+ this.requests = requests;
14
+ this.options = options;
15
+ requests.forEach(request => {
16
+ // Overwrite the _execute method
17
+ Object.defineProperty(request, '_execute', {
18
+ writable: true,
19
+ enumerable: false,
20
+ configurable: true,
21
+ value: () => {
22
+ return new Promise((resolve, reject) => {
23
+ const x = this._results.get(request);
24
+ if (x) {
25
+ if (x.error)
26
+ return reject(x.error);
27
+ return resolve(x.response);
28
+ }
29
+ const callback = (error, response) => {
30
+ this._listeners.delete(callback);
31
+ if (error)
32
+ return reject(error);
33
+ resolve(response);
34
+ };
35
+ this._listeners.add(callback);
36
+ });
37
+ }
38
+ });
39
+ });
40
+ }
41
+ prepare() {
42
+ const batch = this._buildBatchMultipart(this);
43
+ const headers = {
44
+ 'content-type': 'multipart/mixed;boundary=' + batch.boundary
45
+ };
46
+ return mergeRawHttpRequests({
47
+ method: 'POST',
48
+ path: '/$batch',
49
+ headers,
50
+ body: batch.stream()
51
+ }, this.options.http);
52
+ }
53
+ _buildBatchMultipart(batch) {
54
+ const multipart = new BatchMultipart();
55
+ for (const req of batch.requests) {
56
+ const prepared = req.prepare();
57
+ if (req instanceof BatchRequest) {
58
+ const subMultipart = this._buildBatchMultipart(req);
59
+ multipart.addBatch(subMultipart);
60
+ continue;
61
+ }
62
+ multipart.addRequestPart({
63
+ method: prepared.method,
64
+ url: prepared.path,
65
+ headers: prepared.headers,
66
+ data: prepared.body
67
+ });
68
+ }
69
+ return multipart;
70
+ }
71
+ async _execute() {
72
+ const req = this.prepare();
73
+ const resp = await this._handler(req);
74
+ return resp;
75
+ }
76
+ }
@@ -0,0 +1,12 @@
1
+ import { CollectionCreateQueryOptions, CollectionResourceInfo, PartialInput } from '@opra/common';
2
+ import { HttpRequest } from '../http-request.js';
3
+ import { HttpResponse } from '../http-response.js';
4
+ import { CommonHttpRequestOptions, HttpRequestHandler, RawHttpRequest } from '../http-types.js';
5
+ export declare class CollectionCreateRequest<T, TResponse extends HttpResponse<T> = HttpResponse<T>> extends HttpRequest<T, TResponse> {
6
+ protected _handler: HttpRequestHandler;
7
+ readonly resource: CollectionResourceInfo;
8
+ data: PartialInput<T>;
9
+ options: CollectionCreateQueryOptions & CommonHttpRequestOptions;
10
+ constructor(_handler: HttpRequestHandler, resource: CollectionResourceInfo, data: PartialInput<T>, options?: CollectionCreateQueryOptions & CommonHttpRequestOptions);
11
+ prepare(): RawHttpRequest;
12
+ }
@@ -0,0 +1,31 @@
1
+ import { OpraURLSearchParams } from '@opra/common';
2
+ import { HttpRequest } from '../http-request.js';
3
+ import { mergeRawHttpRequests } from '../utils/merge-raw-http-requests.util.js';
4
+ export class CollectionCreateRequest extends HttpRequest {
5
+ _handler;
6
+ resource;
7
+ data;
8
+ options;
9
+ constructor(_handler, resource, data, options = {}) {
10
+ super(_handler, options);
11
+ this._handler = _handler;
12
+ this.resource = resource;
13
+ this.data = data;
14
+ this.options = options;
15
+ }
16
+ prepare() {
17
+ const searchParams = new OpraURLSearchParams();
18
+ if (this.options.include)
19
+ searchParams.set('$include', this.options.include);
20
+ if (this.options.pick)
21
+ searchParams.set('$pick', this.options.pick);
22
+ if (this.options.omit)
23
+ searchParams.set('$omit', this.options.omit);
24
+ return mergeRawHttpRequests({
25
+ method: 'POST',
26
+ path: this.resource.name,
27
+ params: searchParams,
28
+ body: this.data,
29
+ }, this.options.http);
30
+ }
31
+ }
@@ -0,0 +1,11 @@
1
+ import { CollectionDeleteManyQueryOptions, CollectionResourceInfo } from '@opra/common';
2
+ import { HttpRequest } from '../http-request.js';
3
+ import { HttpResponse } from '../http-response.js';
4
+ import { CommonHttpRequestOptions, HttpRequestHandler, RawHttpRequest } from '../http-types.js';
5
+ export declare class CollectionDeleteManyRequest<T, TResponse extends HttpResponse<T> = HttpResponse<T>> extends HttpRequest<T, TResponse> {
6
+ protected _handler: HttpRequestHandler;
7
+ readonly resource: CollectionResourceInfo;
8
+ options: CollectionDeleteManyQueryOptions & CommonHttpRequestOptions;
9
+ constructor(_handler: HttpRequestHandler, resource: CollectionResourceInfo, options?: CollectionDeleteManyQueryOptions & CommonHttpRequestOptions);
10
+ prepare(): RawHttpRequest;
11
+ }