@opra/client 0.25.4 → 0.26.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 (64) hide show
  1. package/browser.js +410 -463
  2. package/cjs/client.js +49 -234
  3. package/cjs/constants.js +2 -2
  4. package/cjs/enums/http-observable-type.enum.js +10 -0
  5. package/cjs/enums/index.js +4 -0
  6. package/cjs/impl/collection-node.js +119 -0
  7. package/cjs/impl/http-request-observable.js +246 -0
  8. package/cjs/impl/http-request.js +28 -0
  9. package/cjs/impl/http-service-base.js +16 -0
  10. package/cjs/impl/singleton-node.js +62 -0
  11. package/cjs/index.js +12 -6
  12. package/cjs/interfaces/client-context.interface.js +2 -0
  13. package/cjs/interfaces/http-event.interface.js +35 -0
  14. package/cjs/interfaces/http-request-defaults.interface.js +2 -0
  15. package/cjs/interfaces/index.js +5 -0
  16. package/cjs/types.js +0 -42
  17. package/esm/client.js +51 -236
  18. package/esm/constants.js +1 -1
  19. package/esm/enums/http-observable-type.enum.js +7 -0
  20. package/esm/enums/index.js +1 -0
  21. package/esm/impl/collection-node.js +115 -0
  22. package/esm/impl/http-request-observable.js +242 -0
  23. package/esm/impl/http-request.js +24 -0
  24. package/esm/impl/http-service-base.js +12 -0
  25. package/esm/impl/singleton-node.js +58 -0
  26. package/esm/index.js +9 -6
  27. package/esm/interfaces/client-context.interface.js +1 -0
  28. package/esm/interfaces/http-event.interface.js +32 -0
  29. package/esm/interfaces/http-request-defaults.interface.js +1 -0
  30. package/esm/interfaces/index.js +2 -0
  31. package/esm/types.js +1 -41
  32. package/package.json +2 -2
  33. package/types/client.d.ts +26 -38
  34. package/types/constants.d.ts +1 -1
  35. package/types/enums/http-observable-type.enum.d.ts +6 -0
  36. package/types/enums/index.d.ts +1 -0
  37. package/types/impl/collection-node.d.ts +66 -0
  38. package/types/impl/http-request-observable.d.ts +45 -0
  39. package/types/{http-request.d.ts → impl/http-request.d.ts} +23 -27
  40. package/types/impl/http-service-base.d.ts +7 -0
  41. package/types/impl/singleton-node.d.ts +35 -0
  42. package/types/index.d.ts +9 -6
  43. package/types/interfaces/client-context.interface.d.ts +13 -0
  44. package/types/interfaces/http-event.interface.d.ts +88 -0
  45. package/types/interfaces/http-request-defaults.interface.d.ts +6 -0
  46. package/types/interfaces/index.d.ts +2 -0
  47. package/types/types.d.ts +4 -111
  48. package/cjs/collection-node.js +0 -124
  49. package/cjs/http-request-observable.js +0 -40
  50. package/cjs/http-request.js +0 -86
  51. package/cjs/http-service-base.js +0 -9
  52. package/cjs/singleton-node.js +0 -68
  53. package/esm/collection-node.js +0 -120
  54. package/esm/http-request-observable.js +0 -36
  55. package/esm/http-request.js +0 -82
  56. package/esm/http-service-base.js +0 -5
  57. package/esm/singleton-node.js +0 -64
  58. package/types/collection-node.d.ts +0 -117
  59. package/types/http-request-observable.d.ts +0 -23
  60. package/types/http-service-base.d.ts +0 -5
  61. package/types/singleton-node.d.ts +0 -65
  62. /package/cjs/{http-response.js → impl/http-response.js} +0 -0
  63. /package/esm/{http-response.js → impl/http-response.js} +0 -0
  64. /package/types/{http-response.d.ts → impl/http-response.d.ts} +0 -0
