@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.
- package/cjs/constants.js +6 -0
- package/cjs/http/http-client.js +164 -0
- package/cjs/http/http-collection-service.js +40 -0
- package/cjs/http/http-request.js +66 -0
- package/cjs/{response.js → http/http-response.js} +0 -0
- package/cjs/http/http-singleton-service.js +16 -0
- package/cjs/http/http-types.js +2 -0
- package/cjs/http/requests/batch-request.js +80 -0
- package/cjs/http/requests/collection-create-request.js +35 -0
- package/cjs/http/requests/collection-delete-many-request.js +28 -0
- package/cjs/http/requests/collection-delete-request.js +29 -0
- package/cjs/http/requests/collection-get-request.js +37 -0
- package/cjs/http/requests/collection-search-request.js +44 -0
- package/cjs/http/requests/collection-update-many-request.js +31 -0
- package/cjs/http/requests/collection-update-request.js +40 -0
- package/cjs/http/requests/http-singleton-get-request.js +31 -0
- package/cjs/http/utils/merge-raw-http-requests.util.js +29 -0
- package/cjs/index.js +16 -4
- package/cjs/interfaces/http-options.interface.js +2 -0
- package/cjs/interfaces/http-request-config.interface.js +2 -0
- package/cjs/types.js +0 -9
- package/esm/client-error.d.ts +1 -1
- package/esm/constants.d.ts +3 -0
- package/esm/constants.js +3 -0
- package/esm/http/http-client.d.ts +26 -0
- package/esm/http/http-client.js +160 -0
- package/esm/http/http-collection-service.d.ts +22 -0
- package/esm/http/http-collection-service.js +36 -0
- package/esm/http/http-request.d.ts +25 -0
- package/esm/http/http-request.js +62 -0
- package/esm/http/http-response.d.ts +14 -0
- package/esm/{response.js → http/http-response.js} +0 -0
- package/esm/http/http-singleton-service.d.ts +10 -0
- package/esm/http/http-singleton-service.js +12 -0
- package/esm/http/http-types.d.ts +26 -0
- package/esm/http/http-types.js +1 -0
- package/esm/http/requests/batch-request.d.ts +18 -0
- package/esm/http/requests/batch-request.js +76 -0
- package/esm/http/requests/collection-create-request.d.ts +12 -0
- package/esm/http/requests/collection-create-request.js +31 -0
- package/esm/http/requests/collection-delete-many-request.d.ts +11 -0
- package/esm/http/requests/collection-delete-many-request.js +24 -0
- package/esm/http/requests/collection-delete-request.d.ts +12 -0
- package/esm/http/requests/collection-delete-request.js +25 -0
- package/esm/http/requests/collection-get-request.d.ts +12 -0
- package/esm/http/requests/collection-get-request.js +33 -0
- package/esm/http/requests/collection-search-request.d.ts +11 -0
- package/esm/http/requests/collection-search-request.js +40 -0
- package/esm/http/requests/collection-update-many-request.d.ts +12 -0
- package/esm/http/requests/collection-update-many-request.js +27 -0
- package/esm/http/requests/collection-update-request.d.ts +13 -0
- package/esm/http/requests/collection-update-request.js +36 -0
- package/esm/http/requests/http-singleton-get-request.d.ts +11 -0
- package/esm/http/requests/http-singleton-get-request.js +27 -0
- package/esm/http/utils/merge-raw-http-requests.util.d.ts +2 -0
- package/esm/http/utils/merge-raw-http-requests.util.js +25 -0
- package/esm/index.d.ts +16 -4
- package/esm/index.js +16 -4
- package/esm/interfaces/http-options.interface.d.ts +20 -0
- package/esm/interfaces/http-options.interface.js +1 -0
- package/esm/interfaces/http-request-config.interface.d.ts +23 -0
- package/esm/interfaces/http-request-config.interface.js +1 -0
- package/esm/types.d.ts +7 -10
- package/esm/types.js +0 -9
- package/package.json +25 -16
- package/umd/opra-client.umd.min.js +1 -0
- package/cjs/client.js +0 -96
- package/cjs/observable-promise.js +0 -10
- package/cjs/requests/collection-create-request.js +0 -22
- package/cjs/requests/collection-delete-many-request.js +0 -14
- package/cjs/requests/collection-get-request.js +0 -22
- package/cjs/requests/collection-search-request.js +0 -46
- package/cjs/requests/collection-update-many-request.js +0 -14
- package/cjs/requests/collection-update-request.js +0 -22
- package/cjs/requests/singleton-get-request.js +0 -22
- package/cjs/services/collection-service.js +0 -192
- package/cjs/services/singleton-service.js +0 -43
- package/esm/client.d.ts +0 -25
- package/esm/client.js +0 -91
- package/esm/observable-promise.d.ts +0 -2
- package/esm/observable-promise.js +0 -6
- package/esm/requests/collection-create-request.d.ts +0 -8
- package/esm/requests/collection-create-request.js +0 -18
- package/esm/requests/collection-delete-many-request.d.ts +0 -7
- package/esm/requests/collection-delete-many-request.js +0 -10
- package/esm/requests/collection-get-request.d.ts +0 -8
- package/esm/requests/collection-get-request.js +0 -18
- package/esm/requests/collection-search-request.d.ts +0 -15
- package/esm/requests/collection-search-request.js +0 -42
- package/esm/requests/collection-update-many-request.d.ts +0 -7
- package/esm/requests/collection-update-many-request.js +0 -10
- package/esm/requests/collection-update-request.d.ts +0 -8
- package/esm/requests/collection-update-request.js +0 -18
- package/esm/requests/singleton-get-request.d.ts +0 -8
- package/esm/requests/singleton-get-request.js +0 -18
- package/esm/response.d.ts +0 -9
- package/esm/services/collection-service.d.ts +0 -31
- package/esm/services/collection-service.js +0 -188
- package/esm/services/singleton-service.d.ts +0 -14
- 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("./
|
|
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("./
|
|
8
|
-
tslib_1.__exportStar(require("./
|
|
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);
|
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;
|
package/esm/client-error.d.ts
CHANGED
package/esm/constants.js
ADDED
|
@@ -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
|
+
}
|