Loading cli/lookup.ts +107 −79 Original line number Diff line number Diff line Loading @@ -25,6 +25,106 @@ const logger = getLogger(["fedify", "cli", "lookup"]); const sigSpec = new EnumType(["draft-cavage-http-signatures-12", "rfc9421"]); interface CommandOptions { authorizedFetch?: boolean; firstKnock: "draft-cavage-http-signatures-12" | "rfc9421"; traverse?: boolean; suppressErrors?: boolean; raw?: boolean; compact?: boolean; expand?: boolean; userAgent?: string; separator: string; output?: string; } export async function createFileStream( outputPath: string, ): Promise<WritableStream> { try { const filepath = isAbsolute(outputPath) ? outputPath : resolve(Deno.env.get("PWD") || Deno.cwd(), outputPath); const parentDir = dirname(filepath); await Deno.mkdir(parentDir, { recursive: true }); const file = await Deno.open(filepath, { write: true, create: true, truncate: true, }); return new WritableStream({ write: (chunk) => file.write(chunk).then(() => {}), close: () => file.close(), abort: (reason) => { file.close(); throw reason; }, }); } catch (err) { const spinner = ora({ text: `Failed to write output to ${colors.red(outputPath)}.`, discardStdin: false, }); spinner.fail(); console.error(`Error: ${String(err)}`); if (err instanceof Deno.errors.PermissionDenied) { console.error( "Permission denied. Try running with proper permissions.", ); } else if (err instanceof Deno.errors.NotFound) { console.error("Path does not exist or is invalid."); } else if (err instanceof Deno.errors.IsADirectory) { console.error("The specified path is a directory, not a file."); } Deno.exit(1); } } export async function writeObjectToStream( object: Object | Link, options: CommandOptions, contextLoader: DocumentLoader, ): Promise<void> { const stream = options.output ? await createFileStream(options.output) : Deno.stdout.writable; const writer = stream.getWriter(); try { let content; if (options.raw) { content = await object.toJsonLd({ contextLoader }); } else if (options.compact) { content = await object.toJsonLd({ format: "compact", contextLoader }); } else if (options.expand) { content = await object.toJsonLd({ format: "expand", contextLoader }); } else { content = object; } content = util.inspect(content, { depth: null, colors: !(options.output), }); const encoder = new TextEncoder(); const bytes = encoder.encode(content + "\n"); await writer.write(bytes); } finally { writer.releaseLock(); if (options.output) { await stream.close(); } } } export const command = new Command() .type("sig-spec", sigSpec) .arguments("<...urls:string>") Loading Loading @@ -154,83 +254,6 @@ export const command = new Command() options.traverse ? "collection" : urls.length > 1 ? "objects" : "object" }...`; async function writeObjectToStream( object: Object | Link, ): Promise<void> { const stream = options.output ? await createFileStream(options.output) : Deno.stdout.writable; const writer = stream.getWriter(); try { let content; if (options.raw) { content = await object.toJsonLd({ contextLoader }); } else if (options.compact) { content = await object.toJsonLd({ format: "compact", contextLoader }); } else if (options.expand) { content = await object.toJsonLd({ format: "expand", contextLoader }); } else { content = object; } content = util.inspect(content, { depth: null, colors: !(stream instanceof WritableStream), }); const encoder = new TextEncoder(); const bytes = encoder.encode(content + "\n"); await writer.write(bytes); } finally { writer.releaseLock(); } } async function createFileStream( outputPath: string, ): Promise<WritableStream> { try { const filepath = isAbsolute(outputPath) ? outputPath : resolve(Deno.env.get("PWD") || Deno.cwd(), outputPath); spinner.start(`Writing output to ${colors.green(filepath)}...`); const parentDir = dirname(filepath); await Deno.mkdir(parentDir, { recursive: true }); const file = await Deno.open(filepath, { write: true, create: true, truncate: true, }); return new WritableStream({ write: (chunk) => file.write(chunk).then(() => {}), close: () => file.close(), abort: (reason) => { file.close(); throw reason; }, }); } catch (err) { spinner.fail(`Failed to write output.`); console.error(`Error: ${String(err)}`); if (err instanceof Deno.errors.PermissionDenied) { console.error( "Permission denied. Try running with proper permissions.", ); } else if (err instanceof Deno.errors.NotFound) { console.error("Path does not exist or is invalid."); } else if (err instanceof Deno.errors.IsADirectory) { console.error("The specified path is a directory, not a file."); } Deno.exit(1); } } if (options.traverse) { const url = urls[0]; const collection = await lookupObject(url, { Loading Loading @@ -267,7 +290,7 @@ export const command = new Command() }) ) { if (!options.output && i > 0) console.log(options.separator); await writeObjectToStream(item); await writeObjectToStream(item, options, contextLoader); i++; } } catch (error) { Loading Loading @@ -323,7 +346,7 @@ export const command = new Command() success = false; } else { spinner.succeed(`Fetched object: ${colors.green(url)}.`); await writeObjectToStream(object); await writeObjectToStream(object, options, contextLoader); if (i < urls.length - 1) { console.log(options.separator); } Loading @@ -343,6 +366,11 @@ export const command = new Command() if (!success) { Deno.exit(1); } if (success && options.output) { spinner.succeed( `Successfully wrote output to ${colors.green(options.output)}.`, ); } }); // cSpell: ignore sigspec Loading
cli/lookup.ts +107 −79 Original line number Diff line number Diff line Loading @@ -25,6 +25,106 @@ const logger = getLogger(["fedify", "cli", "lookup"]); const sigSpec = new EnumType(["draft-cavage-http-signatures-12", "rfc9421"]); interface CommandOptions { authorizedFetch?: boolean; firstKnock: "draft-cavage-http-signatures-12" | "rfc9421"; traverse?: boolean; suppressErrors?: boolean; raw?: boolean; compact?: boolean; expand?: boolean; userAgent?: string; separator: string; output?: string; } export async function createFileStream( outputPath: string, ): Promise<WritableStream> { try { const filepath = isAbsolute(outputPath) ? outputPath : resolve(Deno.env.get("PWD") || Deno.cwd(), outputPath); const parentDir = dirname(filepath); await Deno.mkdir(parentDir, { recursive: true }); const file = await Deno.open(filepath, { write: true, create: true, truncate: true, }); return new WritableStream({ write: (chunk) => file.write(chunk).then(() => {}), close: () => file.close(), abort: (reason) => { file.close(); throw reason; }, }); } catch (err) { const spinner = ora({ text: `Failed to write output to ${colors.red(outputPath)}.`, discardStdin: false, }); spinner.fail(); console.error(`Error: ${String(err)}`); if (err instanceof Deno.errors.PermissionDenied) { console.error( "Permission denied. Try running with proper permissions.", ); } else if (err instanceof Deno.errors.NotFound) { console.error("Path does not exist or is invalid."); } else if (err instanceof Deno.errors.IsADirectory) { console.error("The specified path is a directory, not a file."); } Deno.exit(1); } } export async function writeObjectToStream( object: Object | Link, options: CommandOptions, contextLoader: DocumentLoader, ): Promise<void> { const stream = options.output ? await createFileStream(options.output) : Deno.stdout.writable; const writer = stream.getWriter(); try { let content; if (options.raw) { content = await object.toJsonLd({ contextLoader }); } else if (options.compact) { content = await object.toJsonLd({ format: "compact", contextLoader }); } else if (options.expand) { content = await object.toJsonLd({ format: "expand", contextLoader }); } else { content = object; } content = util.inspect(content, { depth: null, colors: !(options.output), }); const encoder = new TextEncoder(); const bytes = encoder.encode(content + "\n"); await writer.write(bytes); } finally { writer.releaseLock(); if (options.output) { await stream.close(); } } } export const command = new Command() .type("sig-spec", sigSpec) .arguments("<...urls:string>") Loading Loading @@ -154,83 +254,6 @@ export const command = new Command() options.traverse ? "collection" : urls.length > 1 ? "objects" : "object" }...`; async function writeObjectToStream( object: Object | Link, ): Promise<void> { const stream = options.output ? await createFileStream(options.output) : Deno.stdout.writable; const writer = stream.getWriter(); try { let content; if (options.raw) { content = await object.toJsonLd({ contextLoader }); } else if (options.compact) { content = await object.toJsonLd({ format: "compact", contextLoader }); } else if (options.expand) { content = await object.toJsonLd({ format: "expand", contextLoader }); } else { content = object; } content = util.inspect(content, { depth: null, colors: !(stream instanceof WritableStream), }); const encoder = new TextEncoder(); const bytes = encoder.encode(content + "\n"); await writer.write(bytes); } finally { writer.releaseLock(); } } async function createFileStream( outputPath: string, ): Promise<WritableStream> { try { const filepath = isAbsolute(outputPath) ? outputPath : resolve(Deno.env.get("PWD") || Deno.cwd(), outputPath); spinner.start(`Writing output to ${colors.green(filepath)}...`); const parentDir = dirname(filepath); await Deno.mkdir(parentDir, { recursive: true }); const file = await Deno.open(filepath, { write: true, create: true, truncate: true, }); return new WritableStream({ write: (chunk) => file.write(chunk).then(() => {}), close: () => file.close(), abort: (reason) => { file.close(); throw reason; }, }); } catch (err) { spinner.fail(`Failed to write output.`); console.error(`Error: ${String(err)}`); if (err instanceof Deno.errors.PermissionDenied) { console.error( "Permission denied. Try running with proper permissions.", ); } else if (err instanceof Deno.errors.NotFound) { console.error("Path does not exist or is invalid."); } else if (err instanceof Deno.errors.IsADirectory) { console.error("The specified path is a directory, not a file."); } Deno.exit(1); } } if (options.traverse) { const url = urls[0]; const collection = await lookupObject(url, { Loading Loading @@ -267,7 +290,7 @@ export const command = new Command() }) ) { if (!options.output && i > 0) console.log(options.separator); await writeObjectToStream(item); await writeObjectToStream(item, options, contextLoader); i++; } } catch (error) { Loading Loading @@ -323,7 +346,7 @@ export const command = new Command() success = false; } else { spinner.succeed(`Fetched object: ${colors.green(url)}.`); await writeObjectToStream(object); await writeObjectToStream(object, options, contextLoader); if (i < urls.length - 1) { console.log(options.separator); } Loading @@ -343,6 +366,11 @@ export const command = new Command() if (!success) { Deno.exit(1); } if (success && options.output) { spinner.succeed( `Successfully wrote output to ${colors.green(options.output)}.`, ); } }); // cSpell: ignore sigspec