@@ -0,0 +1,246 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpRequestObservable = void 0;
4
+ const rxjs_1 = require("rxjs");
5
+ const isReadableStreamLike_1 = require("rxjs/internal/util/isReadableStreamLike");
6
+ const common_1 = require("@opra/common");
7
+ const client_error_js_1 = require("../client-error.js");
8
+ const constants_js_1 = require("../constants.js");
9
+ const index_js_1 = require("../enums/index.js");
10
+ const index_js_2 = require("../interfaces/index.js");
11
+ const http_request_js_1 = require("./http-request.js");
12
+ const directCopyProperties = ['cache', 'credentials', 'destination', 'headers', 'integrity',
13
+ 'keepalive', 'mode', 'redirect', 'referrer', 'referrerPolicy'];
14
+ const kIntlObservable = Symbol.for('kIntlObservable');
15
+ /**
16
+ * @class HttpRequestObservable
17
+ */
18
+ class HttpRequestObservable extends rxjs_1.Observable {
19
+ constructor(client, init) {
20
+ super((subscriber) => {
21
+ this[kIntlObservable].subscribe((event) => {
22
+ if (event.event === index_js_2.HttpEventType.Response) {
23
+ subscriber.next(event.response.body);
24
+ subscriber.complete();
25
+ }
26
+ }, (error) => subscriber.error(error), () => subscriber.complete());
27
+ });
28
+ Object.defineProperty(this, constants_js_1.kClient, {
29
+ enumerable: false,
30
+ value: client
31
+ });
32
+ this.request = new http_request_js_1.HttpRequest(init);
33
+ if (init?.headers)
34
+ this.header(init.headers);
35
+ this[kIntlObservable] = this._send();
36
+ }
37
+ httpOptions(options) {
38
+ directCopyProperties.forEach(k => {
39
+ if (options[k] !== undefined)
40
+ this.request[k] = options[k];
41
+ });
42
+ return this;
43
+ }
44
+ header(arg0, value) {
45
+ const headers = this.request.headers;
46
+ if (typeof arg0 === 'object') {
47
+ const h = arg0 instanceof Headers
48
+ ? arg0
49
+ : new Headers(arg0);
50
+ h.forEach((v, k) => {
51
+ if (k.toLowerCase() === 'set-cookie') {
52
+ headers.append(k, v);
53
+ }
54
+ else
55
+ headers.set(k, v);
56
+ });
57
+ return this;
58
+ }
59
+ if (value == null)
60
+ headers.delete(arg0);
61
+ else
62
+ headers.append(arg0, String(value));
63
+ return this;
64
+ }
65
+ param(arg0, value) {
66
+ const params = this.request.url.searchParams;
67
+ if (typeof arg0 === 'object') {
68
+ const h = arg0 instanceof URLSearchParams
69
+ ? arg0
70
+ : new URLSearchParams(arg0);
71
+ h.forEach((v, k) => params.set(k, v));
72
+ return this;
73
+ }
74
+ if (value == null)
75
+ params.delete(arg0);
76
+ else
77
+ params.set(arg0, String(value));
78
+ return this;
79
+ }
80
+ observe(observe) {
81
+ return new rxjs_1.Observable((subscriber) => {
82
+ this[kIntlObservable].subscribe((event) => {
83
+ if (observe === index_js_1.HttpObserveType.Events) {
84
+ subscriber.next(event);
85
+ return;
86
+ }
87
+ if (observe === index_js_1.HttpObserveType.ResponseHeader && event.event === index_js_2.HttpEventType.ResponseHeader) {
88
+ subscriber.next(event.response);
89
+ subscriber.complete();
90
+ return;
91
+ }
92
+ if (observe === index_js_1.HttpObserveType.Body && event.event === index_js_2.HttpEventType.Response) {
93
+ subscriber.next(event.response.body);
94
+ subscriber.complete();
95
+ return;
96
+ }
97
+ if (event.event === index_js_2.HttpEventType.Response) {
98
+ subscriber.next(event.response);
99
+ subscriber.complete();
100
+ }
101
+ }, (error) => subscriber.error(error), () => subscriber.complete());
102
+ });
103
+ }
104
+ toPromise() {
105
+ return this.getData();
106
+ }
107
+ getData() {
108
+ return (0, rxjs_1.lastValueFrom)(this.observe(index_js_1.HttpObserveType.Body));
109
+ }
110
+ getResponse() {
111
+ return (0, rxjs_1.lastValueFrom)(this.observe(index_js_1.HttpObserveType.Response));
112
+ }
113
+ _send() {
114
+ const request = this.request;
115
+ const clientContext = this[constants_js_1.kClient][constants_js_1.kContext];
116
+ return new rxjs_1.Observable(subscriber => {
117
+ (async () => {
118
+ // Prepare request
119
+ this._prepareRequest();
120
+ // Call request Interceptors
121
+ for (const interceptor of clientContext.requestInterceptors) {
122
+ await interceptor(request);
123
+ }
124
+ // Emit 'sent' event
125
+ subscriber.next({
126
+ request,
127
+ event: index_js_2.HttpEventType.Sent,
128
+ });
129
+ // Send request
130
+ const url = new common_1.OpraURL(request.url, clientContext.serviceUrl);
131
+ const fetchResponse = await clientContext.fetch(url.toString(), request);
132
+ // Emit 'response-header' event
133
+ const headersResponse = clientContext.createResponse({
134
+ url: fetchResponse.url,
135
+ headers: fetchResponse.headers,
136
+ status: fetchResponse.status,
137
+ statusText: fetchResponse.statusText,
138
+ hasBody: !!fetchResponse.body
139
+ });
140
+ subscriber.next({
141
+ request,
142
+ event: index_js_2.HttpEventType.ResponseHeader,
143
+ response: headersResponse
144
+ });
145
+ // Parse body
146
+ const body = fetchResponse.body
147
+ ? await this._parseBody(fetchResponse)
148
+ : undefined;
149
+ // Handle errors
150
+ if (fetchResponse.status >= 400 && fetchResponse.status <= 599) {
151
+ subscriber.error(new client_error_js_1.ClientError({
152
+ message: fetchResponse.status + ' ' + fetchResponse.statusText,
153
+ status: fetchResponse.status,
154
+ issues: body.errors
155
+ }));
156
+ subscriber.complete();
157
+ return;
158
+ }
159
+ // Create response
160
+ const contentType = fetchResponse.headers.get('Content-Type') || '';
161
+ const responseInit = {
162
+ url: fetchResponse.url,
163
+ headers: fetchResponse.headers,
164
+ status: fetchResponse.status,
165
+ statusText: fetchResponse.statusText,
166
+ body,
167
+ };
168
+ if (constants_js_1.OPRA_JSON_CONTENT_TYPE_PATTERN.test(contentType)) {
169
+ responseInit.totalCount = body?.totalCount;
170
+ responseInit.affected = body?.affected;
171
+ }
172
+ const response = clientContext.createResponse(responseInit);
173
+ // Call response Interceptors
174
+ for (const interceptor of clientContext.responseInterceptors) {
175
+ await interceptor(response);
176
+ }
177
+ // Emit 'response' event
178
+ subscriber.next({
179
+ request,
180
+ event: index_js_2.HttpEventType.Response,
181
+ response
182
+ });
183
+ subscriber.complete();
184
+ })().catch(error => subscriber.error(error));
185
+ });
186
+ }
187
+ _prepareRequest() {
188
+ const request = this.request;
189
+ if (request.body) {
190
+ let body;
191
+ let contentType;
192
+ if (typeof request.body === 'string' || typeof request.body === 'number' || typeof request.body === 'boolean') {
193
+ contentType = 'text/plain;charset=UTF-8"';
194
+ body = String(request.body);
195
+ request.headers.delete('Content-Size');
196
+ delete request.duplex;
197
+ }
198
+ else if ((0, isReadableStreamLike_1.isReadableStreamLike)(request.body)) {
199
+ contentType = 'application/octet-stream';
200
+ body = request.body;
201
+ request.duplex = 'half';
202
+ }
203
+ else if (Buffer.isBuffer(request.body)) {
204
+ contentType = 'application/octet-stream';
205
+ body = request.body;
206
+ request.headers.set('Content-Size', String(request.body.length));
207
+ delete request.duplex;
208
+ }
209
+ else if ((0, common_1.isBlob)(request.body)) {
210
+ contentType = request.body.type || 'application/octet-stream';
211
+ body = request.body;
212
+ request.headers.set('Content-Size', String(request.body.length));
213
+ delete request.duplex;
214
+ }
215
+ else {
216
+ contentType = 'application/json';
217
+ body = JSON.stringify(request.body);
218
+ request.headers.delete('Content-Size');
219
+ delete request.duplex;
220
+ }
221
+ if (!request.headers.has('Content-Type') && contentType)
222
+ request.headers.set('Content-Type', contentType);
223
+ request.body = body;
224
+ }
225
+ }
226
+ async _parseBody(fetchResponse) {
227
+ let body;
228
+ const contentType = fetchResponse.headers.get('Content-Type') || '';
229
+ if (constants_js_1.JSON_CONTENT_TYPE_PATTERN.test(contentType)) {
230
+ body = await fetchResponse.json();
231
+ if (typeof body === 'string')
232
+ body = JSON.parse(body);
233
+ }
234
+ else if (constants_js_1.TEXT_CONTENT_TYPE_PATTERN.test(contentType))
235
+ body = await fetchResponse.text();
236
+ else if (constants_js_1.FORMDATA_CONTENT_TYPE_PATTERN.test(contentType))
237
+ body = await fetchResponse.formData();
238
+ else {
239
+ const buf = await fetchResponse.arrayBuffer();
240
+ if (buf.byteLength)
241
+ body = buf;
242
+ }
243
+ return body;
244
+ }
245
+ }
246
+ exports.HttpRequestObservable = HttpRequestObservable;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpRequest = void 0;
4
+ /// <reference lib="dom" />
5
+ const common_1 = require("@opra/common");
6
+ /**
7
+ * @class HttpRequest
8
+ */
9
+ class HttpRequest {
10
+ constructor(init) {
11
+ this.cache = init?.cache || 'default';
12
+ this.credentials = init?.credentials || 'same-origin';
13
+ this.destination = init?.destination || '';
14
+ this.integrity = init?.integrity || '';
15
+ this.keepalive = init?.keepalive ?? false;
16
+ this.method = (init?.method || 'GET').toUpperCase();
17
+ this.mode = init?.mode || 'cors';
18
+ this.redirect = init?.redirect || 'follow';
19
+ this.mode = init?.mode || 'cors';
20
+ this.referrer = init?.referrer || '';
21
+ this.referrerPolicy = init?.referrerPolicy || '';
22
+ this.signal = init?.signal || new AbortController().signal;
23
+ this.body = init?.body;
24
+ this.url = init?.url instanceof common_1.OpraURL ? init.url : new common_1.OpraURL(init?.url);
25
+ this.headers = init?.headers instanceof Headers ? init.headers : new Headers(init?.headers);
26
+ }
27
+ }
28
+ exports.HttpRequest = HttpRequest;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.HttpServiceBase = void 0;
5
+ const constants_js_1 = require("../constants.js");
6
+ class HttpServiceBase {
7
+ constructor(client) {
8
+ this[_a] = {
9
+ resource: {},
10
+ node: null
11
+ };
12
+ this[constants_js_1.kClient] = client;
13
+ }
14
+ }
15
+ exports.HttpServiceBase = HttpServiceBase;
16
+ _a = constants_js_1.kContext;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpSingletonNode = void 0;
4
+ const putil_varhelpers_1 = require("putil-varhelpers");
5
+ const http_request_observable_js_1 = require("./http-request-observable.js");
6
+ /**
7
+ * @class HttpSingletonNode
8
+ */
9
+ class HttpSingletonNode {
10
+ constructor(client, path) {
11
+ this._client = client;
12
+ this._path = path;
13
+ }
14
+ create(data, options) {
15
+ const observable = new http_request_observable_js_1.HttpRequestObservable(this._client, {
16
+ method: 'POST',
17
+ url: this._path,
18
+ body: data
19
+ });
20
+ if (options?.include)
21
+ observable.param('include', (0, putil_varhelpers_1.toArrayDef)(options.include, []).join(','));
22
+ if (options?.pick)
23
+ observable.param('pick', (0, putil_varhelpers_1.toArrayDef)(options.pick, []).join(','));
24
+ if (options?.omit)
25
+ observable.param('omit', (0, putil_varhelpers_1.toArrayDef)(options.omit, []).join(','));
26
+ return observable;
27
+ }
28
+ delete() {
29
+ return new http_request_observable_js_1.HttpRequestObservable(this._client, {
30
+ method: 'DELETE',
31
+ url: this._path
32
+ });
33
+ }
34
+ get(options) {
35
+ const observable = new http_request_observable_js_1.HttpRequestObservable(this._client, {
36
+ method: 'GET',
37
+ url: this._path
38
+ });
39
+ if (options?.include)
40
+ observable.param('include', (0, putil_varhelpers_1.toArrayDef)(options.include, []).join(','));
41
+ if (options?.pick)
42
+ observable.param('pick', (0, putil_varhelpers_1.toArrayDef)(options.pick, []).join(','));
43
+ if (options?.omit)
44
+ observable.param('omit', (0, putil_varhelpers_1.toArrayDef)(options.omit, []).join(','));
45
+ return observable;
46
+ }
47
+ update(data, options) {
48
+ const observable = new http_request_observable_js_1.HttpRequestObservable(this._client, {
49
+ method: 'PATCH',
50
+ url: this._path,
51
+ body: data
52
+ });
53
+ if (options?.include)
54
+ observable.param('include', (0, putil_varhelpers_1.toArrayDef)(options.include, []).join(','));
55
+ if (options?.pick)
56
+ observable.param('pick', (0, putil_varhelpers_1.toArrayDef)(options.pick, []).join(','));
57
+ if (options?.omit)
58
+ observable.param('omit', (0, putil_varhelpers_1.toArrayDef)(options.omit, []).join(','));
59
+ return observable;
60
+ }
61
+ }
62
+ exports.HttpSingletonNode = HttpSingletonNode;
package/cjs/index.js CHANGED
@@ -1,12 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.kContext = exports.kClient = void 0;
3
4
  const tslib_1 = require("tslib");
