@fedify/cli 2.5.0-dev.2355 → 2.5.0-dev.2364

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/deno.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import "temporal-polyfill";
2
2
  //#region deno.json
3
- var version = "2.5.0-dev.2355+c92a1cb1";
3
+ var version = "2.5.0-dev.2364+4d9b5f4d";
4
4
  //#endregion
5
5
  export { version };
package/dist/lookup.js CHANGED
@@ -47,8 +47,8 @@ var RecursiveLookupError = class extends Error {
47
47
  target;
48
48
  /** Why the target could not be fetched, if known. */
49
49
  failure;
50
- constructor(target, failure) {
51
- super(`Failed to recursively fetch object: ${target}`);
50
+ constructor(target, failure, options) {
51
+ super(`Failed to recursively fetch object: ${target}`, options);
52
52
  this.name = "RecursiveLookupError";
53
53
  this.target = target;
54
54
  this.failure = failure;
@@ -235,9 +235,6 @@ function getLookupFailureHint(error, options = {}) {
235
235
  function shouldPrintLookupFailureHint(authLoader, hint) {
236
236
  return hint !== "authorized-fetch" || authLoader == null;
237
237
  }
238
- function shouldSuggestSuppressErrorsForLookupFailure(authLoader, hint) {
239
- return authLoader != null && hint === "authorized-fetch";
240
- }
241
238
  function printLookupFailureHint(authLoader, error, options = {}) {
242
239
  const hint = getLookupFailureHint(error, options);
243
240
  if (!shouldPrintLookupFailureHint(authLoader, hint)) return;
@@ -256,6 +253,97 @@ function printLookupFailureHint(authLoader, error, options = {}) {
256
253
  return;
257
254
  }
258
255
  }
256
+ function isSuppressibleRecursiveFailure(kind) {
257
+ switch (kind) {
258
+ case "timeout":
259
+ case "private-address":
260
+ case "not-found":
261
+ case "context":
262
+ case "fetch-or-parse": return true;
263
+ }
264
+ }
265
+ /**
266
+ * Classifies recursive follow-up failures and selects their existing hints.
267
+ * @param error The error from collecting a recursive chain.
268
+ * @param options The policies that affect hints, rather than loader behavior.
269
+ * @returns A failure that can be rendered without inspecting its error again.
270
+ */
271
+ function classifyRecursiveLookupFailure(error, options) {
272
+ const wrapped = error instanceof RecursiveLookupError ? error : void 0;
273
+ const failure = wrapped?.failure;
274
+ const recordedTimeout = failure?.error instanceof TimeoutError;
275
+ const presentation = wrapped != null && (wrapped.cause == null || recordedTimeout) ? "target" : "generic";
276
+ const underlyingError = presentation === "target" ? failure?.error : wrapped?.cause ?? error;
277
+ const timeout = underlyingError instanceof TimeoutError || recordedTimeout;
278
+ const privateContextUrl = presentation === "generic" || failure?.source === "context" ? getPrivateContextUrl(underlyingError) : null;
279
+ const blockedTarget = presentation === "target" && !options.allowPrivateAddress && wrapped != null && isPrivateAddressTarget(wrapped.target);
280
+ let hint = { type: "none" };
281
+ if (!timeout) if (presentation === "target") {
282
+ if (blockedTarget) hint = { type: "private-address" };
283
+ else if (privateContextUrl != null) hint = {
284
+ type: "private-context",
285
+ url: privateContextUrl
286
+ };
287
+ else if (failure != null) hint = {
288
+ type: "diagnostic",
289
+ message: describeLookupFailure(failure, options.authorizedFetch).message
290
+ };
291
+ else if (!options.authorizedFetch) hint = { type: "authorized-fetch" };
292
+ } else if (privateContextUrl != null) hint = {
293
+ type: "private-context",
294
+ url: privateContextUrl
295
+ };
296
+ else {
297
+ const legacyHint = getLookupFailureHint(underlyingError, { recursive: true });
298
+ hint = legacyHint === "authorized-fetch" ? { type: options.authorizedFetch ? "suppress-errors" : legacyHint } : { type: legacyHint === "dns" ? "dns" : "private-address" };
299
+ }
300
+ const kind = timeout ? "timeout" : privateContextUrl != null ? "context" : blockedTarget || !(underlyingError instanceof FetchError) && isPrivateAddressError(underlyingError) ? "private-address" : failure?.source === "context" ? "context" : presentation === "target" && failure == null ? "not-found" : "fetch-or-parse";
301
+ return {
302
+ target: wrapped?.target,
303
+ kind,
304
+ source: failure?.source,
305
+ suppressible: isSuppressibleRecursiveFailure(kind),
306
+ presentation,
307
+ error: presentation === "generic" ? underlyingError : error,
308
+ hint
309
+ };
310
+ }
311
+ /**
312
+ * Renders a classified recursive failure without reinterpreting its error.
313
+ * @param failure The classified follow-up failure.
314
+ * @param spinner The spinner that displays the failure headline.
315
+ * @param timeoutSeconds The requested timeout, in seconds.
316
+ * @internal
317
+ */
318
+ function printRecursiveLookupFailure(failure, spinner, timeoutSeconds) {
319
+ const target = failure.presentation === "target" ? failure.target : void 0;
320
+ if (failure.kind === "timeout") {
321
+ handleTimeoutError(spinner, timeoutSeconds, target);
322
+ return;
323
+ }
324
+ spinner.fail(target == null ? "Failed to recursively fetch object." : `Failed to recursively fetch object: ${colors.red(target)}.`);
325
+ switch (failure.hint.type) {
326
+ case "private-address":
327
+ printRecursivePrivateAddressHint();
328
+ return;
329
+ case "private-context":
330
+ printRecursivePrivateContextHint(failure.hint.url);
331
+ return;
332
+ case "dns":
333
+ printError(message`DNS lookup failed. Check the hostname and network connectivity.`);
334
+ return;
335
+ case "authorized-fetch":
336
+ printError(message`It may be a private object. Try with ${optionNames(["-a", "--authorized-fetch"])}.`);
337
+ return;
338
+ case "suppress-errors":
339
+ printError(message`Use the ${optionNames(["-S", "--suppress-errors"])} option to suppress partial errors.`);
340
+ return;
341
+ case "diagnostic":
342
+ printError(message`${text(failure.hint.message)}`);
343
+ return;
344
+ case "none": return;
345
+ }
346
+ }
259
347
  /**
260
348
  * Gets the next recursion target URL from an ActivityPub object.
261
349
  */
@@ -519,8 +607,7 @@ async function runLookup(command, deps = {}) {
519
607
  ...getPortableLookupProblem(target) === "no-gateway" ? gatewayOptions : {}
520
608
  });
521
609
  if (result.object != null) return result.object;
522
- if (result.thrownError != null && !(result.failure?.error instanceof TimeoutError)) throw result.thrownError;
523
- throw new RecursiveLookupError(target, result.failure);
610
+ throw new RecursiveLookupError(target, result.failure, result.thrownError == null ? void 0 : { cause: result.thrownError });
524
611
  }, {
525
612
  suppressErrors: command.suppressErrors,
526
613
  visited
@@ -536,28 +623,12 @@ async function runLookup(command, deps = {}) {
536
623
  await finalizeAndExit(1);
537
624
  return;
538
625
  }
539
- logger.error("Failed to recursively fetch an object in chain: {error}", { error });
540
- if (error instanceof TimeoutError) handleTimeoutError(spinner, command.timeout);
541
- else if (error instanceof RecursiveLookupError && error.failure?.error instanceof TimeoutError) handleTimeoutError(spinner, command.timeout, error.target);
542
- else if (error instanceof RecursiveLookupError) {
543
- spinner.fail(`Failed to recursively fetch object: ${colors.red(error.target)}.`);
544
- const privateContextUrl = error.failure?.source === "context" ? getPrivateContextUrl(error.failure.error) : null;
545
- if (!command.allowPrivateAddress && isPrivateAddressTarget(error.target)) printRecursivePrivateAddressHint();
546
- else if (privateContextUrl != null) printRecursivePrivateContextHint(privateContextUrl);
547
- else if (error.failure != null) printError(message`${text(describeLookupFailure(error.failure, authLoader != null).message)}`);
548
- else if (authLoader == null) printError(message`It may be a private object. Try with ${optionNames(["-a", "--authorized-fetch"])}.`);
549
- } else {
550
- spinner.fail("Failed to recursively fetch object.");
551
- const privateContextUrl = getPrivateContextUrl(error);
552
- if (privateContextUrl != null) {
553
- printRecursivePrivateContextHint(privateContextUrl);
554
- await finalizeAndExit(1);
555
- return;
556
- }
557
- const hint = getLookupFailureHint(error, { recursive: true });
558
- if (shouldSuggestSuppressErrorsForLookupFailure(authLoader, hint)) printError(message`Use the ${optionNames(["-S", "--suppress-errors"])} option to suppress partial errors.`);
559
- else printLookupFailureHint(authLoader, error, { recursive: true });
560
- }
626
+ const failure = classifyRecursiveLookupFailure(error, {
627
+ allowPrivateAddress: command.allowPrivateAddress,
628
+ authorizedFetch: authLoader != null
629
+ });
630
+ logger.error("Failed to recursively fetch an object in chain: {error}", { error: failure.error });
631
+ printRecursiveLookupFailure(failure, spinner, command.timeout);
561
632
  await finalizeAndExit(1);
562
633
  return;
563
634
  }
@@ -779,4 +850,4 @@ async function runLookup(command, deps = {}) {
779
850
  if (success && command.output) spinner.succeed(`Successfully wrote output to ${colors.green(command.output)}.`);
780
851
  }
781
852
  //#endregion
782
- export { RecursiveLookupError, TimeoutError, collectAsyncItems, collectRecursiveObjects, getLookupFailureHint, getPrivateUrlCandidate, getRecursiveTargetId, getVisitedKey, isDocumentLoaderTimeoutError, runLookup, shouldPrintLookupFailureHint, shouldSuggestSuppressErrorsForLookupFailure, toDocumentLoaderTimeout, toPresentationOrder, wrapDocumentLoaderWithTimeout, writeObjectToStream, writeSeparator };
853
+ export { RecursiveLookupError, TimeoutError, classifyRecursiveLookupFailure, collectAsyncItems, collectRecursiveObjects, getLookupFailureHint, getPrivateUrlCandidate, getRecursiveTargetId, getVisitedKey, isDocumentLoaderTimeoutError, printRecursiveLookupFailure, runLookup, shouldPrintLookupFailureHint, toDocumentLoaderTimeout, toPresentationOrder, wrapDocumentLoaderWithTimeout, writeObjectToStream, writeSeparator };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/cli",
3
- "version": "2.5.0-dev.2355+c92a1cb1",
3
+ "version": "2.5.0-dev.2364+4d9b5f4d",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "README.md",
@@ -88,14 +88,14 @@
88
88
  "temporal-polyfill": "^1.0.1",
89
89
  "valibot": "^1.4.0",
90
90
  "yaml": "^2.9.0",
91
- "@fedify/fedify": "2.5.0-dev.2355+c92a1cb1",
92
- "@fedify/init": "2.5.0-dev.2355+c92a1cb1",
93
- "@fedify/relay": "2.5.0-dev.2355+c92a1cb1",
94
- "@fedify/vocab": "2.5.0-dev.2355+c92a1cb1",
95
- "@fedify/webfinger": "2.5.0-dev.2355+c92a1cb1",
96
- "@fedify/sqlite": "2.5.0-dev.2355+c92a1cb1",
97
- "@fedify/vocab-runtime": "2.5.0-dev.2355+c92a1cb1",
98
- "@fedify/vocab-tools": "2.5.0-dev.2355+c92a1cb1"
91
+ "@fedify/init": "2.5.0-dev.2364+4d9b5f4d",
92
+ "@fedify/fedify": "2.5.0-dev.2364+4d9b5f4d",
93
+ "@fedify/relay": "2.5.0-dev.2364+4d9b5f4d",
94
+ "@fedify/vocab-runtime": "2.5.0-dev.2364+4d9b5f4d",
95
+ "@fedify/vocab": "2.5.0-dev.2364+4d9b5f4d",
96
+ "@fedify/sqlite": "2.5.0-dev.2364+4d9b5f4d",
97
+ "@fedify/vocab-tools": "2.5.0-dev.2364+4d9b5f4d",
98
+ "@fedify/webfinger": "2.5.0-dev.2364+4d9b5f4d"
99
99
  },
100
100
  "devDependencies": {
101
101
  "@types/bun": "^1.2.23",