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