@shopify/cli-kit 3.30.2 → 3.31.1
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/environment/fqdn.d.ts +6 -0
- package/dist/environment/fqdn.js +13 -2
- package/dist/environment/fqdn.js.map +1 -1
- package/dist/file.js +2 -2
- package/dist/file.js.map +1 -1
- package/dist/path.d.ts +2 -4
- package/dist/path.js +4 -5
- package/dist/path.js.map +1 -1
- package/dist/private/node/ui/components/Alert.test.js +3 -3
- package/dist/private/node/ui/components/Alert.test.js.map +1 -1
- package/dist/private/node/ui/components/Banner.js +5 -21
- package/dist/private/node/ui/components/Banner.js.map +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.d.ts +0 -1
- package/dist/private/node/ui/components/ConcurrentOutput.js +6 -16
- package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.test.js +3 -2
- package/dist/private/node/ui/components/ConcurrentOutput.test.js.map +1 -1
- package/dist/private/node/ui/components/FatalError.js +2 -2
- package/dist/private/node/ui/components/FatalError.js.map +1 -1
- package/dist/private/node/ui/components/FatalError.test.js +10 -10
- package/dist/private/node/ui/components/FatalError.test.js.map +1 -1
- package/dist/private/node/ui/components/Link.js +1 -1
- package/dist/private/node/ui/components/Link.js.map +1 -1
- package/dist/private/node/ui/components/Link.test.js +1 -1
- package/dist/private/node/ui/components/Link.test.js.map +1 -1
- package/dist/private/node/ui/components/Prompt.js +1 -1
- package/dist/private/node/ui/components/Prompt.js.map +1 -1
- package/dist/private/node/ui/components/Prompt.test.js +4 -2
- package/dist/private/node/ui/components/Prompt.test.js.map +1 -1
- package/dist/private/node/ui/components/Tasks.d.ts +10 -0
- package/dist/private/node/ui/components/Tasks.js +27 -0
- package/dist/private/node/ui/components/Tasks.js.map +1 -0
- package/dist/private/node/ui/components/Tasks.test.d.ts +1 -0
- package/dist/private/node/ui/components/Tasks.test.js +50 -0
- package/dist/private/node/ui/components/Tasks.test.js.map +1 -0
- package/dist/private/node/ui/components/TextAnimation.d.ts +2 -4
- package/dist/private/node/ui/components/TextAnimation.js +24 -35
- package/dist/private/node/ui/components/TextAnimation.js.map +1 -1
- package/dist/private/node/ui/components/TokenizedText.test.js +1 -1
- package/dist/private/node/ui/components/TokenizedText.test.js.map +1 -1
- package/dist/private/node/ui/hooks/use-async-and-unmount.d.ts +6 -0
- package/dist/private/node/ui/hooks/use-async-and-unmount.js +17 -0
- package/dist/private/node/ui/hooks/use-async-and-unmount.js.map +1 -0
- package/dist/private/node/ui/hooks/use-layout.d.ts +3 -0
- package/dist/private/node/ui/hooks/use-layout.js +21 -0
- package/dist/private/node/ui/hooks/use-layout.js.map +1 -0
- package/dist/private/node/ui.d.ts +11 -0
- package/dist/private/node/ui.js +1 -1
- package/dist/private/node/ui.js.map +1 -1
- package/dist/public/node/ui.d.ts +5 -0
- package/dist/public/node/ui.js +7 -0
- package/dist/public/node/ui.js.map +1 -1
- package/dist/session.js +8 -5
- package/dist/session.js.map +1 -1
- package/dist/string.d.ts +0 -6
- package/dist/string.js +0 -11
- package/dist/string.js.map +1 -1
- package/dist/testing/ui.d.ts +1 -0
- package/dist/testing/ui.js +4 -0
- package/dist/testing/ui.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FatalError.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/FatalError.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,iBAAiB,CAAA;AAC1C,OAAO,EAAC,YAAY,EAAC,MAAM,aAAa,CAAA;AACxC,OAAO,EAAC,QAAQ,EAAC,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAC,KAAK,EAAE,GAAG,EAAE,aAAa,EAAC,MAAM,sBAAsB,CAAA;AAC9D,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,QAAQ,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE;IAChC,IAAI,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;QAC3C,MAAM,EAAC,MAAM,EAAC,GAAG,YAAY,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAE3D,MAAM,CAAC,QAAQ,CAAC,MAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;KAU/C,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,CAAA;QACzC,KAAK,CAAC,KAAK,GAAG;;;;;;KAMb,CAAA;QAED,MAAM,EAAC,MAAM,EAAC,GAAG,YAAY,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAE3D,MAAM,CAAC,QAAQ,CAAC,MAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;KAc/C,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,CAAA;QACzC,KAAK,CAAC,KAAK,GAAG;;;;;;KAMb,CAAA;QAED,KAAK,CAAC,SAAS,GAAG;YAChB;gBACE,UAAU;gBACV;oBACE,IAAI,EAAE;wBACJ,KAAK,EAAE,yCAAyC;wBAChD,GAAG,EAAE,qCAAqC;qBAC3C;iBACF;gBACD;oBACE,IAAI,EAAE,GAAG;iBACV;aACF;YACD,gEAAgE;YAChE;gBACE,gFAAgF;gBAChF;oBACE,OAAO,EAAE,SAAS;iBACnB;aACF;SACF,CAAA;QAED,MAAM,EAAC,MAAM,EAAC,GAAG,YAAY,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAE3D,MAAM,CAAC,QAAQ,CAAC,MAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;KAqB/C,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,KAAK,GAAG,IAAI,aAAa,CAAC,kBAAkB,EAAE,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,CAAA;QAExE,MAAM,EAAC,MAAM,EAAC,GAAG,YAAY,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAE3D,MAAM,CAAC,QAAQ,CAAC,MAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;KAU/C,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {FatalError} from './FatalError.js'\nimport {renderString} from '../../ui.js'\nimport {unstyled} from '../../../../output.js'\nimport {Abort, Bug, ExternalError} from '../../../../error.js'\nimport {describe, expect, test} from 'vitest'\nimport React from 'react'\n\ndescribe('FatalError', async () => {\n test('renders correctly with a just a message and tryMessage', async () => {\n const error = new Abort('test', 'try this')\n const {output} = renderString(<FatalError error={error} />)\n\n expect(unstyled(output!)).toMatchInlineSnapshot(`\n \"\n ╭─ error ──────────────────────────────────────────────────────────────────────╮\n │ │\n │ test │\n │ │\n │ try this │\n │ │\n ╰──────────────────────────────────────────────────────────────────────────────╯\n \"\n `)\n })\n\n test('renders correctly with a message and a stack', async () => {\n const error = new Bug('Unexpected error')\n error.stack = `\n Error: Unexpected error\n at Module._compile (internal/modules/cjs/loader.js:1137:30)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)\n at Module.load (internal/modules/cjs/loader.js:985:32)\n at Function.Module._load (internal/modules/cjs/loader.js:878:14)\n `\n\n const {output} = renderString(<FatalError error={error} />)\n\n expect(unstyled(output!)).toMatchInlineSnapshot(`\n \"\n ╭─ error ──────────────────────────────────────────────────────────────────────╮\n │ │\n │ Unexpected error │\n │ │\n │ To investigate the issue, examine this stack trace: │\n │
|
|
1
|
+
{"version":3,"file":"FatalError.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/FatalError.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,iBAAiB,CAAA;AAC1C,OAAO,EAAC,YAAY,EAAC,MAAM,aAAa,CAAA;AACxC,OAAO,EAAC,QAAQ,EAAC,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAC,KAAK,EAAE,GAAG,EAAE,aAAa,EAAC,MAAM,sBAAsB,CAAA;AAC9D,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,QAAQ,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE;IAChC,IAAI,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;QAC3C,MAAM,EAAC,MAAM,EAAC,GAAG,YAAY,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAE3D,MAAM,CAAC,QAAQ,CAAC,MAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;KAU/C,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,CAAA;QACzC,KAAK,CAAC,KAAK,GAAG;;;;;;KAMb,CAAA;QAED,MAAM,EAAC,MAAM,EAAC,GAAG,YAAY,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAE3D,MAAM,CAAC,QAAQ,CAAC,MAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;KAc/C,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,CAAA;QACzC,KAAK,CAAC,KAAK,GAAG;;;;;;KAMb,CAAA;QAED,KAAK,CAAC,SAAS,GAAG;YAChB;gBACE,UAAU;gBACV;oBACE,IAAI,EAAE;wBACJ,KAAK,EAAE,yCAAyC;wBAChD,GAAG,EAAE,qCAAqC;qBAC3C;iBACF;gBACD;oBACE,IAAI,EAAE,GAAG;iBACV;aACF;YACD,gEAAgE;YAChE;gBACE,gFAAgF;gBAChF;oBACE,OAAO,EAAE,SAAS;iBACnB;aACF;SACF,CAAA;QAED,MAAM,EAAC,MAAM,EAAC,GAAG,YAAY,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAE3D,MAAM,CAAC,QAAQ,CAAC,MAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;KAqB/C,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,KAAK,GAAG,IAAI,aAAa,CAAC,kBAAkB,EAAE,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,CAAA;QAExE,MAAM,EAAC,MAAM,EAAC,GAAG,YAAY,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAE3D,MAAM,CAAC,QAAQ,CAAC,MAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;KAU/C,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {FatalError} from './FatalError.js'\nimport {renderString} from '../../ui.js'\nimport {unstyled} from '../../../../output.js'\nimport {Abort, Bug, ExternalError} from '../../../../error.js'\nimport {describe, expect, test} from 'vitest'\nimport React from 'react'\n\ndescribe('FatalError', async () => {\n test('renders correctly with a just a message and tryMessage', async () => {\n const error = new Abort('test', 'try this')\n const {output} = renderString(<FatalError error={error} />)\n\n expect(unstyled(output!)).toMatchInlineSnapshot(`\n \"\n ╭─ error ──────────────────────────────────────────────────────────────────────╮\n │ │\n │ test │\n │ │\n │ try this │\n │ │\n ╰──────────────────────────────────────────────────────────────────────────────╯\n \"\n `)\n })\n\n test('renders correctly with a message and a stack', async () => {\n const error = new Bug('Unexpected error')\n error.stack = `\n Error: Unexpected error\n at Module._compile (internal/modules/cjs/loader.js:1137:30)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)\n at Module.load (internal/modules/cjs/loader.js:985:32)\n at Function.Module._load (internal/modules/cjs/loader.js:878:14)\n `\n\n const {output} = renderString(<FatalError error={error} />)\n\n expect(unstyled(output!)).toMatchInlineSnapshot(`\n \"\n ╭─ error ──────────────────────────────────────────────────────────────────────╮\n │ │\n │ Unexpected error │\n │ │\n │ To investigate the issue, examine this stack trace: │\n │ at _compile (internal/modules/cjs/loader.js:1137) │\n │ at js (internal/modules/cjs/loader.js:1157) │\n │ at load (internal/modules/cjs/loader.js:985) │\n │ at _load (internal/modules/cjs/loader.js:878) │\n │ │\n ╰──────────────────────────────────────────────────────────────────────────────╯\n \"\n `)\n })\n\n test('renders correctly with a message, a stack, and next steps', async () => {\n const error = new Bug('Unexpected error')\n error.stack = `\n Error: Unexpected error\n at Module._compile (internal/modules/cjs/loader.js:1137:30)\n at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)\n at Module.load (internal/modules/cjs/loader.js:985:32)\n at Function.Module._load (internal/modules/cjs/loader.js:878:14)\n `\n\n error.nextSteps = [\n [\n 'Have you',\n {\n link: {\n label: 'created a Shopify Partners organization',\n url: 'https://partners.shopify.com/signup',\n },\n },\n {\n char: '?',\n },\n ],\n 'Have you confirmed your accounts from the emails you received?',\n [\n 'Need to connect to a different App or organization? Run the command again with',\n {\n command: '--reset',\n },\n ],\n ]\n\n const {output} = renderString(<FatalError error={error} />)\n\n expect(unstyled(output!)).toMatchInlineSnapshot(`\n \"\n ╭─ error ──────────────────────────────────────────────────────────────────────╮\n │ │\n │ Unexpected error │\n │ │\n │ Next steps │\n │ • Have you created a Shopify Partners organization ( │\n │ https://partners.shopify.com/signup )? │\n │ • Have you confirmed your accounts from the emails you received? │\n │ • Need to connect to a different App or organization? Run the command │\n │ again with \\`--reset\\` │\n │ │\n │ To investigate the issue, examine this stack trace: │\n │ at _compile (internal/modules/cjs/loader.js:1137) │\n │ at js (internal/modules/cjs/loader.js:1157) │\n │ at load (internal/modules/cjs/loader.js:985) │\n │ at _load (internal/modules/cjs/loader.js:878) │\n │ │\n ╰──────────────────────────────────────────────────────────────────────────────╯\n \"\n `)\n })\n\n test('renders correctly an external error', async () => {\n const error = new ExternalError('Unexpected error', 'yarn', ['install'])\n\n const {output} = renderString(<FatalError error={error} />)\n\n expect(unstyled(output!)).toMatchInlineSnapshot(`\n \"\n ── external error ──────────────────────────────────────────────────────────────\n\n Error coming from \\`yarn install\\`\n\n Unexpected error\n\n ────────────────────────────────────────────────────────────────────────────────\n \"\n `)\n })\n})\n"]}
|
|
@@ -3,7 +3,7 @@ import { Text } from 'ink';
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import terminalLink from 'terminal-link';
|
|
5
5
|
function fallback(text, url) {
|
|
6
|
-
return `${text} ${chalk.dim(`(${url})`)}`;
|
|
6
|
+
return `${text} ${chalk.dim(`( ${url} )`)}`;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* `Link` displays a clickable link when supported by the terminal.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Link.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,IAAI,EAAC,MAAM,KAAK,CAAA;AACxB,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,YAAY,MAAM,eAAe,CAAA;AAOxC,SAAS,QAAQ,CAAC,IAAY,EAAE,GAAW;IACzC,OAAO,GAAG,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"Link.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Link.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,IAAI,EAAC,MAAM,KAAK,CAAA;AACxB,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,YAAY,MAAM,eAAe,CAAA;AAOxC,SAAS,QAAQ,CAAC,IAAY,EAAE,GAAW;IACzC,OAAO,GAAG,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,EAAE,CAAA;AAC7C,CAAC;AAED;;GAEG;AACH,MAAM,IAAI,GAAoB,CAAC,EAAC,GAAG,EAAE,KAAK,EAAC,EAAe,EAAE;IAC1D,OAAO,oBAAC,IAAI,QAAE,YAAY,CAAC,KAAK,IAAI,GAAG,EAAE,GAAG,EAAE,EAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAC,CAAC,CAAQ,CAAA;AAC7F,CAAC,CAAA;AAED,OAAO,EAAC,IAAI,EAAC,CAAA","sourcesContent":["import chalk from 'chalk'\nimport {Text} from 'ink'\nimport React from 'react'\nimport terminalLink from 'terminal-link'\n\ninterface Props {\n url: string\n label?: string\n}\n\nfunction fallback(text: string, url: string) {\n return `${text} ${chalk.dim(`( ${url} )`)}`\n}\n\n/**\n * `Link` displays a clickable link when supported by the terminal.\n */\nconst Link: React.FC<Props> = ({url, label}): JSX.Element => {\n return <Text>{terminalLink(label ?? url, url, {fallback: label ? fallback : false})}</Text>\n}\n\nexport {Link}\n"]}
|
|
@@ -9,7 +9,7 @@ describe('Link', async () => {
|
|
|
9
9
|
label: 'Example',
|
|
10
10
|
};
|
|
11
11
|
const { output } = renderString(React.createElement(Link, { ...link }));
|
|
12
|
-
expect(output).toMatchInlineSnapshot('"Example [2m(https://example.com)[22m"');
|
|
12
|
+
expect(output).toMatchInlineSnapshot('"Example [2m( https://example.com )[22m"');
|
|
13
13
|
});
|
|
14
14
|
test("it doesn't render a fallback if only url is passed", async () => {
|
|
15
15
|
const link = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Link.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAC,YAAY,EAAC,MAAM,aAAa,CAAA;AACxC,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,QAAQ,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE;IAC1B,IAAI,CAAC,+EAA+E,EAAE,KAAK,IAAI,EAAE;QAC/F,MAAM,IAAI,GAAG;YACX,GAAG,EAAE,qBAAqB;YAC1B,KAAK,EAAE,SAAS;SACjB,CAAA;QAED,MAAM,EAAC,MAAM,EAAC,GAAG,YAAY,CAAC,oBAAC,IAAI,OAAK,IAAI,GAAI,CAAC,CAAA;QAEjD,MAAM,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,
|
|
1
|
+
{"version":3,"file":"Link.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Link.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAC,YAAY,EAAC,MAAM,aAAa,CAAA;AACxC,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,QAAQ,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE;IAC1B,IAAI,CAAC,+EAA+E,EAAE,KAAK,IAAI,EAAE;QAC/F,MAAM,IAAI,GAAG;YACX,GAAG,EAAE,qBAAqB;YAC1B,KAAK,EAAE,SAAS;SACjB,CAAA;QAED,MAAM,EAAC,MAAM,EAAC,GAAG,YAAY,CAAC,oBAAC,IAAI,OAAK,IAAI,GAAI,CAAC,CAAA;QAEjD,MAAM,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,4CAA4C,CAAC,CAAA;IACpF,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,IAAI,GAAG;YACX,GAAG,EAAE,qBAAqB;SAC3B,CAAA;QAED,MAAM,EAAC,MAAM,EAAC,GAAG,YAAY,CAAC,oBAAC,IAAI,OAAK,IAAI,GAAI,CAAC,CAAA;QAEjD,MAAM,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,uBAAuB,CAAC,CAAA;IAC/D,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {Link} from './Link.js'\nimport {renderString} from '../../ui.js'\nimport {describe, expect, test} from 'vitest'\nimport React from 'react'\n\ndescribe('Link', async () => {\n test(\"renders correctly with a fallback for terminals that don't support hyperlinks\", async () => {\n const link = {\n url: 'https://example.com',\n label: 'Example',\n }\n\n const {output} = renderString(<Link {...link} />)\n\n expect(output).toMatchInlineSnapshot('\"Example \u001b[2m( https://example.com )\u001b[22m\"')\n })\n\n test(\"it doesn't render a fallback if only url is passed\", async () => {\n const link = {\n url: 'https://example.com',\n }\n\n const {output} = renderString(<Link {...link} />)\n\n expect(output).toMatchInlineSnapshot('\"https://example.com\"')\n })\n})\n"]}
|
|
@@ -5,7 +5,7 @@ import { Box, Text } from 'ink';
|
|
|
5
5
|
import { figures } from 'listr2';
|
|
6
6
|
export default function Prompt({ message, choices, infoTable, onChoose, }) {
|
|
7
7
|
const [answer, setAnswer] = useState(null);
|
|
8
|
-
return (React.createElement(Box, { flexDirection: "column" },
|
|
8
|
+
return (React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
|
|
9
9
|
React.createElement(Box, null,
|
|
10
10
|
React.createElement(Box, { marginRight: 2 },
|
|
11
11
|
React.createElement(Text, null, "?")),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Prompt.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Prompt.tsx"],"names":[],"mappings":"AAAA,OAAO,WAAuD,MAAM,kBAAkB,CAAA;AACtF,OAAO,KAA4B,MAAM,YAAY,CAAA;AACrD,OAAO,KAAK,EAAE,EAAC,QAAQ,EAAC,MAAM,OAAO,CAAA;AACrC,OAAO,EAAC,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAA;AAC7B,OAAO,EAAC,OAAO,EAAC,MAAM,QAAQ,CAAA;AAS9B,MAAM,CAAC,OAAO,UAAU,MAAM,CAAI,EAChC,OAAO,EACP,OAAO,EACP,SAAS,EACT,QAAQ,GAC0B;IAClC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAuB,IAAI,CAAC,CAAA;IAEhE,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ;
|
|
1
|
+
{"version":3,"file":"Prompt.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Prompt.tsx"],"names":[],"mappings":"AAAA,OAAO,WAAuD,MAAM,kBAAkB,CAAA;AACtF,OAAO,KAA4B,MAAM,YAAY,CAAA;AACrD,OAAO,KAAK,EAAE,EAAC,QAAQ,EAAC,MAAM,OAAO,CAAA;AACrC,OAAO,EAAC,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAA;AAC7B,OAAO,EAAC,OAAO,EAAC,MAAM,QAAQ,CAAA;AAS9B,MAAM,CAAC,OAAO,UAAU,MAAM,CAAI,EAChC,OAAO,EACP,OAAO,EACP,SAAS,EACT,QAAQ,GAC0B;IAClC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAuB,IAAI,CAAC,CAAA;IAEhE,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,YAAY,EAAE,CAAC;QACzC,oBAAC,GAAG;YACF,oBAAC,GAAG,IAAC,WAAW,EAAE,CAAC;gBACjB,oBAAC,IAAI,YAAS,CACV;YACN,oBAAC,IAAI,QAAE,OAAO,CAAQ,CAClB;QACL,SAAS,IAAI,CAAC,MAAM,IAAI,CACvB,oBAAC,GAAG,IAAC,UAAU,EAAE,CAAC;YAChB,oBAAC,KAAK,IAAC,KAAK,EAAE,SAAS,GAAI,CACvB,CACP;QACA,MAAM,CAAC,CAAC,CAAC,CACR,oBAAC,GAAG;YACF,oBAAC,GAAG,IAAC,WAAW,EAAE,CAAC;gBACjB,oBAAC,IAAI,IAAC,KAAK,EAAC,MAAM,IAAE,OAAO,CAAC,IAAI,CAAQ,CACpC;YAEN,oBAAC,IAAI,IAAC,KAAK,EAAC,MAAM,IAAE,MAAM,CAAC,KAAK,CAAQ,CACpC,CACP,CAAC,CAAC,CAAC,CACF,oBAAC,WAAW,IACV,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,CAAC,KAAQ,EAAE,EAAE;gBACrB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,CAAA;gBACnE,QAAQ,CAAC,KAAK,CAAC,CAAA;YACjB,CAAC,GACD,CACH,CACG,CACP,CAAA;AACH,CAAC","sourcesContent":["import SelectInput, {Props as SelectProps, Item as SelectItem} from './SelectInput.js'\nimport Table, {Props as TableProps} from './Table.js'\nimport React, {useState} from 'react'\nimport {Box, Text} from 'ink'\nimport {figures} from 'listr2'\n\nexport interface Props<T> {\n message: string\n choices: SelectProps<T>['items']\n onChoose: SelectProps<T>['onSelect']\n infoTable?: TableProps['table']\n}\n\nexport default function Prompt<T>({\n message,\n choices,\n infoTable,\n onChoose,\n}: React.PropsWithChildren<Props<T>>): JSX.Element | null {\n const [answer, setAnswer] = useState<SelectItem<T> | null>(null)\n\n return (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Box>\n <Box marginRight={2}>\n <Text>?</Text>\n </Box>\n <Text>{message}</Text>\n </Box>\n {infoTable && !answer && (\n <Box marginLeft={7}>\n <Table table={infoTable} />\n </Box>\n )}\n {answer ? (\n <Box>\n <Box marginRight={2}>\n <Text color=\"cyan\">{figures.tick}</Text>\n </Box>\n\n <Text color=\"cyan\">{answer.label}</Text>\n </Box>\n ) : (\n <SelectInput\n items={choices}\n onSelect={(value: T) => {\n setAnswer(choices.find((choice) => choice.value === value) ?? null)\n onChoose(value)\n }}\n />\n )}\n </Box>\n )\n}\n"]}
|
|
@@ -20,7 +20,8 @@ describe('Prompt', async () => {
|
|
|
20
20
|
await sendInput(renderInstance, ENTER);
|
|
21
21
|
expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`
|
|
22
22
|
"? Associate your project with the org Castile Ventures?
|
|
23
|
-
[36m✔[39m [36msecond[39m
|
|
23
|
+
[36m✔[39m [36msecond[39m
|
|
24
|
+
"
|
|
24
25
|
`);
|
|
25
26
|
expect(onEnter).toHaveBeenCalledWith(items[1].value);
|
|
26
27
|
});
|
|
@@ -64,7 +65,8 @@ describe('Prompt', async () => {
|
|
|
64
65
|
(9) eighth
|
|
65
66
|
(10) ninth
|
|
66
67
|
|
|
67
|
-
[2mnavigate with arrows, enter to select[22m
|
|
68
|
+
[2mnavigate with arrows, enter to select[22m
|
|
69
|
+
"
|
|
68
70
|
`);
|
|
69
71
|
});
|
|
70
72
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Prompt.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Prompt.test.tsx"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,EAAC,SAAS,EAAE,sBAAsB,EAAC,MAAM,2BAA2B,CAAA;AAC3E,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAC,MAAM,QAAQ,CAAA;AACjD,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,MAAM,EAAC,MAAM,qBAAqB,CAAA;AAE1C,MAAM,UAAU,GAAG,UAAU,CAAA;AAC7B,MAAM,KAAK,GAAG,IAAI,CAAA;AAElB,QAAQ,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;IAC5B,IAAI,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;QAClC,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,EAAE,CAAA;QAEvB,MAAM,KAAK,GAAG;YACZ,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAC;YAChC,EAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAC;YAClC,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAC;SACjC,CAAA;QAED,MAAM,SAAS,GAAG,EAAC,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,uBAAuB,EAAE,gBAAgB,CAAC,EAAC,CAAA;QAEzF,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,MAAM,IACL,OAAO,EAAC,uDAAuD,EAC/D,OAAO,EAAE,KAAK,EACd,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,OAAO,GACjB,CACH,CAAA;QAED,MAAM,sBAAsB,EAAE,CAAA;QAC9B,MAAM,SAAS,CAAC,cAAc,EAAE,UAAU,CAAC,CAAA;QAC3C,MAAM,SAAS,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;QAEtC,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC
|
|
1
|
+
{"version":3,"file":"Prompt.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Prompt.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import Prompt from './Prompt.js'\nimport {sendInput, waitForInputsToBeReady} from '../../../../testing/ui.js'\nimport {describe, expect, test, vi} from 'vitest'\nimport React from 'react'\nimport {render} from 'ink-testing-library'\n\nconst ARROW_DOWN = '\\u001B[B'\nconst ENTER = '\\r'\n\ndescribe('Prompt', async () => {\n test('choose an answer', async () => {\n const onEnter = vi.fn()\n\n const items = [\n {label: 'first', value: 'first'},\n {label: 'second', value: 'second'},\n {label: 'third', value: 'third'},\n ]\n\n const infoTable = {Add: ['new-ext'], Remove: ['integrated-demand-ext', 'order-discount']}\n\n const renderInstance = render(\n <Prompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n infoTable={infoTable}\n onChoose={onEnter}\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, ARROW_DOWN)\n await sendInput(renderInstance, ENTER)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures?\n \u001b[36m✔\u001b[39m \u001b[36msecond\u001b[39m\n \"\n `)\n expect(onEnter).toHaveBeenCalledWith(items[1]!.value)\n })\n\n test('supports an info table', async () => {\n const items = [\n {label: 'first', value: 'first', key: 'f'},\n {label: 'second', value: 'second', key: 's'},\n {label: 'third', value: 'third'},\n {label: 'fourth', value: 'fourth'},\n {label: 'fifth', value: 'fifth', group: 'Automations'},\n {label: 'sixth', value: 'sixth', group: 'Automations'},\n {label: 'seventh', value: 'seventh'},\n {label: 'eighth', value: 'eighth', group: 'Merchant Admin'},\n {label: 'ninth', value: 'ninth', group: 'Merchant Admin'},\n {label: 'tenth', value: 'tenth'},\n ]\n\n const infoTable = {\n Add: ['new-ext'],\n Remove: ['integrated-demand-ext', 'order-discount'],\n }\n\n const renderInstance = render(\n <Prompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n infoTable={infoTable}\n onChoose={() => {}}\n />,\n )\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures?\n\n Add: • new-ext\n Remove: • integrated-demand-ext\n • order-discount\n\n \u001b[36m>\u001b[39m \u001b[36m(f) first\u001b[39m\n (s) second\n (3) third\n (4) fourth\n (5) seventh\n (6) tenth\n\n \u001b[1mAutomations\u001b[22m\n (7) fifth\n (8) sixth\n\n \u001b[1mMerchant Admin\u001b[22m\n (9) eighth\n (10) ninth\n\n \u001b[2mnavigate with arrows, enter to select\u001b[22m\n \"\n `)\n })\n})\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { TextAnimation } from './TextAnimation.js';
|
|
2
|
+
import useLayout from '../hooks/use-layout.js';
|
|
3
|
+
import useAsyncAndUnmount from '../hooks/use-async-and-unmount.js';
|
|
4
|
+
import { Box, Text } from 'ink';
|
|
5
|
+
import React, { useState } from 'react';
|
|
6
|
+
const loadingBarChar = '█';
|
|
7
|
+
const Tasks = ({ tasks }) => {
|
|
8
|
+
const { width } = useLayout();
|
|
9
|
+
const loadingBar = new Array(width).fill(loadingBarChar).join('');
|
|
10
|
+
const [currentTask, setCurrentTask] = useState(tasks[0]);
|
|
11
|
+
const [state, setState] = useState('loading');
|
|
12
|
+
const runTasks = async () => {
|
|
13
|
+
for (const task of tasks) {
|
|
14
|
+
setCurrentTask(task);
|
|
15
|
+
// eslint-disable-next-line no-await-in-loop
|
|
16
|
+
await task.task();
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
useAsyncAndUnmount(runTasks, { onFulfilled: () => setState('success'), onRejected: () => setState('failure') });
|
|
20
|
+
return (React.createElement(Box, { flexDirection: "column" },
|
|
21
|
+
React.createElement(Box, null, state === 'loading' ? (React.createElement(TextAnimation, { text: loadingBar })) : (React.createElement(Text, { color: state === 'success' ? 'green' : 'red' }, loadingBar))),
|
|
22
|
+
React.createElement(Text, null, state === 'success' ? (React.createElement(Text, null, "Complete!")) : (React.createElement(Text, null,
|
|
23
|
+
currentTask.title,
|
|
24
|
+
state === 'loading' && ' ...')))));
|
|
25
|
+
};
|
|
26
|
+
export default Tasks;
|
|
27
|
+
//# sourceMappingURL=Tasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tasks.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Tasks.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAChD,OAAO,SAAS,MAAM,wBAAwB,CAAA;AAC9C,OAAO,kBAAkB,MAAM,mCAAmC,CAAA;AAClE,OAAO,EAAC,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAA;AAC7B,OAAO,KAAK,EAAE,EAAC,QAAQ,EAAC,MAAM,OAAO,CAAA;AAErC,MAAM,cAAc,GAAG,GAAG,CAAA;AAW1B,MAAM,KAAK,GAAoB,CAAC,EAAC,KAAK,EAAC,EAAE,EAAE;IACzC,MAAM,EAAC,KAAK,EAAC,GAAG,SAAS,EAAE,CAAA;IAC3B,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACjE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAO,KAAK,CAAC,CAAC,CAAE,CAAC,CAAA;IAC/D,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAoC,SAAS,CAAC,CAAA;IAEhF,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACxB,cAAc,CAAC,IAAI,CAAC,CAAA;YACpB,4CAA4C;YAC5C,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;SAClB;IACH,CAAC,CAAA;IAED,kBAAkB,CAAC,QAAQ,EAAE,EAAC,WAAW,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAC,CAAC,CAAA;IAE7G,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ;QACzB,oBAAC,GAAG,QACD,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CACrB,oBAAC,aAAa,IAAC,IAAI,EAAE,UAAU,GAAI,CACpC,CAAC,CAAC,CAAC,CACF,oBAAC,IAAI,IAAC,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,IAAG,UAAU,CAAQ,CACxE,CACG;QACN,oBAAC,IAAI,QACF,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CACrB,oBAAC,IAAI,oBAAiB,CACvB,CAAC,CAAC,CAAC,CACF,oBAAC,IAAI;YACF,WAAW,CAAC,KAAK;YACjB,KAAK,KAAK,SAAS,IAAI,MAAM,CACzB,CACR,CACI,CACH,CACP,CAAA;AACH,CAAC,CAAA;AAED,eAAe,KAAK,CAAA","sourcesContent":["import {TextAnimation} from './TextAnimation.js'\nimport useLayout from '../hooks/use-layout.js'\nimport useAsyncAndUnmount from '../hooks/use-async-and-unmount.js'\nimport {Box, Text} from 'ink'\nimport React, {useState} from 'react'\n\nconst loadingBarChar = '█'\n\nexport interface Task {\n title: string\n task: () => Promise<void>\n}\n\nexport interface Props {\n tasks: Task[]\n}\n\nconst Tasks: React.FC<Props> = ({tasks}) => {\n const {width} = useLayout()\n const loadingBar = new Array(width).fill(loadingBarChar).join('')\n const [currentTask, setCurrentTask] = useState<Task>(tasks[0]!)\n const [state, setState] = useState<'success' | 'failure' | 'loading'>('loading')\n\n const runTasks = async () => {\n for (const task of tasks) {\n setCurrentTask(task)\n // eslint-disable-next-line no-await-in-loop\n await task.task()\n }\n }\n\n useAsyncAndUnmount(runTasks, {onFulfilled: () => setState('success'), onRejected: () => setState('failure')})\n\n return (\n <Box flexDirection=\"column\">\n <Box>\n {state === 'loading' ? (\n <TextAnimation text={loadingBar} />\n ) : (\n <Text color={state === 'success' ? 'green' : 'red'}>{loadingBar}</Text>\n )}\n </Box>\n <Text>\n {state === 'success' ? (\n <Text>Complete!</Text>\n ) : (\n <Text>\n {currentTask.title}\n {state === 'loading' && ' ...'}\n </Text>\n )}\n </Text>\n </Box>\n )\n}\n\nexport default Tasks\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import Tasks from './Tasks.js';
|
|
2
|
+
import { getLastFrame } from '../../../../testing/ui.js';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { describe, expect, test } from 'vitest';
|
|
5
|
+
import { render } from 'ink-testing-library';
|
|
6
|
+
describe('Tasks', () => {
|
|
7
|
+
test('shows a success state at the end', async () => {
|
|
8
|
+
// Given
|
|
9
|
+
const firstTask = {
|
|
10
|
+
title: 'task 1',
|
|
11
|
+
task: async () => { },
|
|
12
|
+
};
|
|
13
|
+
const secondTask = {
|
|
14
|
+
title: 'task 2',
|
|
15
|
+
task: async () => { },
|
|
16
|
+
};
|
|
17
|
+
// When
|
|
18
|
+
const renderInstance = render(React.createElement(Tasks, { tasks: [firstTask, secondTask] }));
|
|
19
|
+
// wait for next tick
|
|
20
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
21
|
+
// Then
|
|
22
|
+
expect(getLastFrame(renderInstance)).toMatchInlineSnapshot(`
|
|
23
|
+
"[32m████████████████████████████████████████████████████████████████████████████████[39m
|
|
24
|
+
Complete!"
|
|
25
|
+
`);
|
|
26
|
+
});
|
|
27
|
+
test('shows a failure state at the end', async () => {
|
|
28
|
+
// Given
|
|
29
|
+
const firstTask = {
|
|
30
|
+
title: 'task 1',
|
|
31
|
+
task: async () => {
|
|
32
|
+
throw new Error('something went wrong');
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
const secondTask = {
|
|
36
|
+
title: 'task 2',
|
|
37
|
+
task: async () => { },
|
|
38
|
+
};
|
|
39
|
+
// When
|
|
40
|
+
const renderInstance = render(React.createElement(Tasks, { tasks: [firstTask, secondTask] }));
|
|
41
|
+
// wait for next tick
|
|
42
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
43
|
+
// Then
|
|
44
|
+
expect(getLastFrame(renderInstance)).toMatchInlineSnapshot(`
|
|
45
|
+
"[31m████████████████████████████████████████████████████████████████████████████████[39m
|
|
46
|
+
task 1"
|
|
47
|
+
`);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=Tasks.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tasks.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Tasks.test.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,EAAC,YAAY,EAAC,MAAM,2BAA2B,CAAA;AACtD,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAC,MAAM,EAAC,MAAM,qBAAqB,CAAA;AAE1C,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACrB,IAAI,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAClD,QAAQ;QACR,MAAM,SAAS,GAAG;YAChB,KAAK,EAAE,QAAQ;YACf,IAAI,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;SACrB,CAAA;QAED,MAAM,UAAU,GAAG;YACjB,KAAK,EAAE,QAAQ;YACf,IAAI,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;SACrB,CAAA;QACD,OAAO;QAEP,MAAM,cAAc,GAAG,MAAM,CAAC,oBAAC,KAAK,IAAC,KAAK,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,GAAI,CAAC,CAAA;QAExE,qBAAqB;QACrB,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAA;QAEtD,OAAO;QACP,MAAM,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;KAG1D,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAClD,QAAQ;QACR,MAAM,SAAS,GAAG;YAChB,KAAK,EAAE,QAAQ;YACf,IAAI,EAAE,KAAK,IAAI,EAAE;gBACf,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAA;YACzC,CAAC;SACF,CAAA;QAED,MAAM,UAAU,GAAG;YACjB,KAAK,EAAE,QAAQ;YACf,IAAI,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;SACrB,CAAA;QAED,OAAO;QACP,MAAM,cAAc,GAAG,MAAM,CAAC,oBAAC,KAAK,IAAC,KAAK,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,GAAI,CAAC,CAAA;QAExE,qBAAqB;QACrB,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAA;QAEtD,OAAO;QACP,MAAM,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;KAG1D,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import Tasks from './Tasks.js'\nimport {getLastFrame} from '../../../../testing/ui.js'\nimport React from 'react'\nimport {describe, expect, test} from 'vitest'\nimport {render} from 'ink-testing-library'\n\ndescribe('Tasks', () => {\n test('shows a success state at the end', async () => {\n // Given\n const firstTask = {\n title: 'task 1',\n task: async () => {},\n }\n\n const secondTask = {\n title: 'task 2',\n task: async () => {},\n }\n // When\n\n const renderInstance = render(<Tasks tasks={[firstTask, secondTask]} />)\n\n // wait for next tick\n await new Promise((resolve) => setTimeout(resolve, 0))\n\n // Then\n expect(getLastFrame(renderInstance)).toMatchInlineSnapshot(`\n \"\u001b[32m████████████████████████████████████████████████████████████████████████████████\u001b[39m\n Complete!\"\n `)\n })\n\n test('shows a failure state at the end', async () => {\n // Given\n const firstTask = {\n title: 'task 1',\n task: async () => {\n throw new Error('something went wrong')\n },\n }\n\n const secondTask = {\n title: 'task 2',\n task: async () => {},\n }\n\n // When\n const renderInstance = render(<Tasks tasks={[firstTask, secondTask]} />)\n\n // wait for next tick\n await new Promise((resolve) => setTimeout(resolve, 0))\n\n // Then\n expect(getLastFrame(renderInstance)).toMatchInlineSnapshot(`\n \"\u001b[31m████████████████████████████████████████████████████████████████████████████████\u001b[39m\n task 1\"\n `)\n })\n})\n"]}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
declare type AnimationName = 'rainbow' | 'pulse' | 'glitch' | 'radar' | 'neon' | 'karaoke';
|
|
3
2
|
interface Props {
|
|
4
|
-
|
|
5
|
-
speed?: number;
|
|
3
|
+
text: string;
|
|
6
4
|
}
|
|
7
5
|
/**
|
|
8
|
-
* `TextAnimation` applies
|
|
6
|
+
* `TextAnimation` applies a rainbow animation to text.
|
|
9
7
|
*/
|
|
10
8
|
declare const TextAnimation: React.FC<Props>;
|
|
11
9
|
export { TextAnimation };
|
|
@@ -1,46 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
import chalkAnimation from 'chalk-animation';
|
|
1
|
+
/* eslint-disable id-length */
|
|
3
2
|
import { Text } from 'ink';
|
|
4
|
-
import React, { useEffect, useState } from 'react';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
};
|
|
3
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
4
|
+
import gradient from 'gradient-string';
|
|
5
|
+
function rainbow(text, frame) {
|
|
6
|
+
const hue = 5 * frame;
|
|
7
|
+
const leftColor = { h: hue % 360, s: 0.8, v: 1 };
|
|
8
|
+
const rightColor = { h: (hue + 1) % 360, s: 0.8, v: 1 };
|
|
9
|
+
return gradient(leftColor, rightColor)(text, { interpolation: 'hsv', hsvSpin: 'long' });
|
|
10
|
+
}
|
|
13
11
|
/**
|
|
14
|
-
* `TextAnimation` applies
|
|
12
|
+
* `TextAnimation` applies a rainbow animation to text.
|
|
15
13
|
*/
|
|
16
|
-
const TextAnimation = ({
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
.replace(output ?? '')
|
|
28
|
-
.frame()
|
|
29
|
-
.replace(/^\u001B\[(\d)F\u001B\[G\u001B\[2K/, ''); // eslint-disable-line no-control-regex
|
|
30
|
-
setFrame(frame);
|
|
31
|
-
setAnimationTimeout(setTimeout(() => {
|
|
32
|
-
start();
|
|
33
|
-
}, delays[name] / speed));
|
|
14
|
+
const TextAnimation = ({ text }) => {
|
|
15
|
+
const frame = useRef(0);
|
|
16
|
+
const [renderedFrame, setRenderedFrame] = useState(text);
|
|
17
|
+
const timeout = useRef();
|
|
18
|
+
const renderAnimation = () => {
|
|
19
|
+
const newFrame = frame.current + 1;
|
|
20
|
+
frame.current = newFrame;
|
|
21
|
+
setRenderedFrame(rainbow(text, frame.current));
|
|
22
|
+
timeout.current = setTimeout(() => {
|
|
23
|
+
renderAnimation();
|
|
24
|
+
}, 35);
|
|
34
25
|
};
|
|
35
26
|
useEffect(() => {
|
|
36
|
-
|
|
27
|
+
renderAnimation();
|
|
37
28
|
return () => {
|
|
38
|
-
|
|
39
|
-
clearTimeout(animationTimeout);
|
|
40
|
-
setAnimationTimeout(null);
|
|
29
|
+
clearTimeout(timeout.current);
|
|
41
30
|
};
|
|
42
31
|
}, []);
|
|
43
|
-
return React.createElement(Text, null,
|
|
32
|
+
return React.createElement(Text, null, renderedFrame);
|
|
44
33
|
};
|
|
45
34
|
export { TextAnimation };
|
|
46
35
|
//# sourceMappingURL=TextAnimation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextAnimation.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/TextAnimation.tsx"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"TextAnimation.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/TextAnimation.tsx"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,OAAO,EAAC,IAAI,EAAC,MAAM,KAAK,CAAA;AACxB,OAAO,KAAK,EAAE,EAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAA;AACxD,OAAO,QAAQ,MAAM,iBAAiB,CAAA;AAMtC,SAAS,OAAO,CAAC,IAAY,EAAE,KAAa;IAC1C,MAAM,GAAG,GAAG,CAAC,GAAG,KAAK,CAAA;IACrB,MAAM,SAAS,GAAG,EAAC,CAAC,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAC,CAAA;IAC9C,MAAM,UAAU,GAAG,EAAC,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAC,CAAA;IACrD,OAAO,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,IAAI,EAAE,EAAC,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAC,CAAC,CAAA;AACvF,CAAC;AAED;;GAEG;AACH,MAAM,aAAa,GAAoB,CAAC,EAAC,IAAI,EAAC,EAAe,EAAE;IAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;IACvB,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IACxD,MAAM,OAAO,GAAG,MAAM,EAAkB,CAAA;IAExC,MAAM,eAAe,GAAG,GAAG,EAAE;QAC3B,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,GAAG,CAAC,CAAA;QAClC,KAAK,CAAC,OAAO,GAAG,QAAQ,CAAA;QAExB,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA;QAE9C,OAAO,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,eAAe,EAAE,CAAA;QACnB,CAAC,EAAE,EAAE,CAAC,CAAA;IACR,CAAC,CAAA;IAED,SAAS,CAAC,GAAG,EAAE;QACb,eAAe,EAAE,CAAA;QAEjB,OAAO,GAAG,EAAE;YACV,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAC/B,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,oBAAC,IAAI,QAAE,aAAa,CAAQ,CAAA;AACrC,CAAC,CAAA;AAED,OAAO,EAAC,aAAa,EAAC,CAAA","sourcesContent":["/* eslint-disable id-length */\nimport {Text} from 'ink'\nimport React, {useEffect, useRef, useState} from 'react'\nimport gradient from 'gradient-string'\n\ninterface Props {\n text: string\n}\n\nfunction rainbow(text: string, frame: number) {\n const hue = 5 * frame\n const leftColor = {h: hue % 360, s: 0.8, v: 1}\n const rightColor = {h: (hue + 1) % 360, s: 0.8, v: 1}\n return gradient(leftColor, rightColor)(text, {interpolation: 'hsv', hsvSpin: 'long'})\n}\n\n/**\n * `TextAnimation` applies a rainbow animation to text.\n */\nconst TextAnimation: React.FC<Props> = ({text}): JSX.Element => {\n const frame = useRef(0)\n const [renderedFrame, setRenderedFrame] = useState(text)\n const timeout = useRef<NodeJS.Timeout>()\n\n const renderAnimation = () => {\n const newFrame = frame.current + 1\n frame.current = newFrame\n\n setRenderedFrame(rainbow(text, frame.current))\n\n timeout.current = setTimeout(() => {\n renderAnimation()\n }, 35)\n }\n\n useEffect(() => {\n renderAnimation()\n\n return () => {\n clearTimeout(timeout.current)\n }\n }, [])\n\n return <Text>{renderedFrame}</Text>\n}\n\nexport {TextAnimation}\n"]}
|
|
@@ -33,7 +33,7 @@ describe('TokenizedText', async () => {
|
|
|
33
33
|
];
|
|
34
34
|
const { output } = renderString(React.createElement(TokenizedText, { item: item }));
|
|
35
35
|
expect(unstyled(output)).toMatchInlineSnapshot(`
|
|
36
|
-
"Run \`cd verification-app\` Example (https://example.com)! my-app
|
|
36
|
+
"Run \`cd verification-app\` Example ( https://example.com )! my-app
|
|
37
37
|
• Item 1
|
|
38
38
|
• Item 2
|
|
39
39
|
• Item 3
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenizedText.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/TokenizedText.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAC,YAAY,EAAC,MAAM,aAAa,CAAA;AACxC,OAAO,EAAC,QAAQ,EAAC,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,QAAQ,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;IACnC,IAAI,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,IAAI,GAAG;YACX,KAAK;YACL;gBACE,OAAO,EAAE,qBAAqB;aAC/B;YACD;gBACE,IAAI,EAAE;oBACJ,GAAG,EAAE,qBAAqB;oBAC1B,KAAK,EAAE,SAAS;iBACjB;aACF;YACD;gBACE,IAAI,EAAE,GAAG;aACV;YACD;gBACE,SAAS,EAAE,QAAQ;aACpB;YACD;gBACE,IAAI,EAAE;oBACJ,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;iBACtC;aACF;YACD;gBACE,QAAQ,EAAE,uBAAuB;aAClC;SACF,CAAA;QAED,MAAM,EAAC,MAAM,EAAC,GAAG,YAAY,CAAC,oBAAC,aAAa,IAAC,IAAI,EAAE,IAAI,GAAI,CAAC,CAAA;QAE5D,MAAM,CAAC,QAAQ,CAAC,MAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;KAM/C,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {TokenizedText} from './TokenizedText.js'\nimport {renderString} from '../../ui.js'\nimport {unstyled} from '../../../../output.js'\nimport {describe, expect, test} from 'vitest'\nimport React from 'react'\n\ndescribe('TokenizedText', async () => {\n test('renders arrays of items separated by spaces', async () => {\n const item = [\n 'Run',\n {\n command: 'cd verification-app',\n },\n {\n link: {\n url: 'https://example.com',\n label: 'Example',\n },\n },\n {\n char: '!',\n },\n {\n userInput: 'my-app',\n },\n {\n list: {\n items: ['Item 1', 'Item 2', 'Item 3'],\n },\n },\n {\n filePath: 'src/this/is/a/test.js',\n },\n ]\n\n const {output} = renderString(<TokenizedText item={item} />)\n\n expect(unstyled(output!)).toMatchInlineSnapshot(`\n \"Run \\`cd verification-app\\` Example (https://example.com)! my-app\n • Item 1\n • Item 2\n • Item 3\n \\\\\"src/this/is/a/test.js\\\\\"\"\n `)\n })\n})\n"]}
|
|
1
|
+
{"version":3,"file":"TokenizedText.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/TokenizedText.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAC,YAAY,EAAC,MAAM,aAAa,CAAA;AACxC,OAAO,EAAC,QAAQ,EAAC,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,QAAQ,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;IACnC,IAAI,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,IAAI,GAAG;YACX,KAAK;YACL;gBACE,OAAO,EAAE,qBAAqB;aAC/B;YACD;gBACE,IAAI,EAAE;oBACJ,GAAG,EAAE,qBAAqB;oBAC1B,KAAK,EAAE,SAAS;iBACjB;aACF;YACD;gBACE,IAAI,EAAE,GAAG;aACV;YACD;gBACE,SAAS,EAAE,QAAQ;aACpB;YACD;gBACE,IAAI,EAAE;oBACJ,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;iBACtC;aACF;YACD;gBACE,QAAQ,EAAE,uBAAuB;aAClC;SACF,CAAA;QAED,MAAM,EAAC,MAAM,EAAC,GAAG,YAAY,CAAC,oBAAC,aAAa,IAAC,IAAI,EAAE,IAAI,GAAI,CAAC,CAAA;QAE5D,MAAM,CAAC,QAAQ,CAAC,MAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;KAM/C,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {TokenizedText} from './TokenizedText.js'\nimport {renderString} from '../../ui.js'\nimport {unstyled} from '../../../../output.js'\nimport {describe, expect, test} from 'vitest'\nimport React from 'react'\n\ndescribe('TokenizedText', async () => {\n test('renders arrays of items separated by spaces', async () => {\n const item = [\n 'Run',\n {\n command: 'cd verification-app',\n },\n {\n link: {\n url: 'https://example.com',\n label: 'Example',\n },\n },\n {\n char: '!',\n },\n {\n userInput: 'my-app',\n },\n {\n list: {\n items: ['Item 1', 'Item 2', 'Item 3'],\n },\n },\n {\n filePath: 'src/this/is/a/test.js',\n },\n ]\n\n const {output} = renderString(<TokenizedText item={item} />)\n\n expect(unstyled(output!)).toMatchInlineSnapshot(`\n \"Run \\`cd verification-app\\` Example ( https://example.com )! my-app\n • Item 1\n • Item 2\n • Item 3\n \\\\\"src/this/is/a/test.js\\\\\"\"\n `)\n })\n})\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useApp } from 'ink';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
export default function useEffectAsync(asyncFunction, { onFulfilled = () => { }, onRejected = () => { } }) {
|
|
4
|
+
const { exit: unmountInk } = useApp();
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
asyncFunction()
|
|
7
|
+
.then(() => {
|
|
8
|
+
onFulfilled();
|
|
9
|
+
unmountInk();
|
|
10
|
+
})
|
|
11
|
+
.catch((error) => {
|
|
12
|
+
onRejected(error);
|
|
13
|
+
unmountInk(error);
|
|
14
|
+
});
|
|
15
|
+
}, []);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=use-async-and-unmount.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-async-and-unmount.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/hooks/use-async-and-unmount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,KAAK,CAAA;AAC1B,OAAO,EAAC,SAAS,EAAC,MAAM,OAAO,CAAA;AAO/B,MAAM,CAAC,OAAO,UAAU,cAAc,CACpC,aAAqC,EACrC,EAAC,WAAW,GAAG,GAAG,EAAE,GAAE,CAAC,EAAE,UAAU,GAAG,GAAG,EAAE,GAAE,CAAC,EAAU;IAExD,MAAM,EAAC,IAAI,EAAE,UAAU,EAAC,GAAG,MAAM,EAAE,CAAA;IAEnC,SAAS,CAAC,GAAG,EAAE;QACb,aAAa,EAAE;aACZ,IAAI,CAAC,GAAG,EAAE;YACT,WAAW,EAAE,CAAA;YACb,UAAU,EAAE,CAAA;QACd,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACf,UAAU,CAAC,KAAK,CAAC,CAAA;YACjB,UAAU,CAAC,KAAK,CAAC,CAAA;QACnB,CAAC,CAAC,CAAA;IACN,CAAC,EAAE,EAAE,CAAC,CAAA;AACR,CAAC","sourcesContent":["import {useApp} from 'ink'\nimport {useEffect} from 'react'\n\ninterface Options {\n onFulfilled?: () => unknown\n onRejected?: (error: Error) => void\n}\n\nexport default function useEffectAsync(\n asyncFunction: () => Promise<unknown>,\n {onFulfilled = () => {}, onRejected = () => {}}: Options,\n) {\n const {exit: unmountInk} = useApp()\n\n useEffect(() => {\n asyncFunction()\n .then(() => {\n onFulfilled()\n unmountInk()\n })\n .catch((error) => {\n onRejected(error)\n unmountInk(error)\n })\n }, [])\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useStdout } from 'ink';
|
|
2
|
+
const MIN_WIDTH = 80;
|
|
3
|
+
export default function useLayout() {
|
|
4
|
+
const { stdout } = useStdout();
|
|
5
|
+
const fullWidth = stdout?.columns ?? MIN_WIDTH;
|
|
6
|
+
const twoThirdsOfWidth = Math.floor((fullWidth / 3) * 2);
|
|
7
|
+
let width;
|
|
8
|
+
if (fullWidth <= MIN_WIDTH) {
|
|
9
|
+
width = fullWidth;
|
|
10
|
+
}
|
|
11
|
+
else if (twoThirdsOfWidth < MIN_WIDTH) {
|
|
12
|
+
width = MIN_WIDTH;
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
width = twoThirdsOfWidth;
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
width,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=use-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-layout.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/hooks/use-layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,KAAK,CAAA;AAE7B,MAAM,SAAS,GAAG,EAAE,CAAA;AAEpB,MAAM,CAAC,OAAO,UAAU,SAAS;IAC/B,MAAM,EAAC,MAAM,EAAC,GAAG,SAAS,EAAE,CAAA;IAE5B,MAAM,SAAS,GAAG,MAAM,EAAE,OAAO,IAAI,SAAS,CAAA;IAC9C,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IACxD,IAAI,KAAK,CAAA;IAET,IAAI,SAAS,IAAI,SAAS,EAAE;QAC1B,KAAK,GAAG,SAAS,CAAA;KAClB;SAAM,IAAI,gBAAgB,GAAG,SAAS,EAAE;QACvC,KAAK,GAAG,SAAS,CAAA;KAClB;SAAM;QACL,KAAK,GAAG,gBAAgB,CAAA;KACzB;IAED,OAAO;QACL,KAAK;KACN,CAAA;AACH,CAAC","sourcesContent":["import {useStdout} from 'ink'\n\nconst MIN_WIDTH = 80\n\nexport default function useLayout() {\n const {stdout} = useStdout()\n\n const fullWidth = stdout?.columns ?? MIN_WIDTH\n const twoThirdsOfWidth = Math.floor((fullWidth / 3) * 2)\n let width\n\n if (fullWidth <= MIN_WIDTH) {\n width = fullWidth\n } else if (twoThirdsOfWidth < MIN_WIDTH) {\n width = MIN_WIDTH\n } else {\n width = twoThirdsOfWidth\n }\n\n return {\n width,\n }\n}\n"]}
|
|
@@ -1,13 +1,24 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { Logger, LogLevel } from '../../output.js';
|
|
2
3
|
import { Props as PromptProps } from '../../private/node/ui/components/Prompt.js';
|
|
3
4
|
import { ReactElement } from 'react';
|
|
4
5
|
import { RenderOptions } from 'ink';
|
|
6
|
+
import { EventEmitter } from 'events';
|
|
5
7
|
export declare function renderOnce(element: JSX.Element, logLevel?: LogLevel, logger?: Logger): void;
|
|
6
8
|
export declare function render(element: JSX.Element, options?: RenderOptions): Promise<void>;
|
|
7
9
|
interface Instance {
|
|
8
10
|
output: string | undefined;
|
|
9
11
|
unmount: () => void;
|
|
10
12
|
}
|
|
13
|
+
export declare class OutputStream extends EventEmitter {
|
|
14
|
+
columns: number;
|
|
15
|
+
private _lastFrame?;
|
|
16
|
+
constructor(options: {
|
|
17
|
+
columns: number;
|
|
18
|
+
});
|
|
19
|
+
write: (frame: string) => void;
|
|
20
|
+
lastFrame: () => string | undefined;
|
|
21
|
+
}
|
|
11
22
|
export declare const renderString: (element: ReactElement) => Instance;
|
|
12
23
|
export declare function prompt<T>(options: Omit<PromptProps<T>, 'onChoose'>): Promise<T>;
|
|
13
24
|
export {};
|
package/dist/private/node/ui.js
CHANGED
|
@@ -18,7 +18,7 @@ export function render(element, options) {
|
|
|
18
18
|
return waitUntilExit();
|
|
19
19
|
}
|
|
20
20
|
const TEST_TERMINAL_WIDTH = 80;
|
|
21
|
-
class OutputStream extends EventEmitter {
|
|
21
|
+
export class OutputStream extends EventEmitter {
|
|
22
22
|
constructor(options) {
|
|
23
23
|
super();
|
|
24
24
|
this.write = (frame) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../src/private/node/ui.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,4BAA4B,CAAA;AACrD,OAAO,EAAC,UAAU,EAAE,UAAU,EAAoB,sBAAsB,EAAC,MAAM,iBAAiB,CAAA;AAChG,OAAO,MAA8B,MAAM,4CAA4C,CAAA;AACvF,OAAO,KAAqB,MAAM,OAAO,CAAA;AACzC,OAAO,EAAC,MAAM,IAAI,SAAS,EAAgB,MAAM,KAAK,CAAA;AACtD,OAAO,EAAC,YAAY,EAAC,MAAM,QAAQ,CAAA;AAEnC,MAAM,UAAU,UAAU,CAAC,OAAoB,EAAE,WAAqB,MAAM,EAAE,SAAiB,UAAU;IACvG,MAAM,EAAC,MAAM,EAAE,OAAO,EAAC,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;IAE/C,IAAI,MAAM,EAAE;QACV,IAAI,UAAU,EAAE;YAAE,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QAC9C,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;KACjD;IAED,OAAO,EAAE,CAAA;AACX,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,OAAoB,EAAE,OAAuB;IAClE,MAAM,EAAC,aAAa,EAAC,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IACnD,OAAO,aAAa,EAAE,CAAA;AACxB,CAAC;AAOD,MAAM,mBAAmB,GAAG,EAAE,CAAA;AAC9B,MAAM,YAAa,SAAQ,YAAY;
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../src/private/node/ui.tsx"],"names":[],"mappings":"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","sourcesContent":["import {isUnitTest} from '../../environment/local.js'\nimport {collectLog, consoleLog, Logger, LogLevel, outputWhereAppropriate} from '../../output.js'\nimport Prompt, {Props as PromptProps} from '../../private/node/ui/components/Prompt.js'\nimport React, {ReactElement} from 'react'\nimport {render as inkRender, RenderOptions} from 'ink'\nimport {EventEmitter} from 'events'\n\nexport function renderOnce(element: JSX.Element, logLevel: LogLevel = 'info', logger: Logger = consoleLog) {\n const {output, unmount} = renderString(element)\n\n if (output) {\n if (isUnitTest()) collectLog(logLevel, output)\n outputWhereAppropriate(logLevel, logger, output)\n }\n\n unmount()\n}\n\nexport function render(element: JSX.Element, options?: RenderOptions) {\n const {waitUntilExit} = inkRender(element, options)\n return waitUntilExit()\n}\n\ninterface Instance {\n output: string | undefined\n unmount: () => void\n}\n\nconst TEST_TERMINAL_WIDTH = 80\nexport class OutputStream extends EventEmitter {\n columns: number\n private _lastFrame?: string\n\n constructor(options: {columns: number}) {\n super()\n this.columns = options.columns\n }\n\n write = (frame: string) => {\n this._lastFrame = frame\n }\n\n lastFrame = () => {\n return this._lastFrame\n }\n}\n\nexport const renderString = (element: ReactElement): Instance => {\n const stdout = new OutputStream({columns: isUnitTest() ? TEST_TERMINAL_WIDTH : process.stdout.columns})\n const stderr = new OutputStream({columns: isUnitTest() ? TEST_TERMINAL_WIDTH : process.stderr.columns})\n\n const instance = inkRender(element, {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stdout: stdout as any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stderr: stderr as any,\n debug: true,\n exitOnCtrlC: false,\n patchConsole: false,\n })\n\n return {\n output: stdout.lastFrame(),\n unmount: instance.unmount,\n }\n}\n\nexport async function prompt<T>(options: Omit<PromptProps<T>, 'onChoose'>) {\n let onChooseResolve: (choice: T) => void = () => {}\n\n const onChoosePromise = new Promise<T>((resolve) => {\n onChooseResolve = resolve\n })\n\n const props = {\n ...options,\n onChoose: onChooseResolve,\n }\n\n await render(<Prompt {...props} />, {exitOnCtrlC: false})\n\n return onChoosePromise\n}\n"]}
|
package/dist/public/node/ui.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { OutputProcess } from '../../output.js';
|
|
|
2
2
|
import { Fatal } from '../../error.js';
|
|
3
3
|
import { AlertProps } from '../../private/node/ui/components/Alert.js';
|
|
4
4
|
import { Props as PromptProps } from '../../private/node/ui/components/Prompt.js';
|
|
5
|
+
import { Task } from '../../private/node/ui/components/Tasks.js';
|
|
5
6
|
import { AbortController } from 'abort-controller';
|
|
6
7
|
import { RenderOptions } from 'ink';
|
|
7
8
|
interface RenderConcurrentOptions {
|
|
@@ -181,4 +182,8 @@ interface ConfirmationProps {
|
|
|
181
182
|
* navigate with arrows, enter to select
|
|
182
183
|
*/
|
|
183
184
|
export declare function renderConfirmation({ question, infoTable }: ConfirmationProps): Promise<boolean>;
|
|
185
|
+
/**
|
|
186
|
+
* Runs async tasks and displays their progress to the console.
|
|
187
|
+
*/
|
|
188
|
+
export declare function renderTasks(tasks: Task[]): Promise<void>;
|
|
184
189
|
export {};
|
package/dist/public/node/ui.js
CHANGED
|
@@ -3,6 +3,7 @@ import { consoleError } from '../../output.js';
|
|
|
3
3
|
import { prompt, render, renderOnce } from '../../private/node/ui.js';
|
|
4
4
|
import { alert } from '../../private/node/ui/alert.js';
|
|
5
5
|
import { FatalError } from '../../private/node/ui/components/FatalError.js';
|
|
6
|
+
import Tasks from '../../private/node/ui/components/Tasks.js';
|
|
6
7
|
import React from 'react';
|
|
7
8
|
import { AbortController } from 'abort-controller';
|
|
8
9
|
/**
|
|
@@ -197,4 +198,10 @@ export async function renderConfirmation({ question, infoTable }) {
|
|
|
197
198
|
];
|
|
198
199
|
return prompt({ message: question, choices, infoTable });
|
|
199
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Runs async tasks and displays their progress to the console.
|
|
203
|
+
*/
|
|
204
|
+
export function renderTasks(tasks) {
|
|
205
|
+
return render(React.createElement(Tasks, { tasks: tasks }));
|
|
206
|
+
}
|
|
200
207
|
//# sourceMappingURL=ui.js.map
|