fast-npm-meta 1.4.1 → 1.5.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.
package/dist/cli.mjs CHANGED
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  import process$1 from "node:process";
3
-
4
3
  //#region ../node_modules/.pnpm/cac@7.0.0/node_modules/cac/dist/index.js
5
4
  function toArr(any) {
6
5
  return any == null ? [] : Array.isArray(any) ? any : [any];
@@ -618,11 +617,9 @@ var CAC = class extends EventTarget {
618
617
  * @param name The program name to display in help and version message
619
618
  */
620
619
  const cac = (name = "") => new CAC(name);
621
-
622
620
  //#endregion
623
621
  //#region package.json
624
- var version = "1.4.1";
625
-
622
+ var version = "1.5.0";
626
623
  //#endregion
627
624
  //#region ../node_modules/.pnpm/is-network-error@1.3.0/node_modules/is-network-error/index.js
628
625
  const objectToString = Object.prototype.toString;
@@ -645,9 +642,8 @@ function isNetworkError(error) {
645
642
  if (message.startsWith("error sending request for url")) return true;
646
643
  return errorMessages.has(message);
647
644
  }
648
-
649
645
  //#endregion
650
- //#region ../node_modules/.pnpm/p-retry@7.1.1/node_modules/p-retry/index.js
646
+ //#region ../node_modules/.pnpm/p-retry@8.0.0/node_modules/p-retry/index.js
651
647
  function validateRetries(retries) {
652
648
  if (typeof retries === "number") {
653
649
  if (retries < 0) throw new TypeError("Expected `retries` to be a non-negative number.");
@@ -660,6 +656,10 @@ function validateNumberOption(name, value, { min = 0, allowInfinity = false } =
660
656
  if (!allowInfinity && !Number.isFinite(value)) throw new TypeError(`Expected \`${name}\` to be a finite number.`);
661
657
  if (value < min) throw new TypeError(`Expected \`${name}\` to be \u2265 ${min}.`);
662
658
  }
659
+ function validateFunctionOption(name, value) {
660
+ if (value === void 0) return;
661
+ if (typeof value !== "function") throw new TypeError(`Expected \`${name}\` to be a function.`);
662
+ }
663
663
  var AbortError = class extends Error {
664
664
  constructor(message) {
665
665
  super();
@@ -685,48 +685,69 @@ function calculateRemainingTime(start, max) {
685
685
  if (!Number.isFinite(max)) return max;
686
686
  return max - (performance.now() - start);
687
687
  }
688
+ async function delayForRetry(delay, options) {
689
+ if (delay <= 0) return;
690
+ await new Promise((resolve, reject) => {
691
+ const onAbort = () => {
692
+ clearTimeout(timeoutToken);
693
+ options.signal?.removeEventListener("abort", onAbort);
694
+ reject(options.signal.reason);
695
+ };
696
+ const timeoutToken = setTimeout(() => {
697
+ options.signal?.removeEventListener("abort", onAbort);
698
+ resolve();
699
+ }, delay);
700
+ if (options.unref) timeoutToken.unref?.();
701
+ options.signal?.addEventListener("abort", onAbort, { once: true });
702
+ });
703
+ }
688
704
  async function onAttemptFailure({ error, attemptNumber, retriesConsumed, startTime, options }) {
689
705
  const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new TypeError(`Non-error was thrown: "${error}". You should only throw errors.`);
690
706
  if (normalizedError instanceof AbortError) throw normalizedError.originalError;
691
707
  const retriesLeft = Number.isFinite(options.retries) ? Math.max(0, options.retries - retriesConsumed) : options.retries;
692
708
  const maxRetryTime = options.maxRetryTime ?? Number.POSITIVE_INFINITY;
709
+ const delayTime = calculateDelay(retriesConsumed, options);
710
+ if (calculateRemainingTime(startTime, maxRetryTime) <= 0) {
711
+ const context = Object.freeze({
712
+ error: normalizedError,
713
+ attemptNumber,
714
+ retriesLeft,
715
+ retriesConsumed,
716
+ retryDelay: 0
717
+ });
718
+ await options.onFailedAttempt(context);
719
+ throw normalizedError;
720
+ }
721
+ const consumeRetryContext = Object.freeze({
722
+ error: normalizedError,
723
+ attemptNumber,
724
+ retriesLeft,
725
+ retriesConsumed,
726
+ retryDelay: retriesLeft > 0 ? delayTime : 0
727
+ });
728
+ const consumeRetry = await options.shouldConsumeRetry(consumeRetryContext);
729
+ const effectiveDelay = consumeRetry && retriesLeft > 0 ? delayTime : 0;
693
730
  const context = Object.freeze({
694
731
  error: normalizedError,
695
732
  attemptNumber,
696
733
  retriesLeft,
697
- retriesConsumed
734
+ retriesConsumed,
735
+ retryDelay: effectiveDelay
698
736
  });
699
737
  await options.onFailedAttempt(context);
700
738
  if (calculateRemainingTime(startTime, maxRetryTime) <= 0) throw normalizedError;
701
- const consumeRetry = await options.shouldConsumeRetry(context);
702
- const remainingTime = calculateRemainingTime(startTime, maxRetryTime);
703
- if (remainingTime <= 0 || retriesLeft <= 0) throw normalizedError;
704
- if (normalizedError instanceof TypeError && !isNetworkError(normalizedError)) {
705
- if (consumeRetry) throw normalizedError;
706
- options.signal?.throwIfAborted();
707
- return false;
708
- }
739
+ if (calculateRemainingTime(startTime, maxRetryTime) <= 0 || retriesLeft <= 0) throw normalizedError;
740
+ if (normalizedError instanceof TypeError && !isNetworkError(normalizedError)) throw normalizedError;
709
741
  if (!await options.shouldRetry(context)) throw normalizedError;
742
+ const remainingTimeAfterShouldRetry = calculateRemainingTime(startTime, maxRetryTime);
743
+ if (remainingTimeAfterShouldRetry <= 0) throw normalizedError;
710
744
  if (!consumeRetry) {
711
745
  options.signal?.throwIfAborted();
712
746
  return false;
713
747
  }
714
- const delayTime = calculateDelay(retriesConsumed, options);
715
- const finalDelay = Math.min(delayTime, remainingTime);
748
+ const finalDelay = Math.min(effectiveDelay, remainingTimeAfterShouldRetry);
716
749
  options.signal?.throwIfAborted();
717
- if (finalDelay > 0) await new Promise((resolve, reject) => {
718
- const onAbort = () => {
719
- clearTimeout(timeoutToken);
720
- options.signal?.removeEventListener("abort", onAbort);
721
- reject(options.signal.reason);
722
- };
723
- const timeoutToken = setTimeout(() => {
724
- options.signal?.removeEventListener("abort", onAbort);
725
- resolve();
726
- }, finalDelay);
727
- if (options.unref) timeoutToken.unref?.();
728
- options.signal?.addEventListener("abort", onAbort, { once: true });
729
- });
750
+ await delayForRetry(finalDelay, options);
730
751
  options.signal?.throwIfAborted();
731
752
  return true;
732
753
  }
@@ -743,6 +764,9 @@ async function pRetry(input, options = {}) {
743
764
  options.onFailedAttempt ??= () => {};
744
765
  options.shouldRetry ??= () => true;
745
766
  options.shouldConsumeRetry ??= () => true;
767
+ validateFunctionOption("onFailedAttempt", options.onFailedAttempt);
768
+ validateFunctionOption("shouldRetry", options.shouldRetry);
769
+ validateFunctionOption("shouldConsumeRetry", options.shouldConsumeRetry);
746
770
  validateNumberOption("factor", options.factor, {
747
771
  min: 0,
748
772
  allowInfinity: false
@@ -783,7 +807,6 @@ async function pRetry(input, options = {}) {
783
807
  }
784
808
  throw new Error("Retry attempts exhausted without throwing an error.");
785
809
  }
786
-
787
810
  //#endregion
788
811
  //#region src/api.ts
789
812
  const defaultRetryOptions = {
@@ -835,7 +858,6 @@ function toArray(data) {
835
858
  if (Array.isArray(data)) return data;
836
859
  return [data];
837
860
  }
838
-
839
861
  //#endregion
840
862
  //#region src/cli.ts
841
863
  const cli = cac("fast-npm-meta");
@@ -874,6 +896,5 @@ cli.command("full <...pkgs>", "Get full package metadata (versions list, dist-ta
874
896
  cli.help();
875
897
  cli.version(version);
876
898
  cli.parse();
877
-
878
899
  //#endregion
879
- export { };
900
+ export {};
package/dist/index.mjs CHANGED
@@ -19,9 +19,8 @@ function isNetworkError(error) {
19
19
  if (message.startsWith("error sending request for url")) return true;
20
20
  return errorMessages.has(message);
21
21
  }
22
-
23
22
  //#endregion
24
- //#region ../node_modules/.pnpm/p-retry@7.1.1/node_modules/p-retry/index.js
23
+ //#region ../node_modules/.pnpm/p-retry@8.0.0/node_modules/p-retry/index.js
25
24
  function validateRetries(retries) {
26
25
  if (typeof retries === "number") {
27
26
  if (retries < 0) throw new TypeError("Expected `retries` to be a non-negative number.");
@@ -34,6 +33,10 @@ function validateNumberOption(name, value, { min = 0, allowInfinity = false } =
34
33
  if (!allowInfinity && !Number.isFinite(value)) throw new TypeError(`Expected \`${name}\` to be a finite number.`);
35
34
  if (value < min) throw new TypeError(`Expected \`${name}\` to be \u2265 ${min}.`);
36
35
  }
36
+ function validateFunctionOption(name, value) {
37
+ if (value === void 0) return;
38
+ if (typeof value !== "function") throw new TypeError(`Expected \`${name}\` to be a function.`);
39
+ }
37
40
  var AbortError = class extends Error {
38
41
  constructor(message) {
39
42
  super();
@@ -59,48 +62,69 @@ function calculateRemainingTime(start, max) {
59
62
  if (!Number.isFinite(max)) return max;
60
63
  return max - (performance.now() - start);
61
64
  }
65
+ async function delayForRetry(delay, options) {
66
+ if (delay <= 0) return;
67
+ await new Promise((resolve, reject) => {
68
+ const onAbort = () => {
69
+ clearTimeout(timeoutToken);
70
+ options.signal?.removeEventListener("abort", onAbort);
71
+ reject(options.signal.reason);
72
+ };
73
+ const timeoutToken = setTimeout(() => {
74
+ options.signal?.removeEventListener("abort", onAbort);
75
+ resolve();
76
+ }, delay);
77
+ if (options.unref) timeoutToken.unref?.();
78
+ options.signal?.addEventListener("abort", onAbort, { once: true });
79
+ });
80
+ }
62
81
  async function onAttemptFailure({ error, attemptNumber, retriesConsumed, startTime, options }) {
63
82
  const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new TypeError(`Non-error was thrown: "${error}". You should only throw errors.`);
64
83
  if (normalizedError instanceof AbortError) throw normalizedError.originalError;
65
84
  const retriesLeft = Number.isFinite(options.retries) ? Math.max(0, options.retries - retriesConsumed) : options.retries;
66
85
  const maxRetryTime = options.maxRetryTime ?? Number.POSITIVE_INFINITY;
86
+ const delayTime = calculateDelay(retriesConsumed, options);
87
+ if (calculateRemainingTime(startTime, maxRetryTime) <= 0) {
88
+ const context = Object.freeze({
89
+ error: normalizedError,
90
+ attemptNumber,
91
+ retriesLeft,
92
+ retriesConsumed,
93
+ retryDelay: 0
94
+ });
95
+ await options.onFailedAttempt(context);
96
+ throw normalizedError;
97
+ }
98
+ const consumeRetryContext = Object.freeze({
99
+ error: normalizedError,
100
+ attemptNumber,
101
+ retriesLeft,
102
+ retriesConsumed,
103
+ retryDelay: retriesLeft > 0 ? delayTime : 0
104
+ });
105
+ const consumeRetry = await options.shouldConsumeRetry(consumeRetryContext);
106
+ const effectiveDelay = consumeRetry && retriesLeft > 0 ? delayTime : 0;
67
107
  const context = Object.freeze({
68
108
  error: normalizedError,
69
109
  attemptNumber,
70
110
  retriesLeft,
71
- retriesConsumed
111
+ retriesConsumed,
112
+ retryDelay: effectiveDelay
72
113
  });
73
114
  await options.onFailedAttempt(context);
74
115
  if (calculateRemainingTime(startTime, maxRetryTime) <= 0) throw normalizedError;
75
- const consumeRetry = await options.shouldConsumeRetry(context);
76
- const remainingTime = calculateRemainingTime(startTime, maxRetryTime);
77
- if (remainingTime <= 0 || retriesLeft <= 0) throw normalizedError;
78
- if (normalizedError instanceof TypeError && !isNetworkError(normalizedError)) {
79
- if (consumeRetry) throw normalizedError;
80
- options.signal?.throwIfAborted();
81
- return false;
82
- }
116
+ if (calculateRemainingTime(startTime, maxRetryTime) <= 0 || retriesLeft <= 0) throw normalizedError;
117
+ if (normalizedError instanceof TypeError && !isNetworkError(normalizedError)) throw normalizedError;
83
118
  if (!await options.shouldRetry(context)) throw normalizedError;
119
+ const remainingTimeAfterShouldRetry = calculateRemainingTime(startTime, maxRetryTime);
120
+ if (remainingTimeAfterShouldRetry <= 0) throw normalizedError;
84
121
  if (!consumeRetry) {
85
122
  options.signal?.throwIfAborted();
86
123
  return false;
87
124
  }
88
- const delayTime = calculateDelay(retriesConsumed, options);
89
- const finalDelay = Math.min(delayTime, remainingTime);
125
+ const finalDelay = Math.min(effectiveDelay, remainingTimeAfterShouldRetry);
90
126
  options.signal?.throwIfAborted();
91
- if (finalDelay > 0) await new Promise((resolve, reject) => {
92
- const onAbort = () => {
93
- clearTimeout(timeoutToken);
94
- options.signal?.removeEventListener("abort", onAbort);
95
- reject(options.signal.reason);
96
- };
97
- const timeoutToken = setTimeout(() => {
98
- options.signal?.removeEventListener("abort", onAbort);
99
- resolve();
100
- }, finalDelay);
101
- if (options.unref) timeoutToken.unref?.();
102
- options.signal?.addEventListener("abort", onAbort, { once: true });
103
- });
127
+ await delayForRetry(finalDelay, options);
104
128
  options.signal?.throwIfAborted();
105
129
  return true;
106
130
  }
@@ -117,6 +141,9 @@ async function pRetry(input, options = {}) {
117
141
  options.onFailedAttempt ??= () => {};
118
142
  options.shouldRetry ??= () => true;
119
143
  options.shouldConsumeRetry ??= () => true;
144
+ validateFunctionOption("onFailedAttempt", options.onFailedAttempt);
145
+ validateFunctionOption("shouldRetry", options.shouldRetry);
146
+ validateFunctionOption("shouldConsumeRetry", options.shouldConsumeRetry);
120
147
  validateNumberOption("factor", options.factor, {
121
148
  min: 0,
122
149
  allowInfinity: false
@@ -157,7 +184,6 @@ async function pRetry(input, options = {}) {
157
184
  }
158
185
  throw new Error("Retry attempts exhausted without throwing an error.");
159
186
  }
160
-
161
187
  //#endregion
162
188
  //#region src/api.ts
163
189
  const defaultRetryOptions = {
@@ -217,7 +243,6 @@ function toArray(data) {
217
243
  if (Array.isArray(data)) return data;
218
244
  return [data];
219
245
  }
220
-
221
246
  //#endregion
222
247
  //#region src/helpers.ts
223
248
  const NPM_REGISTRY = "https://registry.npmjs.org/";
@@ -234,6 +259,5 @@ function pickRegistry(scope, npmConfigs, defaultRegistry = NPM_REGISTRY) {
234
259
  if (!registry) registry = npmConfigs.registry || defaultRegistry;
235
260
  return registry;
236
261
  }
237
-
238
262
  //#endregion
239
- export { NPM_REGISTRY, defaultOptions, getLatestVersion, getLatestVersionBatch, getVersions, getVersionsBatch, pickRegistry };
263
+ export { NPM_REGISTRY, defaultOptions, getLatestVersion, getLatestVersionBatch, getVersions, getVersionsBatch, pickRegistry };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "fast-npm-meta",
3
3
  "type": "module",
4
- "version": "1.4.1",
4
+ "version": "1.5.0",
5
5
  "description": "Get npm package metadata",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -28,8 +28,13 @@
28
28
  ],
29
29
  "devDependencies": {
30
30
  "cac": "^7.0.0",
31
- "p-retry": "^7.1.1",
32
- "tsdown": "^0.20.3"
31
+ "p-retry": "^8.0.0",
32
+ "tsdown": "^0.21.7"
33
+ },
34
+ "inlinedDependencies": {
35
+ "cac": "7.0.0",
36
+ "is-network-error": "1.3.0",
37
+ "p-retry": "8.0.0"
33
38
  },
34
39
  "scripts": {
35
40
  "build": "tsdown",