From ab597f063b55419fa7e24df647876033e74c0be2 Mon Sep 17 00:00:00 2001 From: Ayoub Adib Date: Mon, 28 Mar 2022 19:00:53 +0200 Subject: [PATCH] feat: add key support on output --- example/withOutput.ts | 90 +++++++++++++++++++-------- src/api/output/index.ts | 35 +++++++---- src/termost.ts | 2 +- test/__snapshots__/index.test.ts.snap | 11 +++- test/index.test.ts | 2 +- 5 files changed, 100 insertions(+), 40 deletions(-) diff --git a/example/withOutput.ts b/example/withOutput.ts index eeade62..5bc833a 100644 --- a/example/withOutput.ts +++ b/example/withOutput.ts @@ -1,32 +1,70 @@ import { helpers, termost } from "../src"; -const program = termost("Example to showcase the `message` API"); +type ProgramContext = { + output: string; +}; -program.output({ - handler() { - const content = - "A content formatted thanks to the `print` helper presets."; +const program = termost( + "Example to showcase the `message` API" +); - helpers.print(content); - helpers.print(content, { type: "warning" }); - helpers.print(content, { type: "error" }); - helpers.print(content, { type: "success" }); - helpers.print(content, { - type: "information", - label: "👋 You can also customize the label", - }); - helpers.print(["I support also", "multilines", "with array input"], { - type: "information", - label: "👋 You can also customize the label", - }); - console.log( - helpers.format( - "\nYou can also have a total control on the formatting through the `format` helper.", +program + .output({ + handler() { + const content = + "A content formatted thanks to the `print` helper presets."; + + helpers.print(content); + helpers.print(content, { type: "warning" }); + helpers.print(content, { type: "error" }); + helpers.print(content, { type: "success" }); + helpers.print(content, { + type: "information", + label: "👋 You can also customize the label", + }); + helpers.print( + ["I support also", "multilines", "with array input"], { - color: "white", - modifier: ["italic", "strikethrough", "bold"], + type: "information", + label: "👋 You can also customize the label", } - ) - ); - }, -}); + ); + console.log( + helpers.format( + "\nYou can also have a total control on the formatting through the `format` helper.", + { + color: "white", + modifier: ["italic", "strikethrough", "bold"], + } + ) + ); + }, + }) + .output({ + key: "output", + handler() { + return "Hello from previous output"; + }, + }) + .output({ + handler(context) { + helpers.print( + `A shareable value can also be displayed: ${context.output}` + ); + }, + }) + .output({ + async handler() { + helpers.print( + "I can also run asynchronous operations... Operation is starting..." + ); + + await wait(2000); + + helpers.print("Operation is finished"); + }, + }); + +const wait = (delay: number) => { + return new Promise((resolve) => setTimeout(resolve, delay)); +}; diff --git a/src/api/output/index.ts b/src/api/output/index.ts index 9e1d705..f4db7ef 100644 --- a/src/api/output/index.ts +++ b/src/api/output/index.ts @@ -2,26 +2,39 @@ import { ArgumentValues, Context, CreateInstruction, + InstructionKey, InstructionParameters, ObjectLikeConstraint, } from "../../types"; export const createOutput: CreateInstruction< - OutputParameters + OutputParameters > = (parameters) => { - const { handler } = parameters; + const { handler, key } = parameters; return async function execute(context, argv) { - handler(context, argv); + const value = handler(context, argv); - return null; + return { key, value }; }; }; -export type OutputParameters = - InstructionParameters< - Values, - { - handler: (context: Context, argv: ArgumentValues) => void; - } - >; +export type OutputParameters< + Values extends ObjectLikeConstraint, + Key +> = InstructionParameters< + Values, + Key extends keyof Values + ? Partial> & { + handler: ( + context: Context, + argv: ArgumentValues + ) => Promise; + } + : { + handler: ( + context: Context, + argv: ArgumentValues + ) => void; + } +>; diff --git a/src/termost.ts b/src/termost.ts index 567f7a4..3a57ded 100644 --- a/src/termost.ts +++ b/src/termost.ts @@ -35,7 +35,7 @@ export type Termost = { params: InputParameters ): Termost; option(params: OptionParameters): Termost; - output(params: OutputParameters): Termost; + output(params: OutputParameters): Termost; task(params: TaskParameters): Termost; }; diff --git a/test/__snapshots__/index.test.ts.snap b/test/__snapshots__/index.test.ts.snap index e801332..819496e 100644 --- a/test/__snapshots__/index.test.ts.snap +++ b/test/__snapshots__/index.test.ts.snap @@ -157,7 +157,16 @@ exports[`termost should handle \`message\` api 1`] = `  multilines  with array input  -You can also have a total control on the formatting through the \`format\` helper." +You can also have a total control on the formatting through the \`format\` helper. + +ℹ️ Information + A shareable value can also be displayed: Hello from previous output + +ℹ️ Information + I can also run asynchronous operations... Operation is starting... + +ℹ️ Information + Operation is finished" `; exports[`termost should handle \`option\` api 1`] = ` diff --git a/test/index.test.ts b/test/index.test.ts index 16e7f65..262fe5a 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -49,7 +49,7 @@ describe("termost", () => { test("should handle `message` api", async () => { const output = await exec( - "node -r esbuild-register example/withMessage.ts" + "node -r esbuild-register example/withOutput.ts" ); expect(output).toMatchSnapshot();