@naturalcycles/js-lib 15.50.1 → 15.52.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.
@@ -56,6 +56,15 @@ export interface ErrorData {
56
56
  * Sentry takes string[], but for convenience we allow to pass a singe string.
57
57
  */
58
58
  fingerprint?: string;
59
+ /**
60
+ * Similar to fingerprint, with one important difference.
61
+ *
62
+ * fingerprint means FINAL fingerprint that'll be used for error reporting as is.
63
+ *
64
+ * errorGroup is meant to be used as a COMPONENT to construct a fingerprint, but not
65
+ * an exhaustive fingerprint by itself.
66
+ */
67
+ errorGroup?: string;
59
68
  /**
60
69
  * Set when throwing an error from your backend code, to indicate desired http status code.
61
70
  * e.g throw new AppError('oj', { backendResponseStatusCode: 401 })
@@ -86,6 +95,9 @@ export interface HttpRequestErrorData extends ErrorData {
86
95
  * Non-enumerable.
87
96
  */
88
97
  response?: Response;
98
+ /**
99
+ * Full request url, inclusing baseUrl, inputUrl, searchParams, etc.
100
+ */
89
101
  requestUrl: string;
90
102
  requestBaseUrl?: string;
91
103
  requestMethod: HttpMethod;
@@ -95,6 +107,15 @@ export interface HttpRequestErrorData extends ErrorData {
95
107
  * GET /some/url
96
108
  */
97
109
  requestSignature: string;
110
+ /**
111
+ * FetcherOptions.requestName, if it was provided.
112
+ * Allows to construct errorGroup/fingerprint.
113
+ */
114
+ requestName?: string;
115
+ /**
116
+ * FetcherCfg.name if it was provided, for the purpose of constructing an error fingerprint.
117
+ */
118
+ fetcherName?: string;
98
119
  /**
99
120
  * Can be set to 0 if request "failed to start" or "failed to reach the server".
100
121
  */
@@ -160,6 +160,8 @@ export class Fetcher {
160
160
  requestBaseUrl: this.cfg.baseUrl,
161
161
  requestMethod: res.req.init.method,
162
162
  requestSignature: res.signature,
163
+ requestName: res.req.requestName,
164
+ fetcherName: this.cfg.name,
163
165
  requestDuration: Date.now() - res.req.started,
164
166
  });
165
167
  }
