@naturalcycles/js-lib 15.50.1 → 15.51.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 })
@@ -95,6 +104,11 @@ export interface HttpRequestErrorData extends ErrorData {
95
104
  * GET /some/url
96
105
  */
97
106
  requestSignature: string;
107
+ /**
108
+ * FetcherOptions.requestName, if it was provided.
109
+ * Allows to construct errorGroup/fingerprint.
110
+ */
111
+ requestName?: string;
98
112
  /**
99
113
  * Can be set to 0 if request "failed to start" or "failed to reach the server".
100
114
  */
@@ -440,6 +440,7 @@ export class Fetcher {
440
440
  requestBaseUrl: this.cfg.baseUrl || undefined,
441
441
  requestMethod: res.req.init.method,
442
442
  requestSignature: res.signature,
443
+ requestName: res.req.requestName,
443
444
  requestDuration: Date.now() - res.req.started,
444
445
  }), {
445
446
  cause,
@@ -580,11 +581,11 @@ export class Fetcher {
580
581
  return shortUrl;
581
582
  }
582
583
  normalizeCfg(cfg) {
584
+ const { debug = false, logger = console } = cfg;
583
585
  if (cfg.baseUrl?.endsWith('/')) {
584
- console.warn(`Fetcher: baseUrl should not end with slash: ${cfg.baseUrl}`);
586
+ logger.warn(`Fetcher: baseUrl should not end with slash: ${cfg.baseUrl}`);
585
587
  cfg.baseUrl = cfg.baseUrl.slice(0, cfg.baseUrl.length - 1);
586
588
  }
587
- const { debug = false } = cfg;
588
589
  const norm = _merge({
589
590
  baseUrl: '',
590
591
  inputUrl: '',
@@ -595,8 +596,7 @@ export class Fetcher {
595
596
  retry3xx: false,
596
597
  retry4xx: false,
597
598
  retry5xx: true,
598
- // logger: console, Danger! doing this mutates console!
599
- logger: cfg.logger || console,
599
+ logger,
600
600
  debug,
601
601
  logRequest: debug,
602
602
  logRequestBody: debug,
@@ -665,11 +665,12 @@ export class Fetcher {
665
665
  // setup url
666
666
  const baseUrl = opt.baseUrl || this.cfg.baseUrl;
667
667
  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);
668
+ let { inputUrl } = req;
669
+ if (inputUrl.startsWith('/')) {
670
+ this.cfg.logger.warn('Fetcher: url should not start with / when baseUrl is specified');
671
+ inputUrl = inputUrl.slice(1);
671
672
  }
672
- req.fullUrl = `${baseUrl}/${req.inputUrl}`;
673
+ req.fullUrl = `${baseUrl}/${inputUrl}`;
673
674
  }
674
675
  const searchParams = _filterUndefinedValues({
675
676
  ...this.cfg.searchParams,
@@ -263,6 +263,12 @@ export interface FetcherOptions {
263
263
  * Cannot cancel/prevent the error - AfterResponseHook can be used for that instead.
264
264
  */
265
265
  onError?: FetcherOnErrorHook;
266
+ /**
267
+ * If provided - will be passed further to HttpRequestError if error happens,
268
+ * allowing to construct an errorGroup/fingerprint to be able to group errors
269
+ * related to "this type of request".
270
+ */
271
+ requestName?: string;
266
272
  }
267
273
  export type RequestInitNormalized = Omit<RequestInit, 'method' | 'headers'> & {
268
274
  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.51.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": "20.12.12"
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 })
@@ -110,6 +120,11 @@ export interface HttpRequestErrorData extends ErrorData {
110
120
  * GET /some/url
111
121
  */
112
122
  requestSignature: string
123
+ /**
124
+ * FetcherOptions.requestName, if it was provided.
125
+ * Allows to construct errorGroup/fingerprint.
126
+ */
127
+ requestName?: string
113
128
  /**
114
129
  * Can be set to 0 if request "failed to start" or "failed to reach the server".
115
130
  */
@@ -333,6 +333,13 @@ export interface FetcherOptions {
333
333
  * Cannot cancel/prevent the error - AfterResponseHook can be used for that instead.
334
334
  */
335
335
  onError?: FetcherOnErrorHook
336
+
337
+ /**
338
+ * If provided - will be passed further to HttpRequestError if error happens,
339
+ * allowing to construct an errorGroup/fingerprint to be able to group errors
340
+ * related to "this type of request".
341
+ */
342
+ requestName?: string
336
343
  }
337
344
 
338
345
  export type RequestInitNormalized = Omit<RequestInit, 'method' | 'headers'> & {
@@ -551,6 +551,7 @@ export class Fetcher {
551
551
  requestBaseUrl: this.cfg.baseUrl || undefined,
552
552
  requestMethod: res.req.init.method,
553
553
  requestSignature: res.signature,
554
+ requestName: res.req.requestName,
554
555
  requestDuration: Date.now() - res.req.started,
555
556
  }),
556
557
  {
@@ -712,11 +713,12 @@ export class Fetcher {
712
713
  }
713
714
 
714
715
  private normalizeCfg(cfg: FetcherCfg & FetcherOptions): FetcherNormalizedCfg {
716
+ const { debug = false, logger = console } = cfg
717
+
715
718
  if (cfg.baseUrl?.endsWith('/')) {
716
- console.warn(`Fetcher: baseUrl should not end with slash: ${cfg.baseUrl}`)
719
+ logger.warn(`Fetcher: baseUrl should not end with slash: ${cfg.baseUrl}`)
717
720
  cfg.baseUrl = cfg.baseUrl.slice(0, cfg.baseUrl.length - 1)
718
721
  }
719
- const { debug = false } = cfg
720
722
 
721
723
  const norm: FetcherNormalizedCfg = _merge(
722
724
  {
@@ -729,8 +731,7 @@ export class Fetcher {
729
731
  retry3xx: false,
730
732
  retry4xx: false,
731
733
  retry5xx: true,
732
- // logger: console, Danger! doing this mutates console!
733
- logger: cfg.logger || console,
734
+ logger,
734
735
  debug,
735
736
  logRequest: debug,
736
737
  logRequestBody: debug,
@@ -809,11 +810,12 @@ export class Fetcher {
809
810
  // setup url
810
811
  const baseUrl = opt.baseUrl || this.cfg.baseUrl
811
812
  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)
813
+ let { inputUrl } = req
814
+ if (inputUrl.startsWith('/')) {
815
+ this.cfg.logger.warn('Fetcher: url should not start with / when baseUrl is specified')
816
+ inputUrl = inputUrl.slice(1)
815
817
  }
816
- req.fullUrl = `${baseUrl}/${req.inputUrl}`
818
+ req.fullUrl = `${baseUrl}/${inputUrl}`
817
819
  }
818
820
 
819
821
  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 {