@placeos/ts-client 4.2.2 → 4.2.4
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/dist/http/functions.d.ts +1 -1
- package/dist/http/mock.d.ts +6 -1
- package/dist/index.cjs.js +2 -2
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +1232 -1189
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +2 -2
- package/dist/index.umd.js.map +1 -1
- package/dist/repositories/repository.d.ts +2 -0
- package/package.json +1 -1
- package/src/http/functions.ts +57 -23
- package/src/http/mock.ts +25 -11
- package/src/repositories/repository.ts +3 -0
|
@@ -17,6 +17,8 @@ export declare class PlaceRepository extends PlaceResource {
|
|
|
17
17
|
readonly username: string;
|
|
18
18
|
/** Password to connect to repository with */
|
|
19
19
|
readonly password: string;
|
|
20
|
+
/** Root path of the repository to serve at the `folder_name` path */
|
|
21
|
+
readonly root_path: string;
|
|
20
22
|
/** Repository type */
|
|
21
23
|
get type(): PlaceRepositoryType;
|
|
22
24
|
constructor(raw_data?: Partial<PlaceRepository>);
|
package/package.json
CHANGED
package/src/http/functions.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Observable,
|
|
1
|
+
import { Observable, throwError } from 'rxjs';
|
|
2
2
|
import { fromFetch } from 'rxjs/fetch';
|
|
3
|
-
import { filter,
|
|
3
|
+
import { filter, retry, switchMap, take } from 'rxjs/operators';
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
apiKey,
|
|
@@ -225,17 +225,26 @@ export async function transform(
|
|
|
225
225
|
return await resp.json().catch(() => ({}));
|
|
226
226
|
case 'text':
|
|
227
227
|
return await resp.text();
|
|
228
|
+
case 'void':
|
|
229
|
+
return;
|
|
230
|
+
default:
|
|
231
|
+
return await resp.json().catch(() => ({}));
|
|
228
232
|
}
|
|
229
233
|
}
|
|
230
234
|
|
|
231
235
|
/**
|
|
232
236
|
* @private
|
|
233
237
|
*/
|
|
234
|
-
const reloadAuth = () => {
|
|
238
|
+
const reloadAuth = (): Promise<void> => {
|
|
235
239
|
invalidateToken();
|
|
236
|
-
refreshAuthority().then(
|
|
237
|
-
() =>
|
|
238
|
-
() =>
|
|
240
|
+
return refreshAuthority().then(
|
|
241
|
+
() => Promise.resolve(),
|
|
242
|
+
() =>
|
|
243
|
+
new Promise<void>((resolve) => {
|
|
244
|
+
setTimeout(() => {
|
|
245
|
+
reloadAuth().then(() => resolve());
|
|
246
|
+
}, 1000);
|
|
247
|
+
}),
|
|
239
248
|
);
|
|
240
249
|
};
|
|
241
250
|
|
|
@@ -255,7 +264,7 @@ export function request(
|
|
|
255
264
|
m: HttpVerb,
|
|
256
265
|
url: string,
|
|
257
266
|
body?: any,
|
|
258
|
-
) => Observable<
|
|
267
|
+
) => Observable<HashMap | string | void> | null = mockRequest,
|
|
259
268
|
success: (
|
|
260
269
|
e: Response,
|
|
261
270
|
t: HttpResponseType,
|
|
@@ -268,7 +277,9 @@ export function request(
|
|
|
268
277
|
}
|
|
269
278
|
}
|
|
270
279
|
options.headers = options.headers || {};
|
|
271
|
-
options.headers['Content-Type']
|
|
280
|
+
if (!options.headers['Content-Type'] && !options.headers['content-type']) {
|
|
281
|
+
options.headers['Content-Type'] = `application/json`;
|
|
282
|
+
}
|
|
272
283
|
return listenForToken().pipe(
|
|
273
284
|
filter((_) => _),
|
|
274
285
|
take(1),
|
|
@@ -278,34 +289,57 @@ export function request(
|
|
|
278
289
|
} else {
|
|
279
290
|
options.headers!.Authorization = `Bearer ${token()}`;
|
|
280
291
|
}
|
|
281
|
-
|
|
292
|
+
const fetchOptions: any = {
|
|
282
293
|
...options,
|
|
283
|
-
body: JSON.stringify(options.body),
|
|
284
294
|
method,
|
|
285
295
|
credentials: 'same-origin',
|
|
286
|
-
}
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
// Only add body for methods that support it and when body exists
|
|
299
|
+
if (
|
|
300
|
+
['POST', 'PUT', 'PATCH'].includes(method) &&
|
|
301
|
+
options.body !== undefined
|
|
302
|
+
) {
|
|
303
|
+
fetchOptions.body =
|
|
304
|
+
typeof options.body === 'string'
|
|
305
|
+
? options.body
|
|
306
|
+
: JSON.stringify(options.body);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return fromFetch(url, fetchOptions) as Observable<Response>;
|
|
287
310
|
}),
|
|
288
|
-
switchMap((resp) => {
|
|
311
|
+
switchMap((resp: Response) => {
|
|
289
312
|
if (resp.ok) {
|
|
290
313
|
return success(resp, options.response_type as any);
|
|
291
314
|
}
|
|
292
315
|
return throwError(resp);
|
|
293
316
|
}),
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
317
|
+
retry({
|
|
318
|
+
count: 4,
|
|
319
|
+
delay: (error, retry_count) => {
|
|
320
|
+
return new Observable<number>((subscriber) => {
|
|
297
321
|
if (error.status === 511) {
|
|
298
322
|
sendToLogin(authority()!);
|
|
299
|
-
|
|
323
|
+
subscriber.error(error);
|
|
324
|
+
return;
|
|
300
325
|
}
|
|
301
|
-
if (
|
|
302
|
-
|
|
326
|
+
if (error.status !== 401) {
|
|
327
|
+
subscriber.error(error || {});
|
|
328
|
+
return;
|
|
303
329
|
}
|
|
304
330
|
log('HTTP', 'Auth error', error);
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
331
|
+
// Wait for auth refresh before retrying with exponential backoff
|
|
332
|
+
const delay_ms = Math.pow(2, retry_count - 1) * 1000; // Exponential backoff: 1s, 2s, 4s, 8s
|
|
333
|
+
reloadAuth()
|
|
334
|
+
.then(() => {
|
|
335
|
+
subscriber.next(delay_ms);
|
|
336
|
+
subscriber.complete();
|
|
337
|
+
})
|
|
338
|
+
.catch(() => {
|
|
339
|
+
subscriber.error(error);
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
},
|
|
343
|
+
}),
|
|
310
344
|
);
|
|
311
345
|
}
|
package/src/http/mock.ts
CHANGED
|
@@ -86,12 +86,12 @@ export function clearMockEndpoints(
|
|
|
86
86
|
* @param handler_map Handler map to query for the request handler.
|
|
87
87
|
* Defaults to the global handler map
|
|
88
88
|
*/
|
|
89
|
-
export function mockRequest
|
|
89
|
+
export function mockRequest(
|
|
90
90
|
method: HttpVerb,
|
|
91
91
|
url: string,
|
|
92
92
|
body?: any,
|
|
93
93
|
handler_map: HashMap<MockHttpRequestHandler> = _handlers,
|
|
94
|
-
): Observable<
|
|
94
|
+
): Observable<HashMap | string | void> | null {
|
|
95
95
|
const handler = findRequestHandler(method, url, handler_map);
|
|
96
96
|
if (handler) {
|
|
97
97
|
const request = processRequest(url, handler, body);
|
|
@@ -113,7 +113,7 @@ export function findRequestHandler(
|
|
|
113
113
|
handler_map: HashMap<MockHttpRequestHandler> = _handlers,
|
|
114
114
|
): MockHttpRequestHandler | null {
|
|
115
115
|
const path = url
|
|
116
|
-
.replace(/(http|https)
|
|
116
|
+
.replace(/(http|https):\/\/[a-zA-Z0-9.]*:?([0-9]*)?/g, '')
|
|
117
117
|
.replace(/^\//, '')
|
|
118
118
|
.split('?')[0];
|
|
119
119
|
const route_parts = path.split('/');
|
|
@@ -161,16 +161,16 @@ export function processRequest<T = any>(
|
|
|
161
161
|
const parts = url
|
|
162
162
|
.replace(/(http|https):\/\/[a-zA-Z0-9.]*:?([0-9]*)?/g, '')
|
|
163
163
|
.split('?');
|
|
164
|
-
const path = parts[0].replace(
|
|
164
|
+
const path = parts[0].replace(/^\//, '');
|
|
165
165
|
const query = parts[1] || '';
|
|
166
166
|
const query_params = convertPairStringToMap(query);
|
|
167
167
|
// Grab route parameters from URL
|
|
168
168
|
const route_parts = path.split('/');
|
|
169
169
|
const route_params: HashMap = {};
|
|
170
|
-
for (
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
170
|
+
for (let i = 0; i < handler.path_structure.length; i++) {
|
|
171
|
+
const paramName = handler.path_structure[i];
|
|
172
|
+
if (paramName) {
|
|
173
|
+
route_params[paramName] = route_parts[i];
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
const request = {
|
|
@@ -196,9 +196,15 @@ export function onMockRequest(
|
|
|
196
196
|
handler: MockHttpRequestHandler,
|
|
197
197
|
request: MockHttpRequest,
|
|
198
198
|
) {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
199
|
+
let result;
|
|
200
|
+
try {
|
|
201
|
+
result = handler.callback
|
|
202
|
+
? handler.callback(request)
|
|
203
|
+
: handler.metadata;
|
|
204
|
+
} catch (error) {
|
|
205
|
+
log('HTTP(M)', `ERROR ${request.method}:`, [request.url, error]);
|
|
206
|
+
throw error;
|
|
207
|
+
}
|
|
202
208
|
const variance = handler.delay_variance || 100;
|
|
203
209
|
const delay_value = handler.delay || 300;
|
|
204
210
|
const delay_time =
|
|
@@ -206,3 +212,11 @@ export function onMockRequest(
|
|
|
206
212
|
log('HTTP(M)', `RESP ${request.method}:`, [request.url, result]);
|
|
207
213
|
return from([result]).pipe(delay(Math.max(200, delay_time)));
|
|
208
214
|
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Get a list of the method + endpoints that have been mocked
|
|
218
|
+
* @returns List of the method + endpoint that have been mocked
|
|
219
|
+
*/
|
|
220
|
+
export function listMockedEndpoints(): string[] {
|
|
221
|
+
return Object.keys(_handlers);
|
|
222
|
+
}
|
|
@@ -18,6 +18,8 @@ export class PlaceRepository extends PlaceResource {
|
|
|
18
18
|
public readonly username: string;
|
|
19
19
|
/** Password to connect to repository with */
|
|
20
20
|
public readonly password: string;
|
|
21
|
+
/** Root path of the repository to serve at the `folder_name` path */
|
|
22
|
+
public readonly root_path: string;
|
|
21
23
|
/** Repository type */
|
|
22
24
|
public get type() {
|
|
23
25
|
return this.repo_type;
|
|
@@ -33,5 +35,6 @@ export class PlaceRepository extends PlaceResource {
|
|
|
33
35
|
this.repo_type = raw_data.repo_type || PlaceRepositoryType.Driver;
|
|
34
36
|
this.username = raw_data.username || '';
|
|
35
37
|
this.password = raw_data.password || '';
|
|
38
|
+
this.root_path = raw_data.root_path || '';
|
|
36
39
|
}
|
|
37
40
|
}
|