@naturalcycles/js-lib 15.33.1 → 15.33.3

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.
@@ -283,7 +283,7 @@ export class Fetcher {
283
283
  }
284
284
  }
285
285
  try {
286
- res.fetchResponse = await Fetcher.callNativeFetch(req.fullUrl, req.init, this.cfg.fetchFn);
286
+ res.fetchResponse = await (this.cfg.overrideFetchFn || Fetcher.callNativeFetch)(req.fullUrl, req.init, this.cfg.fetchFn);
287
287
  res.ok = res.fetchResponse.ok;
288
288
  // important to set it to undefined, otherwise it can keep the previous value (from previous try)
289
289
  res.err = undefined;
@@ -399,8 +399,8 @@ export class Fetcher {
399
399
  * This method exists to be able to easily mock it.
400
400
  * It is static, so mocking applies to ALL instances (even future ones) of Fetcher at once.
401
401
  */
402
- static async callNativeFetch(url, init, fetchFn = globalThis.fetch) {
403
- return (await fetchFn(url, init));
402
+ static async callNativeFetch(url, init, fetchFn) {
403
+ return await (fetchFn || globalThis.fetch)(url, init);
404
404
  }
405
405
  async onNotOkResponse(res) {
406
406
  let cause;
@@ -227,9 +227,23 @@ export interface FetcherOptions {
227
227
  */
228
228
  debug?: boolean;
229
229
  /**
230
- * If provided - will be used instead of static `Fetcher.callNativeFetch`.
230
+ * If provided - will be used instead of `globalThis.fetch`.
231
+ * Can be used e.g to pass a `fetch` function from `undici` (in Node.js).
232
+ *
233
+ * This function IS called from `Fetcher.callNativeFetch`, so
234
+ * when `callNativeFetch` is mocked - fetchFn is NOT called.
231
235
  */
232
236
  fetchFn?: FetchFunction;
237
+ /**
238
+ * Allows to provide a fetch function that is NOT mocked by `Fetcher.callNativeFetch`.
239
+ *
240
+ * By default - consider `fetchFn`, that's what you would need most of the time.
241
+ *
242
+ * If you want to pass a fetch function that is NOT mockable - use `overrideFetchFn`.
243
+ * Example of where it is useful: in backend resourceTestService, which still needs to call
244
+ * native fetch, while allowing unit tests' fetch calls to be mocked.
245
+ */
246
+ overrideFetchFn?: FetchFunction;
233
247
  /**
234
248
  * Default to true.
235
249
  * Set to false to not throw on `!Response.ok`, but simply return `Response.body` as-is (json parsed, etc).
@@ -284,14 +298,14 @@ export type FetcherResponseType = 'json' | 'text' | 'void' | 'arrayBuffer' | 'bl
284
298
  * Used to be able to override and provide a different implementation,
285
299
  * e.g when mocking.
286
300
  */
287
- export type FetchFunction = (url: string, init: RequestInitCrossPlatform) => Promise<ResponseCrossPlatform>;
301
+ export type FetchFunction = (url: string, init: RequestInit) => Promise<Response>;
288
302
  /**
289
303
  * A subset of RequestInit that would match both:
290
304
  *
291
305
  * 1. RequestInit from dom types
292
306
  * 2. RequestInit from undici types
293
307
  */
294
- export interface RequestInitCrossPlatform {
308
+ export interface RequestInitLike {
295
309
  method?: string;
296
310
  referrer?: string;
297
311
  keepalive?: boolean;
@@ -299,7 +313,7 @@ export interface RequestInitCrossPlatform {
299
313
  /**
300
314
  * A subset of Response type that matches both dom and undici types.
301
315
  */
302
- export interface ResponseCrossPlatform {
316
+ export interface ResponseLike {
303
317
  ok: boolean;
304
318
  status: number;
305
319
  statusText: string;
@@ -5,6 +5,7 @@ type ZodBranded<T, B> = T & Record<'_zod', Record<'output', B>>;
5
5
  export type ZodBrandedString<B> = ZodBranded<z.ZodString, B>;
6
6
  export type ZodBrandedInt<B> = ZodBranded<z.ZodInt, B>;
7
7
  export type ZodBrandedNumber<B> = ZodBranded<z.ZodNumber, B>;
8
+ export type ZodBrandedIsoDate = ZodBranded<z.ZodISODate, IsoDate>;
8
9
  declare function unixTimestamp(): ZodBrandedInt<UnixTimestamp>;
9
10
  declare function unixTimestamp2000(): ZodBrandedInt<UnixTimestamp>;
10
11
  declare function unixTimestampMillis(): ZodBranded<z.ZodNumber, UnixTimestampMillis>;
@@ -42,9 +42,7 @@ function semVer() {
42
42
  function isoDate() {
43
43
  return z
44
44
  .string()
45
- .refine(v => {
46
- return /^\d{4}-\d{2}-\d{2}$/.test(v);
47
- }, 'Must be a YYYY-MM-DD string')
45
+ .regex(/^\d{4}-\d{2}-\d{2}$/, { error: 'Must be a YYYY-MM-DD string' })
48
46
  .describe('IsoDate');
49
47
  }
50
48
  function email() {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
3
  "type": "module",
4
- "version": "15.33.1",
4
+ "version": "15.33.3",
5
5
  "dependencies": {
6
6
  "tslib": "^2",
7
7
  "undici": "^7",
@@ -290,10 +290,25 @@ export interface FetcherOptions {
290
290
  debug?: boolean
291
291
 
292
292
  /**
293
- * If provided - will be used instead of static `Fetcher.callNativeFetch`.
293
+ * If provided - will be used instead of `globalThis.fetch`.
294
+ * Can be used e.g to pass a `fetch` function from `undici` (in Node.js).
295
+ *
296
+ * This function IS called from `Fetcher.callNativeFetch`, so
297
+ * when `callNativeFetch` is mocked - fetchFn is NOT called.
294
298
  */
295
299
  fetchFn?: FetchFunction
296
300
 
301
+ /**
302
+ * Allows to provide a fetch function that is NOT mocked by `Fetcher.callNativeFetch`.
303
+ *
304
+ * By default - consider `fetchFn`, that's what you would need most of the time.
305
+ *
306
+ * If you want to pass a fetch function that is NOT mockable - use `overrideFetchFn`.
307
+ * Example of where it is useful: in backend resourceTestService, which still needs to call
308
+ * native fetch, while allowing unit tests' fetch calls to be mocked.
309
+ */
310
+ overrideFetchFn?: FetchFunction
311
+
297
312
  /**
298
313
  * Default to true.
299
314
  * Set to false to not throw on `!Response.ok`, but simply return `Response.body` as-is (json parsed, etc).
@@ -364,10 +379,7 @@ export type FetcherResponseType =
364
379
  * Used to be able to override and provide a different implementation,
365
380
  * e.g when mocking.
366
381
  */
367
- export type FetchFunction = (
368
- url: string,
369
- init: RequestInitCrossPlatform,
370
- ) => Promise<ResponseCrossPlatform>
382
+ export type FetchFunction = (url: string, init: RequestInit) => Promise<Response>
371
383
 
372
384
  /**
373
385
  * A subset of RequestInit that would match both:
@@ -375,7 +387,7 @@ export type FetchFunction = (
375
387
  * 1. RequestInit from dom types
376
388
  * 2. RequestInit from undici types
377
389
  */
378
- export interface RequestInitCrossPlatform {
390
+ export interface RequestInitLike {
379
391
  method?: string
380
392
  referrer?: string
381
393
  keepalive?: boolean
@@ -384,7 +396,7 @@ export interface RequestInitCrossPlatform {
384
396
  /**
385
397
  * A subset of Response type that matches both dom and undici types.
386
398
  */
387
- export interface ResponseCrossPlatform {
399
+ export interface ResponseLike {
388
400
  ok: boolean
389
401
  status: number
390
402
  statusText: string
@@ -370,7 +370,11 @@ export class Fetcher {
370
370
  }
371
371
 
372
372
  try {
373
- res.fetchResponse = await Fetcher.callNativeFetch(req.fullUrl, req.init, this.cfg.fetchFn)
373
+ res.fetchResponse = await (this.cfg.overrideFetchFn || Fetcher.callNativeFetch)(
374
+ req.fullUrl,
375
+ req.init,
376
+ this.cfg.fetchFn,
377
+ )
374
378
  res.ok = res.fetchResponse.ok
375
379
  // important to set it to undefined, otherwise it can keep the previous value (from previous try)
376
380
  res.err = undefined
@@ -502,9 +506,9 @@ export class Fetcher {
502
506
  static async callNativeFetch(
503
507
  url: string,
504
508
  init: RequestInitNormalized,
505
- fetchFn: FetchFunction = globalThis.fetch,
509
+ fetchFn?: FetchFunction,
506
510
  ): Promise<Response> {
507
- return (await fetchFn(url, init)) as Response
511
+ return await (fetchFn || globalThis.fetch)(url, init)
508
512
  }
509
513
 
510
514
  private async onNotOkResponse(res: FetcherResponse): Promise<void> {
@@ -6,6 +6,7 @@ type ZodBranded<T, B> = T & Record<'_zod', Record<'output', B>>
6
6
  export type ZodBrandedString<B> = ZodBranded<z.ZodString, B>
7
7
  export type ZodBrandedInt<B> = ZodBranded<z.ZodInt, B>
8
8
  export type ZodBrandedNumber<B> = ZodBranded<z.ZodNumber, B>
9
+ export type ZodBrandedIsoDate = ZodBranded<z.ZodISODate, IsoDate>
9
10
 
10
11
  const TS_2500 = 16725225600 // 2500-01-01
11
12
  const TS_2000 = 946684800 // 2000-01-01
@@ -56,9 +57,7 @@ function semVer(): z.ZodString {
56
57
  function isoDate(): ZodBrandedString<IsoDate> {
57
58
  return z
58
59
  .string()
59
- .refine(v => {
60
- return /^\d{4}-\d{2}-\d{2}$/.test(v)
61
- }, 'Must be a YYYY-MM-DD string')
60
+ .regex(/^\d{4}-\d{2}-\d{2}$/, { error: 'Must be a YYYY-MM-DD string' })
62
61
  .describe('IsoDate') as ZodBrandedString<IsoDate>
63
62
  }
64
63