@@ -440,6 +442,8 @@ export class Fetcher {
440
442
  requestBaseUrl: this.cfg.baseUrl || undefined,
441
443
  requestMethod: res.req.init.method,
442
444
  requestSignature: res.signature,
445
+ requestName: res.req.requestName,
446
+ fetcherName: this.cfg.name,
443
447
  requestDuration: Date.now() - res.req.started,
444
448
  }), {
445
449
  cause,
@@ -580,13 +584,14 @@ export class Fetcher {
580
584
  return shortUrl;
581
585
  }
582
586
  normalizeCfg(cfg) {
587
+ const { debug = false, logger = console } = cfg;
583
588
  if (cfg.baseUrl?.endsWith('/')) {
584
- console.warn(`Fetcher: baseUrl should not end with slash: ${cfg.baseUrl}`);
589
+ logger.warn(`Fetcher: baseUrl should not end with slash: ${cfg.baseUrl}`);
585
590
  cfg.baseUrl = cfg.baseUrl.slice(0, cfg.baseUrl.length - 1);
586
591
  }
587
- const { debug = false } = cfg;
588
592
  const norm = _merge({
589
593
  baseUrl: '',
594
+ name: '',
590
595
  inputUrl: '',
591
596
  responseType: 'json',
592
597
  searchParams: {},
@@ -595,8 +600,7 @@ export class Fetcher {
595
600
  retry3xx: false,
596
601
  retry4xx: false,
597
602
  retry5xx: true,
598
- // logger: console, Danger! doing this mutates console!
599
- logger: cfg.logger || console,
603
+ logger,
600
604
  debug,
601
605
  logRequest: debug,
602
606
  logRequestBody: debug,
@@ -665,11 +669,12 @@ export class Fetcher {
665
669
  // setup url
666
670
  const baseUrl = opt.baseUrl || this.cfg.baseUrl;
667
671
  if (baseUrl) {
668
- if (req.fullUrl.startsWith('/')) {
669
- console.warn('Fetcher: url should not start with / when baseUrl is specified');
670
- req.fullUrl = req.fullUrl.slice(1);
672
+ let { inputUrl } = req;
673
+ if (inputUrl.startsWith('/')) {
674
+ this.cfg.logger.warn('Fetcher: url should not start with / when baseUrl is specified');
675
+ inputUrl = inputUrl.slice(1);
671
676
  }
672
- req.fullUrl = `${baseUrl}/${req.inputUrl}`;
677
+ req.fullUrl = `${baseUrl}/${inputUrl}`;
673
678
  }
674
679
  const searchParams = _filterUndefinedValues({
675
680
  ...this.cfg.searchParams,
@@ -26,6 +26,12 @@ export interface FetcherCfg {
26
26
  * Should **not** contain trailing slash.
27
27
  */
28
28
  baseUrl?: string;
29
+ /**
30
+ * "Name" of the fetcher.
31
+ * Accessible inside HttpRequestError, to be able to construct a good fingerprint.
32
+ * If name is not provided - baseUrl is used to identify a Fetcher.
33
+ */
34
+ name?: string;
29
35
  /**
30
36
  * Default rule is that you **are allowed** to mutate req, res, res.retryStatus
31
37
  * properties of hook function arguments.
@@ -263,6 +269,12 @@ export interface FetcherOptions {
263
269
  * Cannot cancel/prevent the error - AfterResponseHook can be used for that instead.
264
270
  */
265
271
  onError?: FetcherOnErrorHook;
272
+ /**
273
+ * If provided - will be passed further to HttpRequestError if error happens,
274
+ * allowing to construct an errorGroup/fingerprint to be able to group errors
275
+ * related to "this type of request".
276
+ */
277
+ requestName?: string;
266
278
  }
267
279
  export type RequestInitNormalized = Omit<RequestInit, 'method' | 'headers'> & {
268
280
  method: HttpMethod;
@@ -13,6 +13,7 @@ import type { Reviver } from '../types.js';
13
13
  * It's recommended that this function is circular-reference-safe.
14
14
  */
15
15
  export declare function setGlobalStringifyFunction(fn: JsonStringifyFunction): void;
16
+ export declare function resetGlobalStringifyFunction(): void;
16
17
  export type JsonStringifyFunction = (obj: any, reviver?: Reviver, space?: number) => string;
17
18
  export interface StringifyOptions {
18
19
  /**
@@ -20,6 +20,9 @@ let globalStringifyFunction = _safeJsonStringify;
20
20
  export function setGlobalStringifyFunction(fn) {
21
21
  globalStringifyFunction = fn;
22
22
  }
23
+ export function resetGlobalStringifyFunction() {
24
+ globalStringifyFunction = _safeJsonStringify;
25
+ }
23
26
  /**
24
27
  * Inspired by `_inspect` from nodejs-lib, which is based on util.inpect that is not available in the Browser.
25
28
  * Potentially can do this (with extra 2Kb gz size): https://github.com/deecewan/browser-util-inspect
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
3
  "type": "module",
4
- "version": "15.50.1",
4
+ "version": "15.52.0",
5
5
  "dependencies": {
6
6
  "tslib": "^2",
7
7
  "undici": "^7",
@@ -13,7 +13,7 @@
13
13
  "@types/semver": "^7",
14
14
  "crypto-js": "^4",
15
15
  "dayjs": "^1",
16
- "@naturalcycles/dev-lib": "20.12.10"
16
+ "@naturalcycles/dev-lib": "18.4.2"
17
17
  },
18
18
  "exports": {
19
19
  ".": "./dist/index.js",
@@ -65,6 +65,16 @@ export interface ErrorData {
65
65
  */
66
66
  fingerprint?: string
67
67
 
68
+ /**
69
+ * Similar to fingerprint, with one important difference.
70
+ *
71
+ * fingerprint means FINAL fingerprint that'll be used for error reporting as is.
72
+ *
73
+ * errorGroup is meant to be used as a COMPONENT to construct a fingerprint, but not
74
+ * an exhaustive fingerprint by itself.
75
+ */
76
+ errorGroup?: string
77
+
68
78
  /**
69
79
  * Set when throwing an error from your backend code, to indicate desired http status code.
70
80
  * e.g throw new AppError('oj', { backendResponseStatusCode: 401 })
@@ -100,7 +110,9 @@ export interface HttpRequestErrorData extends ErrorData {
100
110
  * Non-enumerable.
101
111
  */
102
112
  response?: Response
103
-
113
+ /**
114
+ * Full request url, inclusing baseUrl, inputUrl, searchParams, etc.
115
+ */
104
116
  requestUrl: string
105
117
  requestBaseUrl?: string
106
118
  requestMethod: HttpMethod
@@ -110,6 +122,15 @@ export interface HttpRequestErrorData extends ErrorData {
110
122
  * GET /some/url
111
123
  */
112
124
  requestSignature: string
125
+ /**
126
+ * FetcherOptions.requestName, if it was provided.
127
+ * Allows to construct errorGroup/fingerprint.
128
+ */
129
+ requestName?: string
130
+ /**
131
+ * FetcherCfg.name if it was provided, for the purpose of constructing an error fingerprint.
132
+ */
133
+ fetcherName?: string
113
134
  /**
114
135
  * Can be set to 0 if request "failed to start" or "failed to reach the server".
115
136
  */
@@ -57,6 +57,13 @@ export interface FetcherCfg {
57
57
  */
58
58
  baseUrl?: string
59
59
 
60
+ /**
61
+ * "Name" of the fetcher.
62
+ * Accessible inside HttpRequestError, to be able to construct a good fingerprint.
63
+ * If name is not provided - baseUrl is used to identify a Fetcher.
64
+ */
65
+ name?: string
66
+
60
67
  /**
61
68
  * Default rule is that you **are allowed** to mutate req, res, res.retryStatus
62
69
  * properties of hook function arguments.
@@ -333,6 +340,13 @@ export interface FetcherOptions {
333
340
  * Cannot cancel/prevent the error - AfterResponseHook can be used for that instead.
334
341
  */
335
342
  onError?: FetcherOnErrorHook
343
+
344
+ /**
345
+ * If provided - will be passed further to HttpRequestError if error happens,
346
+ * allowing to construct an errorGroup/fingerprint to be able to group errors
347
+ * related to "this type of request".
348
+ */
349
+ requestName?: string
336
350
  }
337
351
 
338
352
  export type RequestInitNormalized = Omit<RequestInit, 'method' | 'headers'> & {
@@ -221,6 +221,8 @@ export class Fetcher {
221
221
  requestBaseUrl: this.cfg.baseUrl,
222
222
  requestMethod: res.req.init.method,
223
223
  requestSignature: res.signature,
224
+ requestName: res.req.requestName,
225
+ fetcherName: this.cfg.name,
224
226
  requestDuration: Date.now() - res.req.started,
225
227
  })
226
228
  }
@@ -551,6 +553,8 @@ export class Fetcher {
551
553
  requestBaseUrl: this.cfg.baseUrl || undefined,
552
554
  requestMethod: res.req.init.method,
553
555
  requestSignature: res.signature,
556
+ requestName: res.req.requestName,
557
+ fetcherName: this.cfg.name,
554
558
  requestDuration: Date.now() - res.req.started,
555
559
  }),
556
560
  {
@@ -712,15 +716,17 @@ export class Fetcher {
712
716
  }
713
717
 
714
718
  private normalizeCfg(cfg: FetcherCfg & FetcherOptions): FetcherNormalizedCfg {
719
+ const { debug = false, logger = console } = cfg
720
+
715
721
  if (cfg.baseUrl?.endsWith('/')) {
716
- console.warn(`Fetcher: baseUrl should not end with slash: ${cfg.baseUrl}`)
722
+ logger.warn(`Fetcher: baseUrl should not end with slash: ${cfg.baseUrl}`)
717
723
  cfg.baseUrl = cfg.baseUrl.slice(0, cfg.baseUrl.length - 1)
718
724
  }
719
- const { debug = false } = cfg
720
725
 
721
726
  const norm: FetcherNormalizedCfg = _merge(
722
727
  {
723
728
  baseUrl: '',
729
+ name: '',
724
730
  inputUrl: '',
725
731
  responseType: 'json',
726
732
  searchParams: {},
@@ -729,8 +735,7 @@ export class Fetcher {
729
735
  retry3xx: false,
730
736
  retry4xx: false,
731
737
  retry5xx: true,
732
- // logger: console, Danger! doing this mutates console!
733
- logger: cfg.logger || console,
738
+ logger,
734
739
  debug,
735
740
  logRequest: debug,
736
741
  logRequestBody: debug,
@@ -809,11 +814,12 @@ export class Fetcher {
809
814
  // setup url
810
815
  const baseUrl = opt.baseUrl || this.cfg.baseUrl
811
816
  if (baseUrl) {
812
- if (req.fullUrl.startsWith('/')) {
813
- console.warn('Fetcher: url should not start with / when baseUrl is specified')
814
- req.fullUrl = req.fullUrl.slice(1)
817
+ let { inputUrl } = req
818
+ if (inputUrl.startsWith('/')) {
819
+ this.cfg.logger.warn('Fetcher: url should not start with / when baseUrl is specified')
820
+ inputUrl = inputUrl.slice(1)
815
821
  }
816
- req.fullUrl = `${baseUrl}/${req.inputUrl}`
822
+ req.fullUrl = `${baseUrl}/${inputUrl}`
817
823
  }
818
824
 
819
825
  const searchParams = _filterUndefinedValues({
@@ -26,6 +26,10 @@ export function setGlobalStringifyFunction(fn: JsonStringifyFunction): void {
26
26
  globalStringifyFunction = fn
27
27
  }
28
28
 
29
+ export function resetGlobalStringifyFunction(): void {
30
+ globalStringifyFunction = _safeJsonStringify
31
+ }
32
+
29
33
  export type JsonStringifyFunction = (obj: any, reviver?: Reviver, space?: number) => string
30
34
 
31
35
  export interface StringifyOptions {