4
5
  tslib_1.__exportStar(require("./client.js"), exports);
5
6
  tslib_1.__exportStar(require("./client-error.js"), exports);
6
- tslib_1.__exportStar(require("./collection-node.js"), exports);
7
- tslib_1.__exportStar(require("./http-request.js"), exports);
8
- tslib_1.__exportStar(require("./http-request-observable.js"), exports);
9
- tslib_1.__exportStar(require("./http-response.js"), exports);
10
- tslib_1.__exportStar(require("./http-service-base.js"), exports);
11
- tslib_1.__exportStar(require("./singleton-node.js"), exports);
12
7
  tslib_1.__exportStar(require("./types.js"), exports);
8
+ tslib_1.__exportStar(require("./enums/index.js"), exports);
9
+ tslib_1.__exportStar(require("./interfaces/index.js"), exports);
10
+ tslib_1.__exportStar(require("./impl/collection-node.js"), exports);
11
+ tslib_1.__exportStar(require("./impl/singleton-node.js"), exports);
12
+ tslib_1.__exportStar(require("./impl/http-request.js"), exports);
13
+ tslib_1.__exportStar(require("./impl/http-response.js"), exports);
14
+ tslib_1.__exportStar(require("./impl/http-service-base.js"), exports);
15
+ tslib_1.__exportStar(require("./impl/http-request-observable.js"), exports);
16
+ var constants_js_1 = require("./constants.js");
17
+ Object.defineProperty(exports, "kClient", { enumerable: true, get: function () { return constants_js_1.kClient; } });
18
+ Object.defineProperty(exports, "kContext", { enumerable: true, get: function () { return constants_js_1.kContext; } });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpEventType = void 0;
4
+ /**
5
+ * Type enumeration for the different kinds of `HttpEvent`.
6
+ */
7
+ var HttpEventType;
8
+ (function (HttpEventType) {
9
+ /**
10
+ * The request was sent out over the wire.
11
+ */
12
+ HttpEventType["Sent"] = "sent";
13
+ /**
14
+ * An upload progress event was received.
15
+ *
16
+ * Note: The `FetchBackend` doesn't support progress report on uploads.
17
+ */
18
+ HttpEventType["UploadProgress"] = "upload-progress";
19
+ /**
20
+ * The response status code and headers were received.
21
+ */
22
+ HttpEventType["ResponseHeader"] = "response-header";
23
+ /**
24
+ * A download progress event was received.
25
+ */
26
+ HttpEventType["DownloadProgress"] = "download-progress";
27
+ /**
28
+ * The full response including the body was received.
29
+ */
30
+ HttpEventType["Response"] = "response";
31
+ /**
32
+ * A custom event from an interceptor or a backend.
33
+ */
34
+ HttpEventType["Custom"] = "custom";
35
+ })(HttpEventType || (exports.HttpEventType = HttpEventType = {}));
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./http-event.interface.js"), exports);
5
+ tslib_1.__exportStar(require("./http-request-defaults.interface.js"), exports);
package/cjs/types.js CHANGED
@@ -1,44 +1,2 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HttpEventType = exports.HttpObserveType = void 0;
4
- /* **********************
5
- * Enums
6
- *********************** */
7
- var HttpObserveType;
8
- (function (HttpObserveType) {
9
- HttpObserveType["Response"] = "response";
10
- HttpObserveType["Body"] = "body";
11
- HttpObserveType["Events"] = "events";
12
- })(HttpObserveType || (exports.HttpObserveType = HttpObserveType = {}));
13
- /**
14
- * Type enumeration for the different kinds of `HttpEvent`.
15
- */
16
- var HttpEventType;
17
- (function (HttpEventType) {
18
- /**
19
- * The request was sent out over the wire.
20
- */
21
- HttpEventType["Sent"] = "sent";
22
- /**
23
- * An upload progress event was received.
24
- *
25
- * Note: The `FetchBackend` doesn't support progress report on uploads.
26
- */
27
- HttpEventType["UploadProgress"] = "upload-progress";
28
- /**
29
- * The response status code and headers were received.
30
- */
31
- HttpEventType["ResponseHeader"] = "response-header";
32
- /**
33
- * A download progress event was received.
34
- */
35
- HttpEventType["DownloadProgress"] = "download-progress";
36
- /**
37
- * The full response including the body was received.
38
- */
39
- HttpEventType["Response"] = "response";
40
- /**
41
- * A custom event from an interceptor or a backend.
42
- */
43
- HttpEventType["Custom"] = "custom";
44
- })(HttpEventType || (exports.HttpEventType = HttpEventType = {}));