@xh/hoist 67.0.0-SNAPSHOT.1723673844830 → 67.0.0-SNAPSHOT.1723841759825
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/CHANGELOG.md +8 -8
- package/build/types/core/XH.d.ts +2 -6
- package/build/types/core/exception/Exception.d.ts +3 -3
- package/build/types/core/types/Interfaces.d.ts +1 -13
- package/build/types/promise/Promise.d.ts +0 -5
- package/build/types/svc/FetchService.d.ts +12 -5
- package/core/XH.ts +1 -10
- package/core/exception/Exception.ts +9 -4
- package/core/types/Interfaces.ts +1 -14
- package/package.json +3 -3
- package/promise/Promise.ts +1 -7
- package/security/BaseOAuthClient.ts +5 -4
- package/svc/FetchService.ts +48 -32
- package/svc/TrackService.ts +4 -2
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,15 +8,15 @@
|
|
|
8
8
|
* New `FetchService` members: `autoGenCorrelationIds`, `genCorrelationId` and
|
|
9
9
|
`correlationIdHeaderKey` to support generation and inclusion of Correlation IDs on outbound
|
|
10
10
|
request headers.
|
|
11
|
-
* Correlation
|
|
11
|
+
* Correlation IDs are assigned via:
|
|
12
12
|
* `FetchOptions.correlationId` - specify an ID to be used on a particular request or `true`
|
|
13
13
|
to use a UUID generated by Hoist (see `FetchService.genCorrelationId()`).
|
|
14
|
-
* `TrackOptions.correlationId` - specify an ID for a tracked activity, if not
|
|
15
|
-
|
|
16
|
-
* If set on a fetch request, Correlation IDs are passed through to downstream
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
* `TrackOptions.correlationId` - specify an ID for a tracked activity, if not using the
|
|
15
|
+
new `FetchOptions.track` API (see below).
|
|
16
|
+
* If set on a fetch request, Correlation IDs are passed through to downstream error reporting
|
|
17
|
+
and are available for review in the Admin Console.
|
|
18
|
+
* New `FetchOptions.track` - specify `TrackOptions` or message `string` to track a request via
|
|
19
|
+
Hoist activity tracking. The request's Correlation ID and LoadSpec will be included automatically.
|
|
20
20
|
* New global interceptors on `FetchService`. See `FetchService.addInterceptor()`.
|
|
21
21
|
* New property `FetchOptions.asJson` to instruct `FetchService` to decode an HTTP response as JSON.
|
|
22
22
|
Note that `FetchService` methods suffixed with `Json` will set this property automatically.
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
|
|
38
38
|
### 📚 Libraries
|
|
39
39
|
|
|
40
|
-
*
|
|
40
|
+
* short-unique-id `added @ 5.2`
|
|
41
41
|
|
|
42
42
|
## 66.1.1 - 2024-08-01
|
|
43
43
|
|
package/build/types/core/XH.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { AppContainerModel } from '../appcontainer/AppContainerModel';
|
|
|
9
9
|
import { BannerModel } from '../appcontainer/BannerModel';
|
|
10
10
|
import { ToastModel } from '../appcontainer/ToastModel';
|
|
11
11
|
import '../styles/XH.scss';
|
|
12
|
-
import { AppSpec, AppState, AppSuspendData, BannerSpec, ExceptionHandler, ExceptionHandlerOptions,
|
|
12
|
+
import { AppSpec, AppState, AppSuspendData, BannerSpec, ExceptionHandler, ExceptionHandlerOptions, HoistAppModel, HoistException, HoistService, HoistServiceClass, HoistUser, MessageSpec, PageState, PlainObject, SizingMode, TaskObserver, Theme, ToastSpec, TrackOptions } from './';
|
|
13
13
|
import { HoistModel, ModelSelector, RefreshContextModel } from './model';
|
|
14
14
|
export declare const MIN_HOIST_CORE_VERSION = "18.0";
|
|
15
15
|
/**
|
|
@@ -117,7 +117,7 @@ export declare class XHApi {
|
|
|
117
117
|
* Send a request via the underlying fetch API.
|
|
118
118
|
* @see FetchService.fetch
|
|
119
119
|
*/
|
|
120
|
-
fetch(opts: FetchOptions): Promise<
|
|
120
|
+
fetch(opts: FetchOptions): Promise<any>;
|
|
121
121
|
/**
|
|
122
122
|
* Send an HTTP request and decode the response as JSON.
|
|
123
123
|
* @see FetchService.fetchJson
|
|
@@ -398,10 +398,6 @@ export declare class XHApi {
|
|
|
398
398
|
* Deliberately *not* intended to be globally unique, suitable for reuse, or to appear as such.
|
|
399
399
|
*/
|
|
400
400
|
genId(): string;
|
|
401
|
-
/**
|
|
402
|
-
* Generate a universally unique identifier (UUID). Useful for generating Correlation IDs.
|
|
403
|
-
*/
|
|
404
|
-
genUUID(): string;
|
|
405
401
|
private get acm();
|
|
406
402
|
}
|
|
407
403
|
/** The app-wide singleton instance. */
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { FetchOptions } from '@xh/hoist/svc';
|
|
2
|
-
import { FetchResponse } from '../';
|
|
3
2
|
import { FetchException, HoistException, TimeoutException, TimeoutExceptionConfig } from './Types';
|
|
4
3
|
/**
|
|
5
4
|
* Standardized Exception/Error objects.
|
|
@@ -26,9 +25,10 @@ export declare class Exception {
|
|
|
26
25
|
/**
|
|
27
26
|
* Create an Error to throw when a fetch call returns a !ok response.
|
|
28
27
|
* @param fetchOptions - original options passed to FetchService.
|
|
29
|
-
* @param
|
|
28
|
+
* @param response - return value of native fetch.
|
|
29
|
+
* @param responseText - optional additional details from the server.
|
|
30
30
|
*/
|
|
31
|
-
static fetchError(fetchOptions: FetchOptions,
|
|
31
|
+
static fetchError(fetchOptions: FetchOptions, response: Response, responseText?: string): FetchException;
|
|
32
32
|
/**
|
|
33
33
|
* Create an Error to throw when a fetchJson call encounters a SyntaxError.
|
|
34
34
|
* @param fetchOptions - original options passed to FetchService.
|
|
@@ -19,15 +19,6 @@ export interface HoistUser {
|
|
|
19
19
|
hasRole(s: string): boolean;
|
|
20
20
|
hasGate(s: string): boolean;
|
|
21
21
|
}
|
|
22
|
-
/**
|
|
23
|
-
* Enhanced Response returned by FetchService.
|
|
24
|
-
*/
|
|
25
|
-
export interface FetchResponse extends Response {
|
|
26
|
-
/**
|
|
27
|
-
* Property containing the already-awaited output of `response.text()`.
|
|
28
|
-
*/
|
|
29
|
-
responseText: string;
|
|
30
|
-
}
|
|
31
22
|
/**
|
|
32
23
|
* Options for showing a "toast" notification that appears and then automatically dismisses.
|
|
33
24
|
*/
|
|
@@ -170,10 +161,7 @@ export interface TrackOptions {
|
|
|
170
161
|
message: string;
|
|
171
162
|
/** App-supplied category.*/
|
|
172
163
|
category?: string;
|
|
173
|
-
/**
|
|
174
|
-
* Correlation ID to save along with track log. If not provided, will attempt to source from the
|
|
175
|
-
* underlying Fetch Request.
|
|
176
|
-
*/
|
|
164
|
+
/** Correlation ID to save along with track log. */
|
|
177
165
|
correlationId?: string;
|
|
178
166
|
/** App-supplied data to save along with track log.*/
|
|
179
167
|
data?: PlainObject | PlainObject[];
|
|
@@ -58,11 +58,6 @@ declare global {
|
|
|
58
58
|
* @param options - TrackOptions, or simply a message string.
|
|
59
59
|
*/
|
|
60
60
|
track(options: TrackOptions | string): Promise<T>;
|
|
61
|
-
/**
|
|
62
|
-
* Set by FetchService to relay correlation IDs to downstream error handling and tracking.
|
|
63
|
-
* @internal
|
|
64
|
-
*/
|
|
65
|
-
correlationId?: string;
|
|
66
61
|
}
|
|
67
62
|
}
|
|
68
63
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Awaitable, HoistService, LoadSpec, PlainObject } from '@xh/hoist/core';
|
|
1
|
+
import { Awaitable, HoistService, LoadSpec, PlainObject, TrackOptions } from '@xh/hoist/core';
|
|
2
2
|
import { PromiseTimeoutSpec } from '@xh/hoist/promise';
|
|
3
3
|
import { StatusCodes } from 'http-status-codes';
|
|
4
4
|
import { IStringifyOptions } from 'qs';
|
|
@@ -24,14 +24,16 @@ import { IStringifyOptions } from 'qs';
|
|
|
24
24
|
export declare class FetchService extends HoistService {
|
|
25
25
|
static instance: FetchService;
|
|
26
26
|
NO_JSON_RESPONSES: StatusCodes[];
|
|
27
|
+
private idGenerator;
|
|
27
28
|
private autoAborters;
|
|
28
29
|
private _defaultHeaders;
|
|
29
30
|
private _interceptors;
|
|
30
31
|
/** True to auto-generate a Correlation ID for each request unless otherwise specified. */
|
|
31
32
|
autoGenCorrelationIds: boolean;
|
|
32
33
|
/**
|
|
33
|
-
* Method for generating Correlation ID's. Defaults to
|
|
34
|
-
*
|
|
34
|
+
* Method for generating Correlation ID's. Defaults to a 16 character random string with
|
|
35
|
+
* an extremely low probability of collisions. Applications may customize
|
|
36
|
+
* to improve readability or provide a stronger uniqueness guarantee.
|
|
35
37
|
*/
|
|
36
38
|
genCorrelationId: () => string;
|
|
37
39
|
/** Request header name to be used for Correlation ID tracking. */
|
|
@@ -68,11 +70,11 @@ export declare class FetchService extends HoistService {
|
|
|
68
70
|
* requests. Other shortcut variants will delegate to this method, after setting
|
|
69
71
|
* default options and pre-processing content.
|
|
70
72
|
*
|
|
71
|
-
* Set `asJson` to true return a parsed JSON result, rather than the raw
|
|
73
|
+
* Set `asJson` to true return a parsed JSON result, rather than the raw Response.
|
|
72
74
|
* Note that shortcut variant of this method (e.g. `fetchJson`, `postJson`) will set this
|
|
73
75
|
* flag for you.
|
|
74
76
|
*
|
|
75
|
-
* @returns Promise which resolves to a
|
|
77
|
+
* @returns Promise which resolves to a Response or JSON.
|
|
76
78
|
*/
|
|
77
79
|
fetch(opts: FetchOptions): Promise<any>;
|
|
78
80
|
/**
|
|
@@ -199,4 +201,9 @@ export interface FetchOptions {
|
|
|
199
201
|
* True to decode the HTTP response as JSON. Default false.
|
|
200
202
|
*/
|
|
201
203
|
asJson?: boolean;
|
|
204
|
+
/**
|
|
205
|
+
* If set, the request will be tracked via Hoist activity tracking. (Do not set `correlationId`
|
|
206
|
+
* here - use the top-level `correlationId` property instead.)
|
|
207
|
+
*/
|
|
208
|
+
track?: string | TrackOptions;
|
|
202
209
|
}
|
package/core/XH.ts
CHANGED
|
@@ -46,7 +46,6 @@ import {
|
|
|
46
46
|
Exception,
|
|
47
47
|
ExceptionHandler,
|
|
48
48
|
ExceptionHandlerOptions,
|
|
49
|
-
FetchResponse,
|
|
50
49
|
HoistAppModel,
|
|
51
50
|
HoistException,
|
|
52
51
|
HoistService,
|
|
@@ -64,7 +63,6 @@ import {
|
|
|
64
63
|
import {installServicesAsync} from './impl/InstallServices';
|
|
65
64
|
import {instanceManager} from './impl/InstanceManager';
|
|
66
65
|
import {HoistModel, ModelSelector, RefreshContextModel} from './model';
|
|
67
|
-
import {v4} from 'uuid';
|
|
68
66
|
|
|
69
67
|
export const MIN_HOIST_CORE_VERSION = '18.0';
|
|
70
68
|
|
|
@@ -263,7 +261,7 @@ export class XHApi {
|
|
|
263
261
|
* Send a request via the underlying fetch API.
|
|
264
262
|
* @see FetchService.fetch
|
|
265
263
|
*/
|
|
266
|
-
fetch(opts: FetchOptions): Promise<
|
|
264
|
+
fetch(opts: FetchOptions): Promise<any> {
|
|
267
265
|
return this.fetchService.fetch(opts);
|
|
268
266
|
}
|
|
269
267
|
|
|
@@ -781,13 +779,6 @@ export class XHApi {
|
|
|
781
779
|
return uniqueId('xh-id-');
|
|
782
780
|
}
|
|
783
781
|
|
|
784
|
-
/**
|
|
785
|
-
* Generate a universally unique identifier (UUID). Useful for generating Correlation IDs.
|
|
786
|
-
*/
|
|
787
|
-
genUUID(): string {
|
|
788
|
-
return v4();
|
|
789
|
-
}
|
|
790
|
-
|
|
791
782
|
//----------------
|
|
792
783
|
// Implementation
|
|
793
784
|
//----------------
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Copyright © 2024 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
7
|
import {FetchOptions} from '@xh/hoist/svc';
|
|
8
|
-
import {
|
|
8
|
+
import {PlainObject, XH} from '../';
|
|
9
9
|
import {isPlainObject} from 'lodash';
|
|
10
10
|
|
|
11
11
|
import {FetchException, HoistException, TimeoutException, TimeoutExceptionConfig} from './Types';
|
|
@@ -58,10 +58,15 @@ export class Exception {
|
|
|
58
58
|
/**
|
|
59
59
|
* Create an Error to throw when a fetch call returns a !ok response.
|
|
60
60
|
* @param fetchOptions - original options passed to FetchService.
|
|
61
|
-
* @param
|
|
61
|
+
* @param response - return value of native fetch.
|
|
62
|
+
* @param responseText - optional additional details from the server.
|
|
62
63
|
*/
|
|
63
|
-
static fetchError(
|
|
64
|
-
|
|
64
|
+
static fetchError(
|
|
65
|
+
fetchOptions: FetchOptions,
|
|
66
|
+
response: Response,
|
|
67
|
+
responseText: string = null
|
|
68
|
+
): FetchException {
|
|
69
|
+
const {headers, status, statusText} = response,
|
|
65
70
|
defaults = {
|
|
66
71
|
name: 'HTTP Error ' + (status || ''),
|
|
67
72
|
message: statusText,
|
package/core/types/Interfaces.ts
CHANGED
|
@@ -28,16 +28,6 @@ export interface HoistUser {
|
|
|
28
28
|
hasGate(s: string): boolean;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
/**
|
|
32
|
-
* Enhanced Response returned by FetchService.
|
|
33
|
-
*/
|
|
34
|
-
export interface FetchResponse extends Response {
|
|
35
|
-
/**
|
|
36
|
-
* Property containing the already-awaited output of `response.text()`.
|
|
37
|
-
*/
|
|
38
|
-
responseText: string;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
31
|
/**
|
|
42
32
|
* Options for showing a "toast" notification that appears and then automatically dismisses.
|
|
43
33
|
*/
|
|
@@ -213,10 +203,7 @@ export interface TrackOptions {
|
|
|
213
203
|
/** App-supplied category.*/
|
|
214
204
|
category?: string;
|
|
215
205
|
|
|
216
|
-
/**
|
|
217
|
-
* Correlation ID to save along with track log. If not provided, will attempt to source from the
|
|
218
|
-
* underlying Fetch Request.
|
|
219
|
-
*/
|
|
206
|
+
/** Correlation ID to save along with track log. */
|
|
220
207
|
correlationId?: string;
|
|
221
208
|
|
|
222
209
|
/** App-supplied data to save along with track log.*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xh/hoist",
|
|
3
|
-
"version": "67.0.0-SNAPSHOT.
|
|
3
|
+
"version": "67.0.0-SNAPSHOT.1723841759825",
|
|
4
4
|
"description": "Hoist add-on for building and deploying React Applications.",
|
|
5
5
|
"repository": "github:xh/hoist-react",
|
|
6
6
|
"homepage": "https://xh.io",
|
|
@@ -83,9 +83,9 @@
|
|
|
83
83
|
"router5": "~7.0.2",
|
|
84
84
|
"router5-plugin-browser": "~7.0.2",
|
|
85
85
|
"semver": "~7.6.0",
|
|
86
|
+
"short-unique-id": "~5.2.0",
|
|
86
87
|
"store2": "~2.13.1",
|
|
87
|
-
"ua-parser-js": "~1.0.2"
|
|
88
|
-
"uuid": "~10.0.0"
|
|
88
|
+
"ua-parser-js": "~1.0.2"
|
|
89
89
|
},
|
|
90
90
|
"peerDependencies": {
|
|
91
91
|
"react": "~18.2.0",
|
package/promise/Promise.ts
CHANGED
|
@@ -92,12 +92,6 @@ declare global {
|
|
|
92
92
|
* @param options - TrackOptions, or simply a message string.
|
|
93
93
|
*/
|
|
94
94
|
track(options: TrackOptions | string): Promise<T>;
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Set by FetchService to relay correlation IDs to downstream error handling and tracking.
|
|
98
|
-
* @internal
|
|
99
|
-
*/
|
|
100
|
-
correlationId?: string;
|
|
101
95
|
}
|
|
102
96
|
}
|
|
103
97
|
|
|
@@ -206,7 +200,7 @@ const enhancePromise = promisePrototype => {
|
|
|
206
200
|
const startTime = Date.now();
|
|
207
201
|
return this.finally(() => {
|
|
208
202
|
options.elapsed = Date.now() - startTime;
|
|
209
|
-
XH.track(
|
|
203
|
+
XH.track(options);
|
|
210
204
|
});
|
|
211
205
|
},
|
|
212
206
|
|
|
@@ -11,7 +11,7 @@ import {Timer} from '@xh/hoist/utils/async';
|
|
|
11
11
|
import {MINUTES, olderThan, ONE_MINUTE, SECONDS} from '@xh/hoist/utils/datetime';
|
|
12
12
|
import {isJSON, throwIf} from '@xh/hoist/utils/js';
|
|
13
13
|
import {find, forEach, isEmpty, isObject, keys, pickBy, union} from 'lodash';
|
|
14
|
-
import
|
|
14
|
+
import ShortUniqueId from 'short-unique-id';
|
|
15
15
|
|
|
16
16
|
export type LoginMethod = 'REDIRECT' | 'POPUP';
|
|
17
17
|
|
|
@@ -254,11 +254,12 @@ export abstract class BaseOAuthClient<C extends BaseOAuthClientConfig<S>, S> ext
|
|
|
254
254
|
*/
|
|
255
255
|
protected captureRedirectState(): string {
|
|
256
256
|
const {pathname, search} = window.location,
|
|
257
|
+
key = new ShortUniqueId({length: 8}).rnd(),
|
|
257
258
|
state = {
|
|
258
|
-
key
|
|
259
|
-
timestamp: Date.now(),
|
|
259
|
+
key,
|
|
260
260
|
pathname,
|
|
261
|
-
search
|
|
261
|
+
search,
|
|
262
|
+
timestamp: Date.now()
|
|
262
263
|
};
|
|
263
264
|
|
|
264
265
|
const recs = this.getLocalStorage('xhOAuthState', []).filter(
|
package/svc/FetchService.ts
CHANGED
|
@@ -7,18 +7,19 @@
|
|
|
7
7
|
import {
|
|
8
8
|
Awaitable,
|
|
9
9
|
Exception,
|
|
10
|
-
FetchResponse,
|
|
11
10
|
HoistService,
|
|
12
11
|
LoadSpec,
|
|
13
12
|
PlainObject,
|
|
13
|
+
TrackOptions,
|
|
14
14
|
XH
|
|
15
15
|
} from '@xh/hoist/core';
|
|
16
16
|
import {PromiseTimeoutSpec} from '@xh/hoist/promise';
|
|
17
17
|
import {isLocalDate, SECONDS} from '@xh/hoist/utils/datetime';
|
|
18
|
-
import {apiDeprecated} from '@xh/hoist/utils/js';
|
|
18
|
+
import {apiDeprecated, warnIf} from '@xh/hoist/utils/js';
|
|
19
19
|
import {StatusCodes} from 'http-status-codes';
|
|
20
20
|
import {isDate, isFunction, isNil, isObject, isString, omit, omitBy} from 'lodash';
|
|
21
21
|
import {IStringifyOptions, stringify} from 'qs';
|
|
22
|
+
import ShortUniqueId from 'short-unique-id';
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Service for making managed HTTP requests, both to the app's own Hoist server and to remote APIs.
|
|
@@ -44,6 +45,7 @@ export class FetchService extends HoistService {
|
|
|
44
45
|
|
|
45
46
|
NO_JSON_RESPONSES = [StatusCodes.NO_CONTENT, StatusCodes.RESET_CONTENT];
|
|
46
47
|
|
|
48
|
+
private idGenerator = new ShortUniqueId({length: 16});
|
|
47
49
|
private autoAborters = {};
|
|
48
50
|
private _defaultHeaders: DefaultHeaders[] = [];
|
|
49
51
|
private _interceptors: FetchInterceptor[] = [];
|
|
@@ -54,10 +56,11 @@ export class FetchService extends HoistService {
|
|
|
54
56
|
autoGenCorrelationIds = false;
|
|
55
57
|
|
|
56
58
|
/**
|
|
57
|
-
* Method for generating Correlation ID's. Defaults to
|
|
58
|
-
*
|
|
59
|
+
* Method for generating Correlation ID's. Defaults to a 16 character random string with
|
|
60
|
+
* an extremely low probability of collisions. Applications may customize
|
|
61
|
+
* to improve readability or provide a stronger uniqueness guarantee.
|
|
59
62
|
*/
|
|
60
|
-
genCorrelationId: () => string = () =>
|
|
63
|
+
genCorrelationId: () => string = () => this.idGenerator.rnd();
|
|
61
64
|
|
|
62
65
|
/** Request header name to be used for Correlation ID tracking. */
|
|
63
66
|
correlationIdHeaderKey: string = 'X-Correlation-ID';
|
|
@@ -107,13 +110,13 @@ export class FetchService extends HoistService {
|
|
|
107
110
|
* requests. Other shortcut variants will delegate to this method, after setting
|
|
108
111
|
* default options and pre-processing content.
|
|
109
112
|
*
|
|
110
|
-
* Set `asJson` to true return a parsed JSON result, rather than the raw
|
|
113
|
+
* Set `asJson` to true return a parsed JSON result, rather than the raw Response.
|
|
111
114
|
* Note that shortcut variant of this method (e.g. `fetchJson`, `postJson`) will set this
|
|
112
115
|
* flag for you.
|
|
113
116
|
*
|
|
114
|
-
* @returns Promise which resolves to a
|
|
117
|
+
* @returns Promise which resolves to a Response or JSON.
|
|
115
118
|
*/
|
|
116
|
-
fetch(opts: FetchOptions): Promise<any> {
|
|
119
|
+
async fetch(opts: FetchOptions): Promise<any> {
|
|
117
120
|
return this.fetchInternalAsync(opts);
|
|
118
121
|
}
|
|
119
122
|
|
|
@@ -121,7 +124,7 @@ export class FetchService extends HoistService {
|
|
|
121
124
|
* Send an HTTP request and decode the response as JSON.
|
|
122
125
|
* @returns the decoded JSON object, or null if the response has status in {@link NO_JSON_RESPONSES}.
|
|
123
126
|
*/
|
|
124
|
-
fetchJson(opts: FetchOptions): Promise<any> {
|
|
127
|
+
async fetchJson(opts: FetchOptions): Promise<any> {
|
|
125
128
|
return this.fetchInternalAsync({asJson: true, ...opts});
|
|
126
129
|
}
|
|
127
130
|
|
|
@@ -129,7 +132,7 @@ export class FetchService extends HoistService {
|
|
|
129
132
|
* Send a GET request and decode the response as JSON.
|
|
130
133
|
* @returns the decoded JSON object, or null if the response status is in {@link NO_JSON_RESPONSES}.
|
|
131
134
|
*/
|
|
132
|
-
getJson(opts: FetchOptions): Promise<any> {
|
|
135
|
+
async getJson(opts: FetchOptions): Promise<any> {
|
|
133
136
|
return this.fetchInternalAsync({asJson: true, method: 'GET', ...opts});
|
|
134
137
|
}
|
|
135
138
|
|
|
@@ -137,7 +140,7 @@ export class FetchService extends HoistService {
|
|
|
137
140
|
* Send a POST request with a JSON body and decode the response as JSON.
|
|
138
141
|
* @returns the decoded JSON object, or null if the response status is in {@link NO_JSON_RESPONSES}.
|
|
139
142
|
*/
|
|
140
|
-
postJson(opts: FetchOptions): Promise<any> {
|
|
143
|
+
async postJson(opts: FetchOptions): Promise<any> {
|
|
141
144
|
return this.sendJsonInternalAsync({method: 'POST', ...opts});
|
|
142
145
|
}
|
|
143
146
|
|
|
@@ -145,7 +148,7 @@ export class FetchService extends HoistService {
|
|
|
145
148
|
* Send a PUT request with a JSON body and decode the response as JSON.
|
|
146
149
|
* @returns the decoded JSON object, or null if the response status is in {@link NO_JSON_RESPONSES}.
|
|
147
150
|
*/
|
|
148
|
-
putJson(opts: FetchOptions): Promise<any> {
|
|
151
|
+
async putJson(opts: FetchOptions): Promise<any> {
|
|
149
152
|
return this.sendJsonInternalAsync({method: 'PUT', ...opts});
|
|
150
153
|
}
|
|
151
154
|
|
|
@@ -153,7 +156,7 @@ export class FetchService extends HoistService {
|
|
|
153
156
|
* Send a PATCH request with a JSON body and decode the response as JSON.
|
|
154
157
|
* @returns the decoded JSON object, or null if the response status is in {@link NO_JSON_RESPONSES}.
|
|
155
158
|
*/
|
|
156
|
-
patchJson(opts: FetchOptions): Promise<any> {
|
|
159
|
+
async patchJson(opts: FetchOptions): Promise<any> {
|
|
157
160
|
return this.sendJsonInternalAsync({method: 'PATCH', ...opts});
|
|
158
161
|
}
|
|
159
162
|
|
|
@@ -161,7 +164,7 @@ export class FetchService extends HoistService {
|
|
|
161
164
|
* Send a DELETE request with optional JSON body and decode the optional response as JSON.
|
|
162
165
|
* @returns the decoded JSON object, or null if the response status is in {@link NO_JSON_RESPONSES}.
|
|
163
166
|
*/
|
|
164
|
-
deleteJson(opts: FetchOptions): Promise<any> {
|
|
167
|
+
async deleteJson(opts: FetchOptions): Promise<any> {
|
|
165
168
|
return this.sendJsonInternalAsync({method: 'DELETE', ...opts});
|
|
166
169
|
}
|
|
167
170
|
|
|
@@ -209,20 +212,30 @@ export class FetchService extends HoistService {
|
|
|
209
212
|
//-----------------------
|
|
210
213
|
// Implementation
|
|
211
214
|
//-----------------------
|
|
212
|
-
private fetchInternalAsync(opts: FetchOptions): Promise<any> {
|
|
215
|
+
private async fetchInternalAsync(opts: FetchOptions): Promise<any> {
|
|
213
216
|
opts = this.withCorrelationId(opts);
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
217
|
+
opts = await this.withDefaultHeadersAsync(opts);
|
|
218
|
+
let ret = this.managedFetchAsync(opts);
|
|
219
|
+
|
|
220
|
+
// Apply tracking
|
|
221
|
+
const {correlationId, loadSpec, track} = opts;
|
|
222
|
+
if (track) {
|
|
223
|
+
const trackOptions = isString(track) ? {message: track} : track;
|
|
224
|
+
warnIf(
|
|
225
|
+
trackOptions.correlationId || trackOptions.loadSpec,
|
|
226
|
+
'Neither Correlation ID nor LoadSpec should be set in `FetchOptions.track`. Use `FetchOptions` top-level properties instead.'
|
|
227
|
+
);
|
|
228
|
+
ret = ret.track({...trackOptions, correlationId: correlationId as string, loadSpec});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Apply interceptors
|
|
232
|
+
for (const interceptor of this._interceptors) {
|
|
233
|
+
ret = ret.then(
|
|
234
|
+
value => interceptor.onFulfilled(opts, value),
|
|
235
|
+
cause => interceptor.onRejected(opts, cause)
|
|
236
|
+
);
|
|
237
|
+
}
|
|
224
238
|
|
|
225
|
-
ret.correlationId = opts.correlationId as string;
|
|
226
239
|
return ret;
|
|
227
240
|
}
|
|
228
241
|
|
|
@@ -322,7 +335,7 @@ export class FetchService extends HoistService {
|
|
|
322
335
|
private async abortableFetchAsync(
|
|
323
336
|
opts: FetchOptions,
|
|
324
337
|
aborter: AbortController
|
|
325
|
-
): Promise<
|
|
338
|
+
): Promise<Response> {
|
|
326
339
|
// 1) Prepare URL
|
|
327
340
|
let {url, method, headers, body, params} = opts,
|
|
328
341
|
isRelativeUrl = !url.startsWith('/') && !url.includes('//');
|
|
@@ -363,12 +376,9 @@ export class FetchService extends HoistService {
|
|
|
363
376
|
}
|
|
364
377
|
|
|
365
378
|
// 4) Await underlying fetch and post-process response.
|
|
366
|
-
const ret =
|
|
379
|
+
const ret = await fetch(url, fetchOpts);
|
|
367
380
|
|
|
368
|
-
if (!ret.ok)
|
|
369
|
-
ret.responseText = await this.safeResponseTextAsync(ret);
|
|
370
|
-
throw Exception.fetchError(opts, ret);
|
|
371
|
-
}
|
|
381
|
+
if (!ret.ok) throw Exception.fetchError(opts, ret, await this.safeResponseTextAsync(ret));
|
|
372
382
|
|
|
373
383
|
return ret;
|
|
374
384
|
}
|
|
@@ -475,4 +485,10 @@ export interface FetchOptions {
|
|
|
475
485
|
* True to decode the HTTP response as JSON. Default false.
|
|
476
486
|
*/
|
|
477
487
|
asJson?: boolean;
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* If set, the request will be tracked via Hoist activity tracking. (Do not set `correlationId`
|
|
491
|
+
* here - use the top-level `correlationId` property instead.)
|
|
492
|
+
*/
|
|
493
|
+
track?: string | TrackOptions;
|
|
478
494
|
}
|
package/svc/TrackService.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import {HoistService, TrackOptions, XH} from '@xh/hoist/core';
|
|
8
8
|
import {isOmitted} from '@xh/hoist/utils/impl';
|
|
9
9
|
import {stripTags, withDefault} from '@xh/hoist/utils/js';
|
|
10
|
-
import {isString} from 'lodash';
|
|
10
|
+
import {isNil, isString} from 'lodash';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Primary service for tracking any activity that an application's admins want to track.
|
|
@@ -104,7 +104,9 @@ export class TrackService extends HoistService {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
const elapsedStr = query.elapsed != null ? `${query.elapsed}ms` : null,
|
|
107
|
-
consoleMsgs = [query.category, query.msg, elapsedStr].filter(
|
|
107
|
+
consoleMsgs = [query.category, query.msg, query.correlationId, elapsedStr].filter(
|
|
108
|
+
it => !isNil(it)
|
|
109
|
+
);
|
|
108
110
|
|
|
109
111
|
this.logInfo(...consoleMsgs);
|
|
110
112
|
|