@shopify/cli-kit 3.31.1 → 3.32.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/README.md +1 -1
- package/dist/api.d.ts +2 -5
- package/dist/api.js +2 -5
- package/dist/api.js.map +1 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/constants.js.map +1 -1
- package/dist/environment/local.d.ts +1 -0
- package/dist/environment/local.js +4 -1
- package/dist/environment/local.js.map +1 -1
- package/dist/file.d.ts +10 -3
- package/dist/file.js +34 -34
- package/dist/file.js.map +1 -1
- package/dist/http/fetch.js +1 -1
- package/dist/http/fetch.js.map +1 -1
- package/dist/http.d.ts +0 -1
- package/dist/http.js +0 -1
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +0 -8
- package/dist/index.js +0 -8
- package/dist/index.js.map +1 -1
- package/dist/metadata.d.ts +1 -1
- package/dist/metadata.js.map +1 -1
- package/dist/monorail.d.ts +1 -1
- package/dist/monorail.js.map +1 -1
- package/dist/npm.js +1 -1
- package/dist/npm.js.map +1 -1
- package/dist/output.d.ts +2 -2
- package/dist/output.js +1 -1
- package/dist/output.js.map +1 -1
- package/dist/path.d.ts +3 -1
- package/dist/path.js +2 -2
- package/dist/path.js.map +1 -1
- package/dist/plugins.d.ts +1 -1
- package/dist/plugins.js.map +1 -1
- package/dist/{json.d.ts → private/common/json.d.ts} +0 -0
- package/dist/{json.js → private/common/json.js} +0 -0
- package/dist/private/common/json.js.map +1 -0
- package/dist/private/node/analytics.d.ts +27 -0
- package/dist/private/node/analytics.js +57 -0
- package/dist/private/node/analytics.js.map +1 -0
- package/dist/private/node/api/graphql.d.ts +5 -0
- package/dist/private/node/api/graphql.js +63 -0
- package/dist/private/node/api/graphql.js.map +1 -0
- package/dist/{api/common.d.ts → private/node/api/headers.d.ts} +3 -8
- package/dist/{api/common.js → private/node/api/headers.js} +20 -60
- package/dist/private/node/api/headers.js.map +1 -0
- package/dist/private/node/ui/components/Alert.test.js +5 -5
- package/dist/private/node/ui/components/Alert.test.js.map +1 -1
- package/dist/private/node/ui/components/Banner.js +5 -5
- package/dist/private/node/ui/components/Banner.js.map +1 -1
- package/dist/private/node/ui/components/Banner.test.js +11 -11
- package/dist/private/node/ui/components/Banner.test.js.map +1 -1
- package/dist/private/node/ui/components/Command.test.js +3 -3
- package/dist/private/node/ui/components/Command.test.js.map +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.d.ts +2 -2
- package/dist/private/node/ui/components/ConcurrentOutput.js +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.test.js +3 -3
- package/dist/private/node/ui/components/ConcurrentOutput.test.js.map +1 -1
- package/dist/private/node/ui/components/FatalError.test.js +9 -9
- package/dist/private/node/ui/components/FatalError.test.js.map +1 -1
- package/dist/private/node/ui/components/FilePath.test.js +3 -3
- package/dist/private/node/ui/components/FilePath.test.js.map +1 -1
- package/dist/private/node/ui/components/FullScreen.js +11 -9
- package/dist/private/node/ui/components/FullScreen.js.map +1 -1
- package/dist/private/node/ui/components/Link.test.js +5 -5
- package/dist/private/node/ui/components/Link.test.js.map +1 -1
- package/dist/private/node/ui/components/List.test.js +5 -5
- package/dist/private/node/ui/components/List.test.js.map +1 -1
- package/dist/private/node/ui/components/SelectInput.d.ts +2 -2
- package/dist/private/node/ui/components/SelectInput.js +16 -24
- package/dist/private/node/ui/components/SelectInput.js.map +1 -1
- package/dist/private/node/ui/components/SelectInput.test.js +62 -32
- package/dist/private/node/ui/components/SelectInput.test.js.map +1 -1
- package/dist/private/node/ui/components/{Prompt.d.ts → SelectPrompt.d.ts} +4 -3
- package/dist/private/node/ui/components/SelectPrompt.js +46 -0
- package/dist/private/node/ui/components/SelectPrompt.js.map +1 -0
- package/dist/private/node/ui/components/{Prompt.test.d.ts → SelectPrompt.test.d.ts} +0 -0
- package/dist/private/node/ui/components/{Prompt.test.js → SelectPrompt.test.js} +7 -6
- package/dist/private/node/ui/components/SelectPrompt.test.js.map +1 -0
- package/dist/private/node/ui/components/Table.js +2 -2
- package/dist/private/node/ui/components/Table.js.map +1 -1
- package/dist/private/node/ui/components/Tasks.d.ts +1 -1
- package/dist/private/node/ui/components/Tasks.js +3 -3
- package/dist/private/node/ui/components/Tasks.js.map +1 -1
- package/dist/private/node/ui/components/Tasks.test.js +4 -4
- package/dist/private/node/ui/components/Tasks.test.js.map +1 -1
- package/dist/private/node/ui/components/TextAnimation.js.map +1 -1
- package/dist/private/node/ui/components/TextInput.d.ts +9 -0
- package/dist/private/node/ui/components/TextInput.js +74 -0
- package/dist/private/node/ui/components/TextInput.js.map +1 -0
- package/dist/private/node/ui/components/TextInput.test.d.ts +1 -0
- package/dist/private/node/ui/components/TextInput.test.js +139 -0
- package/dist/private/node/ui/components/TextInput.test.js.map +1 -0
- package/dist/private/node/ui/components/TextPrompt.d.ts +8 -0
- package/dist/private/node/ui/components/TextPrompt.js +52 -0
- package/dist/private/node/ui/components/TextPrompt.js.map +1 -0
- package/dist/private/node/ui/components/TextPrompt.test.d.ts +1 -0
- package/dist/private/node/ui/components/TextPrompt.test.js +68 -0
- package/dist/private/node/ui/components/TextPrompt.test.js.map +1 -0
- package/dist/private/node/ui/components/TokenizedText.test.js +3 -3
- package/dist/private/node/ui/components/TokenizedText.test.js.map +1 -1
- package/dist/private/node/ui/components/UserInput.test.js +3 -3
- package/dist/private/node/ui/components/UserInput.test.js.map +1 -1
- package/dist/private/node/ui/hooks/use-layout.d.ts +6 -3
- package/dist/private/node/ui/hooks/use-layout.js +17 -8
- package/dist/private/node/ui/hooks/use-layout.js.map +1 -1
- package/dist/private/node/ui.d.ts +2 -3
- package/dist/private/node/ui.js +7 -16
- package/dist/private/node/ui.js.map +1 -1
- package/dist/public/common/array.js +1 -1
- package/dist/public/common/array.js.map +1 -1
- package/dist/public/common/collection.js +1 -1
- package/dist/public/common/collection.js.map +1 -1
- package/dist/public/common/function.js +1 -1
- package/dist/public/common/function.js.map +1 -1
- package/dist/public/common/lang.js +1 -1
- package/dist/public/common/lang.js.map +1 -1
- package/dist/public/common/object.js +4 -4
- package/dist/public/common/object.js.map +1 -1
- package/dist/public/common/string.d.ts +55 -1
- package/dist/public/common/string.js +93 -1
- package/dist/public/common/string.js.map +1 -1
- package/dist/public/common/url.d.ts +7 -0
- package/dist/public/common/url.js +17 -0
- package/dist/public/common/url.js.map +1 -0
- package/dist/public/node/abort.d.ts +16 -0
- package/dist/public/node/abort.js +17 -0
- package/dist/public/node/abort.js.map +1 -0
- package/dist/public/node/analytics.d.ts +13 -0
- package/dist/public/node/analytics.js +82 -0
- package/dist/public/node/analytics.js.map +1 -0
- package/dist/public/node/api/admin.d.ts +11 -0
- package/dist/public/node/api/admin.js +70 -0
- package/dist/public/node/api/admin.js.map +1 -0
- package/dist/public/node/api/oxygen.d.ts +22 -0
- package/dist/public/node/api/oxygen.js +40 -0
- package/dist/public/node/api/oxygen.js.map +1 -0
- package/dist/{api → public/node/api}/partners.d.ts +11 -3
- package/dist/public/node/api/partners.js +40 -0
- package/dist/public/node/api/partners.js.map +1 -0
- package/dist/public/node/archiver.js +1 -1
- package/dist/public/node/archiver.js.map +1 -1
- package/dist/public/node/base-command.js +1 -1
- package/dist/public/node/base-command.js.map +1 -1
- package/dist/public/node/crypto.d.ts +42 -0
- package/dist/public/node/crypto.js +55 -0
- package/dist/public/node/crypto.js.map +1 -0
- package/dist/public/node/error-handler.js +3 -2
- package/dist/public/node/error-handler.js.map +1 -1
- package/dist/public/node/framework.js +1 -1
- package/dist/public/node/framework.js.map +1 -1
- package/dist/public/node/hooks/postrun.js +2 -2
- package/dist/public/node/hooks/postrun.js.map +1 -1
- package/dist/public/node/hooks/prerun.js +2 -2
- package/dist/public/node/hooks/prerun.js.map +1 -1
- package/dist/{template.d.ts → public/node/liquid.d.ts} +10 -2
- package/dist/{template.js → public/node/liquid.js} +18 -13
- package/dist/public/node/liquid.js.map +1 -0
- package/dist/public/node/node-package-manager.d.ts +3 -3
- package/dist/public/node/node-package-manager.js +1 -1
- package/dist/public/node/node-package-manager.js.map +1 -1
- package/dist/public/node/os.d.ts +16 -0
- package/dist/{os.js → public/node/os.js} +33 -29
- package/dist/public/node/os.js.map +1 -0
- package/dist/public/node/presets.d.ts +1 -1
- package/dist/public/node/presets.js +2 -2
- package/dist/public/node/presets.js.map +1 -1
- package/dist/public/node/ruby.d.ts +13 -9
- package/dist/public/node/ruby.js +91 -23
- package/dist/public/node/ruby.js.map +1 -1
- package/dist/public/node/tcp.d.ts +2 -0
- package/dist/public/node/tcp.js +9 -0
- package/dist/public/node/tcp.js.map +1 -1
- package/dist/public/node/toml.d.ts +15 -0
- package/dist/public/node/toml.js +20 -0
- package/dist/public/node/toml.js.map +1 -0
- package/dist/public/node/ui.d.ts +12 -17
- package/dist/public/node/ui.js +25 -29
- package/dist/public/node/ui.js.map +1 -1
- package/dist/public/node/vscode.d.ts +14 -0
- package/dist/{vscode.js → public/node/vscode.js} +13 -7
- package/dist/public/node/vscode.js.map +1 -0
- package/dist/session/authorize.d.ts +4 -0
- package/dist/session/authorize.js +8 -3
- package/dist/session/authorize.js.map +1 -1
- package/dist/{api/identity.d.ts → session/identity-token-validation.d.ts} +0 -0
- package/dist/{api/identity.js → session/identity-token-validation.js} +1 -1
- package/dist/session/identity-token-validation.js.map +1 -0
- package/dist/session/redirect-listener.js +6 -3
- package/dist/session/redirect-listener.js.map +1 -1
- package/dist/session/schema.d.ts +18 -18
- package/dist/session/store.js +1 -1
- package/dist/session/store.js.map +1 -1
- package/dist/session.js +3 -3
- package/dist/session.js.map +1 -1
- package/dist/system.d.ts +2 -2
- package/dist/system.js +1 -1
- package/dist/system.js.map +1 -1
- package/dist/testing/ui.d.ts +1 -1
- package/dist/testing/ui.js +1 -1
- package/dist/testing/ui.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/ui/inquirer/autocomplete.d.ts +2 -2
- package/dist/ui/inquirer/autocomplete.js +1 -1
- package/dist/ui/inquirer/autocomplete.js.map +1 -1
- package/dist/ui/inquirer/input.d.ts +2 -2
- package/dist/ui/inquirer/input.js.map +1 -1
- package/dist/ui/inquirer/password.d.ts +2 -2
- package/dist/ui/inquirer/password.js.map +1 -1
- package/dist/ui/inquirer/select.d.ts +2 -2
- package/dist/ui/inquirer/select.js +2 -2
- package/dist/ui/inquirer/select.js.map +1 -1
- package/package.json +30 -27
- package/dist/abort.d.ts +0 -1
- package/dist/abort.js +0 -2
- package/dist/abort.js.map +0 -1
- package/dist/analytics.d.ts +0 -44
- package/dist/analytics.js +0 -154
- package/dist/analytics.js.map +0 -1
- package/dist/api/admin.d.ts +0 -3
- package/dist/api/admin.js +0 -56
- package/dist/api/admin.js.map +0 -1
- package/dist/api/common.js.map +0 -1
- package/dist/api/identity.js.map +0 -1
- package/dist/api/oxygen.d.ts +0 -5
- package/dist/api/oxygen.js +0 -30
- package/dist/api/oxygen.js.map +0 -1
- package/dist/api/partners.js +0 -44
- package/dist/api/partners.js.map +0 -1
- package/dist/http/graphql.d.ts +0 -13
- package/dist/http/graphql.js +0 -12
- package/dist/http/graphql.js.map +0 -1
- package/dist/id.d.ts +0 -6
- package/dist/id.js +0 -18
- package/dist/id.js.map +0 -1
- package/dist/json.js.map +0 -1
- package/dist/os.d.ts +0 -10
- package/dist/os.js.map +0 -1
- package/dist/private/node/ui/components/Prompt.js +0 -23
- package/dist/private/node/ui/components/Prompt.js.map +0 -1
- package/dist/private/node/ui/components/Prompt.test.js.map +0 -1
- package/dist/string.d.ts +0 -28
- package/dist/string.js +0 -77
- package/dist/string.js.map +0 -1
- package/dist/template.js.map +0 -1
- package/dist/toml.d.ts +0 -3
- package/dist/toml.js +0 -8
- package/dist/toml.js.map +0 -1
- package/dist/vscode.d.ts +0 -8
- package/dist/vscode.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectPrompt.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/SelectPrompt.tsx"],"names":[],"mappings":"AAAA,OAAO,WAA6D,MAAM,kBAAkB,CAAA;AAC5F,OAAO,KAA4B,MAAM,YAAY,CAAA;AACrD,OAAO,EAAC,WAAW,EAAC,MAAM,aAAa,CAAA;AACvC,OAAO,KAAK,EAAE,EAAe,WAAW,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAA;AAChE,OAAO,EAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAC,MAAM,KAAK,CAAA;AAC1E,OAAO,EAAC,OAAO,EAAC,MAAM,QAAQ,CAAA;AAC9B,OAAO,WAAW,MAAM,cAAc,CAAA;AAStC,SAAS,YAAY,CAAI,EACvB,OAAO,EACP,OAAO,EACP,SAAS,EACT,QAAQ,GAC0B;IAClC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAgB,OAAO,CAAC,CAAC,CAAE,CAAC,CAAA;IAChE,MAAM,EAAC,IAAI,EAAE,UAAU,EAAC,GAAG,MAAM,EAAE,CAAA;IACnC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACjD,MAAM,EAAC,MAAM,EAAC,GAAG,SAAS,EAAE,CAAA;IAC5B,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;IAEvC,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,IAAI,EAAE,EAAE;QACvC,IAAI,IAAI,KAAK,IAAI,EAAE;YACjB,MAAM,EAAC,MAAM,EAAC,GAAG,cAAc,CAAC,IAAI,CAAC,CAAA;YACrC,SAAS,CAAC,MAAM,CAAC,CAAA;SAClB;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,QAAQ,CACN,WAAW,CACT,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACb,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAEvB,IAAI,GAAG,CAAC,MAAM,EAAE;YACd,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE;gBACnC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,CAAA;aACxC;YACD,YAAY,CAAC,IAAI,CAAC,CAAA;YAClB,UAAU,EAAE,CAAA;YACZ,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;SACvB;IACH,CAAC,EACD,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAC3B,CACF,CAAA;IAED,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,YAAY,EAAE,CAAC,EAAE,GAAG,EAAE,WAAW;QAC3D,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,SAAS,IAAI,CAC1B,oBAAC,GAAG,IAAC,UAAU,EAAE,CAAC;YAChB,oBAAC,KAAK,IAAC,KAAK,EAAE,SAAS,GAAI,CACvB,CACP;QACA,SAAS,CAAC,CAAC,CAAC,CACX,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,IAAa,EAAE,EAAE;gBAC1B,SAAS,CAAC,IAAI,CAAC,CAAA;YACjB,CAAC,GACD,CACH,CACG,CACP,CAAA;AACH,CAAC;AAED,OAAO,EAAC,YAAY,EAAC,CAAA","sourcesContent":["import SelectInput, {Props as SelectProps, Item as SelectItem, Item} from './SelectInput.js'\nimport Table, {Props as TableProps} from './Table.js'\nimport {handleCtrlC} from '../../ui.js'\nimport React, {ReactElement, useCallback, useState} from 'react'\nimport {Box, measureElement, Text, useApp, useInput, useStdout} from 'ink'\nimport {figures} from 'listr2'\nimport ansiEscapes from 'ansi-escapes'\n\nexport interface Props<T> {\n message: string\n choices: SelectProps<T>['items']\n onSubmit: (value: T) => void\n infoTable?: TableProps['table']\n}\n\nfunction SelectPrompt<T>({\n message,\n choices,\n infoTable,\n onSubmit,\n}: React.PropsWithChildren<Props<T>>): ReactElement | null {\n const [answer, setAnswer] = useState<SelectItem<T>>(choices[0]!)\n const {exit: unmountInk} = useApp()\n const [submitted, setSubmitted] = useState(false)\n const {stdout} = useStdout()\n const [height, setHeight] = useState(0)\n\n const measuredRef = useCallback((node) => {\n if (node !== null) {\n const {height} = measureElement(node)\n setHeight(height)\n }\n }, [])\n\n useInput(\n useCallback(\n (input, key) => {\n handleCtrlC(input, key)\n\n if (key.return) {\n if (stdout && height >= stdout.rows) {\n stdout.write(ansiEscapes.clearTerminal)\n }\n setSubmitted(true)\n unmountInk()\n onSubmit(answer.value)\n }\n },\n [answer, onSubmit, height],\n ),\n )\n\n return (\n <Box flexDirection=\"column\" marginBottom={1} ref={measuredRef}>\n <Box>\n <Box marginRight={2}>\n <Text>?</Text>\n </Box>\n <Text>{message}</Text>\n </Box>\n {infoTable && !submitted && (\n <Box marginLeft={7}>\n <Table table={infoTable} />\n </Box>\n )}\n {submitted ? (\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 onChange={(item: Item<T>) => {\n setAnswer(item)\n }}\n />\n )}\n </Box>\n )\n}\n\nexport {SelectPrompt}\n"]}
|
|
File without changes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { sendInput, waitForInputsToBeReady } from '../../../../testing/ui.js';
|
|
1
|
+
import { SelectPrompt } from './SelectPrompt.js';
|
|
2
|
+
import { getLastFrameAfterUnmount, sendInput, waitForInputsToBeReady } from '../../../../testing/ui.js';
|
|
3
3
|
import { describe, expect, test, vi } from 'vitest';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { render } from 'ink-testing-library';
|
|
@@ -14,11 +14,11 @@ describe('Prompt', async () => {
|
|
|
14
14
|
{ label: 'third', value: 'third' },
|
|
15
15
|
];
|
|
16
16
|
const infoTable = { Add: ['new-ext'], Remove: ['integrated-demand-ext', 'order-discount'] };
|
|
17
|
-
const renderInstance = render(React.createElement(
|
|
17
|
+
const renderInstance = render(React.createElement(SelectPrompt, { message: "Associate your project with the org Castile Ventures?", choices: items, infoTable: infoTable, onSubmit: onEnter }));
|
|
18
18
|
await waitForInputsToBeReady();
|
|
19
19
|
await sendInput(renderInstance, ARROW_DOWN);
|
|
20
20
|
await sendInput(renderInstance, ENTER);
|
|
21
|
-
expect(renderInstance
|
|
21
|
+
expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`
|
|
22
22
|
"? Associate your project with the org Castile Ventures?
|
|
23
23
|
[36m✔[39m [36msecond[39m
|
|
24
24
|
"
|
|
@@ -42,11 +42,12 @@ describe('Prompt', async () => {
|
|
|
42
42
|
Add: ['new-ext'],
|
|
43
43
|
Remove: ['integrated-demand-ext', 'order-discount'],
|
|
44
44
|
};
|
|
45
|
-
const renderInstance = render(React.createElement(
|
|
45
|
+
const renderInstance = render(React.createElement(SelectPrompt, { message: "Associate your project with the org Castile Ventures?", choices: items, infoTable: infoTable, onSubmit: () => { } }));
|
|
46
46
|
expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`
|
|
47
47
|
"? Associate your project with the org Castile Ventures?
|
|
48
48
|
|
|
49
49
|
Add: • new-ext
|
|
50
|
+
|
|
50
51
|
Remove: • integrated-demand-ext
|
|
51
52
|
• order-discount
|
|
52
53
|
|
|
@@ -70,4 +71,4 @@ describe('Prompt', async () => {
|
|
|
70
71
|
`);
|
|
71
72
|
});
|
|
72
73
|
});
|
|
73
|
-
//# sourceMappingURL=
|
|
74
|
+
//# sourceMappingURL=SelectPrompt.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectPrompt.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/SelectPrompt.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAC,wBAAwB,EAAE,SAAS,EAAE,sBAAsB,EAAC,MAAM,2BAA2B,CAAA;AACrG,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,YAAY,IACX,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,wBAAwB,CAAC,cAAc,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;KAItE,CAAC,CAAA;QAEF,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,CAAA;IACvD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,KAAK,GAAG;YACZ,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAC;YAC1C,EAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAC;YAC5C,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,EAAE,KAAK,EAAE,aAAa,EAAC;YACtD,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAC;YACtD,EAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAC;YACpC,EAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAC;YAC3D,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAC;YACzD,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAC;SACjC,CAAA;QAED,MAAM,SAAS,GAAG;YAChB,GAAG,EAAE,CAAC,SAAS,CAAC;YAChB,MAAM,EAAE,CAAC,uBAAuB,EAAE,gBAAgB,CAAC;SACpD,CAAA;QAED,MAAM,cAAc,GAAG,MAAM,CAC3B,oBAAC,YAAY,IACX,OAAO,EAAC,uDAAuD,EAC/D,OAAO,EAAE,KAAK,EACd,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,GAClB,CACH,CAAA;QAED,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;KAyBxD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {SelectPrompt} from './SelectPrompt.js'\nimport {getLastFrameAfterUnmount, 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 <SelectPrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n infoTable={infoTable}\n onSubmit={onEnter}\n />,\n )\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, ARROW_DOWN)\n await sendInput(renderInstance, ENTER)\n\n expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures?\n \u001b[36m✔\u001b[39m \u001b[36msecond\u001b[39m\n \"\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 <SelectPrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n infoTable={infoTable}\n onSubmit={() => {}}\n />,\n )\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures?\n\n Add: • new-ext\n\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"]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { List } from './List.js';
|
|
2
|
-
import { capitalize } from '../../../../string.js';
|
|
2
|
+
import { capitalize } from '../../../../public/common/string.js';
|
|
3
3
|
import { Box, Text } from 'ink';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
const Table = ({ table }) => {
|
|
6
6
|
const headers = Object.keys(table);
|
|
7
7
|
const headerColumnWidth = Math.max(...headers.map((header) => header.length));
|
|
8
|
-
return (React.createElement(Box, { flexDirection: "column", paddingY: 1 }, headers.map((header, index) => (React.createElement(Box, { key: index },
|
|
8
|
+
return (React.createElement(Box, { flexDirection: "column", paddingY: 1 }, headers.map((header, index) => (React.createElement(Box, { key: index, marginBottom: index === headers.length - 1 ? 0 : 1 },
|
|
9
9
|
React.createElement(Box, { width: headerColumnWidth + 1 },
|
|
10
10
|
React.createElement(Text, null,
|
|
11
11
|
capitalize(header),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Table.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Table.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAC,UAAU,EAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"Table.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Table.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAC,UAAU,EAAC,MAAM,qCAAqC,CAAA;AAC9D,OAAO,EAAC,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAA;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAA;AAQzB,MAAM,KAAK,GAAoB,CAAC,EAAC,KAAK,EAAC,EAAE,EAAE;IACzC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAClC,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IAE7E,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,IACpC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAC9B,oBAAC,GAAG,IAAC,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,oBAAC,GAAG,IAAC,KAAK,EAAE,iBAAiB,GAAG,CAAC;YAC/B,oBAAC,IAAI;gBAAE,UAAU,CAAC,MAAM,CAAC;oBAAS,CAC9B;QACN,oBAAC,GAAG,IAAC,QAAQ,EAAE,CAAC;YACd,oBAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAE,GAAI,CAC3B,CACF,CACP,CAAC,CACE,CACP,CAAA;AACH,CAAC,CAAA;AAED,eAAe,KAAK,CAAA","sourcesContent":["import {List} from './List.js'\nimport {capitalize} from '../../../../public/common/string.js'\nimport {Box, Text} from 'ink'\nimport React from 'react'\n\nexport interface Props {\n table: {\n [header: string]: string[]\n }\n}\n\nconst Table: React.FC<Props> = ({table}) => {\n const headers = Object.keys(table)\n const headerColumnWidth = Math.max(...headers.map((header) => header.length))\n\n return (\n <Box flexDirection=\"column\" paddingY={1}>\n {headers.map((header, index) => (\n <Box key={index} marginBottom={index === headers.length - 1 ? 0 : 1}>\n <Box width={headerColumnWidth + 1}>\n <Text>{capitalize(header)}:</Text>\n </Box>\n <Box flexGrow={1}>\n <List items={table[header]!} />\n </Box>\n </Box>\n ))}\n </Box>\n )\n}\n\nexport default Table\n"]}
|
|
@@ -5,8 +5,8 @@ import { Box, Text } from 'ink';
|
|
|
5
5
|
import React, { useState } from 'react';
|
|
6
6
|
const loadingBarChar = '█';
|
|
7
7
|
const Tasks = ({ tasks }) => {
|
|
8
|
-
const {
|
|
9
|
-
const loadingBar = new Array(
|
|
8
|
+
const { twoThirds } = useLayout();
|
|
9
|
+
const loadingBar = new Array(twoThirds).fill(loadingBarChar).join('');
|
|
10
10
|
const [currentTask, setCurrentTask] = useState(tasks[0]);
|
|
11
11
|
const [state, setState] = useState('loading');
|
|
12
12
|
const runTasks = async () => {
|
|
@@ -23,5 +23,5 @@ const Tasks = ({ tasks }) => {
|
|
|
23
23
|
currentTask.title,
|
|
24
24
|
state === 'loading' && ' ...')))));
|
|
25
25
|
};
|
|
26
|
-
export
|
|
26
|
+
export { Tasks };
|
|
27
27
|
//# sourceMappingURL=Tasks.js.map
|
|
@@ -1 +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,
|
|
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,SAAS,EAAC,GAAG,SAAS,EAAE,CAAA;IAC/B,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACrE,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,OAAO,EAAC,KAAK,EAAC,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 {twoThirds} = useLayout()\n const loadingBar = new Array(twoThirds).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 {Tasks}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import Tasks from './Tasks.js';
|
|
2
|
-
import {
|
|
1
|
+
import { Tasks } from './Tasks.js';
|
|
2
|
+
import { getLastFrameAfterUnmount } from '../../../../testing/ui.js';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { describe, expect, test } from 'vitest';
|
|
5
5
|
import { render } from 'ink-testing-library';
|
|
@@ -19,7 +19,7 @@ describe('Tasks', () => {
|
|
|
19
19
|
// wait for next tick
|
|
20
20
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
21
21
|
// Then
|
|
22
|
-
expect(
|
|
22
|
+
expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`
|
|
23
23
|
"[32m████████████████████████████████████████████████████████████████████████████████[39m
|
|
24
24
|
Complete!"
|
|
25
25
|
`);
|
|
@@ -41,7 +41,7 @@ describe('Tasks', () => {
|
|
|
41
41
|
// wait for next tick
|
|
42
42
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
43
43
|
// Then
|
|
44
|
-
expect(
|
|
44
|
+
expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`
|
|
45
45
|
"[31m████████████████████████████████████████████████████████████████████████████████[39m
|
|
46
46
|
task 1"
|
|
47
47
|
`);
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"Tasks.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Tasks.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,YAAY,CAAA;AAChC,OAAO,EAAC,wBAAwB,EAAC,MAAM,2BAA2B,CAAA;AAClE,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,wBAAwB,CAAC,cAAc,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;KAGtE,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,wBAAwB,CAAC,cAAc,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;KAGtE,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {Tasks} from './Tasks.js'\nimport {getLastFrameAfterUnmount} 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(getLastFrameAfterUnmount(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(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`\n \"\u001b[31m████████████████████████████████████████████████████████████████████████████████\u001b[39m\n task 1\"\n `)\n })\n})\n"]}
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,OAA4B,CAAC,CAAA;QACpD,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 as unknown as number)\n }\n }, [])\n\n return <Text>{renderedFrame}</Text>\n}\n\nexport {TextAnimation}\n"]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/* eslint-disable no-nested-ternary */
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
import { Text, useInput } from 'ink';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
const TextInput = ({ value, placeholder = '', onChange, color = 'cyan' }) => {
|
|
7
|
+
const [cursorOffset, setCursorOffset] = useState((value || '').length);
|
|
8
|
+
// if the updated value is shorter than the last one we need to reset the cursor
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
setCursorOffset((previousOffset) => {
|
|
11
|
+
const newValue = value || '';
|
|
12
|
+
if (previousOffset > newValue.length - 1) {
|
|
13
|
+
return newValue.length;
|
|
14
|
+
}
|
|
15
|
+
return previousOffset;
|
|
16
|
+
});
|
|
17
|
+
}, [value]);
|
|
18
|
+
let renderedValue = value.length > 0 ? '' : chalk.inverse(' ');
|
|
19
|
+
const renderedPlaceholder = placeholder.length > 0 ? chalk.inverse(placeholder[0]) + chalk.dim(placeholder.slice(1)) : undefined;
|
|
20
|
+
// render cursor
|
|
21
|
+
renderedValue = value
|
|
22
|
+
.split('')
|
|
23
|
+
.map((char, index) => {
|
|
24
|
+
if (index === cursorOffset) {
|
|
25
|
+
return chalk.inverse(char);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
return char;
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
.join('');
|
|
32
|
+
if (cursorOffset === value.length) {
|
|
33
|
+
renderedValue += chalk.inverse(' ');
|
|
34
|
+
}
|
|
35
|
+
useInput((input, key) => {
|
|
36
|
+
if (key.upArrow ||
|
|
37
|
+
key.downArrow ||
|
|
38
|
+
(key.ctrl && input === 'c') ||
|
|
39
|
+
key.tab ||
|
|
40
|
+
(key.shift && key.tab) ||
|
|
41
|
+
key.return) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
let nextCursorOffset = cursorOffset;
|
|
45
|
+
let nextValue = value;
|
|
46
|
+
if (key.leftArrow) {
|
|
47
|
+
if (cursorOffset > 0) {
|
|
48
|
+
nextCursorOffset--;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else if (key.rightArrow) {
|
|
52
|
+
if (cursorOffset < value.length) {
|
|
53
|
+
nextCursorOffset++;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else if (key.backspace || key.delete) {
|
|
57
|
+
if (cursorOffset > 0) {
|
|
58
|
+
nextValue = value.slice(0, cursorOffset - 1) + value.slice(cursorOffset, value.length);
|
|
59
|
+
nextCursorOffset--;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
nextValue = value.slice(0, cursorOffset) + input + value.slice(cursorOffset, value.length);
|
|
64
|
+
nextCursorOffset += input.length;
|
|
65
|
+
}
|
|
66
|
+
setCursorOffset(nextCursorOffset);
|
|
67
|
+
if (nextValue !== value) {
|
|
68
|
+
onChange(nextValue);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return (React.createElement(Text, { color: color }, placeholder ? (value.length > 0 ? renderedValue : renderedPlaceholder) : renderedValue));
|
|
72
|
+
};
|
|
73
|
+
export { TextInput };
|
|
74
|
+
//# sourceMappingURL=TextInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TextInput.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/TextInput.tsx"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-nested-ternary */\nimport * as React from 'react'\nimport {useEffect, useState} from 'react'\nimport {Text, useInput} from 'ink'\nimport chalk from 'chalk'\nimport type {FC} from 'react'\n\ninterface Props {\n placeholder?: string\n value: string\n onChange: (value: string) => void\n color?: string\n}\n\nconst TextInput: FC<Props> = ({value, placeholder = '', onChange, color = 'cyan'}) => {\n const [cursorOffset, setCursorOffset] = useState((value || '').length)\n\n // if the updated value is shorter than the last one we need to reset the cursor\n useEffect(() => {\n setCursorOffset((previousOffset) => {\n const newValue = value || ''\n\n if (previousOffset > newValue.length - 1) {\n return newValue.length\n }\n\n return previousOffset\n })\n }, [value])\n\n let renderedValue = value.length > 0 ? '' : chalk.inverse(' ')\n const renderedPlaceholder =\n placeholder.length > 0 ? chalk.inverse(placeholder[0]) + chalk.dim(placeholder.slice(1)) : undefined\n\n // render cursor\n renderedValue = value\n .split('')\n .map((char, index) => {\n if (index === cursorOffset) {\n return chalk.inverse(char)\n } else {\n return char\n }\n })\n .join('')\n\n if (cursorOffset === value.length) {\n renderedValue += chalk.inverse(' ')\n }\n\n useInput((input, key) => {\n if (\n key.upArrow ||\n key.downArrow ||\n (key.ctrl && input === 'c') ||\n key.tab ||\n (key.shift && key.tab) ||\n key.return\n ) {\n return\n }\n\n let nextCursorOffset = cursorOffset\n let nextValue = value\n\n if (key.leftArrow) {\n if (cursorOffset > 0) {\n nextCursorOffset--\n }\n } else if (key.rightArrow) {\n if (cursorOffset < value.length) {\n nextCursorOffset++\n }\n } else if (key.backspace || key.delete) {\n if (cursorOffset > 0) {\n nextValue = value.slice(0, cursorOffset - 1) + value.slice(cursorOffset, value.length)\n nextCursorOffset--\n }\n } else {\n nextValue = value.slice(0, cursorOffset) + input + value.slice(cursorOffset, value.length)\n nextCursorOffset += input.length\n }\n\n setCursorOffset(nextCursorOffset)\n\n if (nextValue !== value) {\n onChange(nextValue)\n }\n })\n\n return (\n <Text color={color}>{placeholder ? (value.length > 0 ? renderedValue : renderedPlaceholder) : renderedValue}</Text>\n )\n}\n\nexport {TextInput}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { TextInput } from './TextInput.js';
|
|
2
|
+
import { sendInput, waitForChange, waitForInputsToBeReady } from '../../../../testing/ui.js';
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
import { describe, test, expect, vi } from 'vitest';
|
|
5
|
+
import { render } from 'ink-testing-library';
|
|
6
|
+
const ARROW_LEFT = '\u001B[D';
|
|
7
|
+
const ARROW_RIGHT = '\u001B[C';
|
|
8
|
+
const DELETE = '\u007F';
|
|
9
|
+
describe('TextInput', () => {
|
|
10
|
+
test('default state', () => {
|
|
11
|
+
const { lastFrame } = render(React.createElement(TextInput, { value: "", onChange: () => { } }));
|
|
12
|
+
// inverted space escape sequence
|
|
13
|
+
expect(lastFrame()).toMatchInlineSnapshot('"[36m[7m [27m[39m"');
|
|
14
|
+
});
|
|
15
|
+
test('displays value with cursor', () => {
|
|
16
|
+
const { lastFrame } = render(React.createElement(TextInput, { value: "Hello", onChange: () => { } }));
|
|
17
|
+
// inverted space escape sequence after Hello
|
|
18
|
+
expect(lastFrame()).toMatchInlineSnapshot('"[36mHello[7m [27m[39m"');
|
|
19
|
+
});
|
|
20
|
+
test('displays placeholder', () => {
|
|
21
|
+
const { lastFrame } = render(React.createElement(TextInput, { value: "", placeholder: "Placeholder", onChange: () => { } }));
|
|
22
|
+
// inverted escape sequence around "P", laceholder after that
|
|
23
|
+
expect(lastFrame()).toMatchInlineSnapshot('"[36m[7mP[27m[2mlaceholder[22m[39m"');
|
|
24
|
+
});
|
|
25
|
+
test('moves the cursor with arrows', async () => {
|
|
26
|
+
const renderInstance = render(React.createElement(TextInput, { value: "Hello", onChange: () => { } }));
|
|
27
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mHello[7m [27m[39m"');
|
|
28
|
+
await waitForInputsToBeReady();
|
|
29
|
+
await sendInput(renderInstance, ARROW_LEFT);
|
|
30
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mHell[7mo[27m[39m"');
|
|
31
|
+
await sendInput(renderInstance, ARROW_LEFT);
|
|
32
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mHel[7ml[27mo[39m"');
|
|
33
|
+
await sendInput(renderInstance, ARROW_LEFT);
|
|
34
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mHe[7ml[27mlo[39m"');
|
|
35
|
+
await sendInput(renderInstance, ARROW_LEFT);
|
|
36
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mH[7me[27mllo[39m"');
|
|
37
|
+
await sendInput(renderInstance, ARROW_LEFT);
|
|
38
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36m[7mH[27mello[39m"');
|
|
39
|
+
// cursor can't go before the first character
|
|
40
|
+
renderInstance.stdin.write(ARROW_LEFT);
|
|
41
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
42
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36m[7mH[27mello[39m"');
|
|
43
|
+
await sendInput(renderInstance, ARROW_RIGHT);
|
|
44
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mH[7me[27mllo[39m"');
|
|
45
|
+
await sendInput(renderInstance, ARROW_RIGHT);
|
|
46
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mHe[7ml[27mlo[39m"');
|
|
47
|
+
await sendInput(renderInstance, ARROW_RIGHT);
|
|
48
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mHel[7ml[27mo[39m"');
|
|
49
|
+
await sendInput(renderInstance, ARROW_RIGHT);
|
|
50
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mHell[7mo[27m[39m"');
|
|
51
|
+
await sendInput(renderInstance, ARROW_RIGHT);
|
|
52
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mHello[7m [27m[39m"');
|
|
53
|
+
// cursor can't go after the last character
|
|
54
|
+
renderInstance.stdin.write(ARROW_RIGHT);
|
|
55
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
56
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mHello[7m [27m[39m"');
|
|
57
|
+
});
|
|
58
|
+
test('moves the cursor when deleting', async () => {
|
|
59
|
+
const StatefulTextInput = () => {
|
|
60
|
+
const [value, setValue] = useState('Hello');
|
|
61
|
+
return React.createElement(TextInput, { value: value, onChange: setValue });
|
|
62
|
+
};
|
|
63
|
+
const renderInstance = render(React.createElement(StatefulTextInput, null));
|
|
64
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mHello[7m [27m[39m"');
|
|
65
|
+
await waitForInputsToBeReady();
|
|
66
|
+
await sendInput(renderInstance, DELETE);
|
|
67
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mHell[7m [27m[39m"');
|
|
68
|
+
await sendInput(renderInstance, DELETE);
|
|
69
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mHel[7m [27m[39m"');
|
|
70
|
+
await sendInput(renderInstance, DELETE);
|
|
71
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mHe[7m [27m[39m"');
|
|
72
|
+
await sendInput(renderInstance, DELETE);
|
|
73
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mH[7m [27m[39m"');
|
|
74
|
+
await sendInput(renderInstance, DELETE);
|
|
75
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36m[7m [27m[39m"');
|
|
76
|
+
// cannot delete after the value has been cleared
|
|
77
|
+
renderInstance.stdin.write(DELETE);
|
|
78
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
79
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36m[7m [27m[39m"');
|
|
80
|
+
});
|
|
81
|
+
test('accepts input', async () => {
|
|
82
|
+
const StatefulTextInput = () => {
|
|
83
|
+
const [value, setValue] = useState('');
|
|
84
|
+
return React.createElement(TextInput, { value: value, onChange: setValue });
|
|
85
|
+
};
|
|
86
|
+
const renderInstance = render(React.createElement(StatefulTextInput, null));
|
|
87
|
+
await waitForInputsToBeReady();
|
|
88
|
+
await sendInput(renderInstance, 'H');
|
|
89
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mH[7m [27m[39m"');
|
|
90
|
+
await sendInput(renderInstance, 'ello');
|
|
91
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mHello[7m [27m[39m"');
|
|
92
|
+
});
|
|
93
|
+
test('onChange', async () => {
|
|
94
|
+
const onChange = vi.fn();
|
|
95
|
+
const renderInstance = render(React.createElement(TextInput, { value: "", onChange: onChange }));
|
|
96
|
+
await waitForInputsToBeReady();
|
|
97
|
+
await sendInput(renderInstance, 'X');
|
|
98
|
+
expect(onChange).toHaveBeenCalledWith('X');
|
|
99
|
+
});
|
|
100
|
+
test('deletes at the beginning and in the middle of text', async () => {
|
|
101
|
+
const StatefulTextInput = () => {
|
|
102
|
+
const [value, setValue] = useState('');
|
|
103
|
+
return React.createElement(TextInput, { value: value, onChange: setValue });
|
|
104
|
+
};
|
|
105
|
+
const renderInstance = render(React.createElement(StatefulTextInput, null));
|
|
106
|
+
await waitForInputsToBeReady();
|
|
107
|
+
await sendInput(renderInstance, 'T');
|
|
108
|
+
await sendInput(renderInstance, 'e');
|
|
109
|
+
await sendInput(renderInstance, 's');
|
|
110
|
+
await sendInput(renderInstance, 't');
|
|
111
|
+
await sendInput(renderInstance, ARROW_LEFT);
|
|
112
|
+
await sendInput(renderInstance, DELETE);
|
|
113
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mTe[7mt[27m[39m"');
|
|
114
|
+
await sendInput(renderInstance, ARROW_LEFT);
|
|
115
|
+
await sendInput(renderInstance, ARROW_LEFT);
|
|
116
|
+
renderInstance.stdin.write(DELETE);
|
|
117
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
118
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36m[7mT[27met[39m"');
|
|
119
|
+
});
|
|
120
|
+
test('adjusts cursor when text is shorter than last value', async () => {
|
|
121
|
+
let resetValue = () => { };
|
|
122
|
+
const StatefulTextInput = () => {
|
|
123
|
+
const [value, setValue] = useState('');
|
|
124
|
+
resetValue = () => setValue('');
|
|
125
|
+
return React.createElement(TextInput, { value: value, onChange: setValue });
|
|
126
|
+
};
|
|
127
|
+
const renderInstance = render(React.createElement(StatefulTextInput, null));
|
|
128
|
+
await waitForInputsToBeReady();
|
|
129
|
+
await sendInput(renderInstance, 'A');
|
|
130
|
+
await sendInput(renderInstance, 'B');
|
|
131
|
+
await waitForChange(resetValue, renderInstance.lastFrame);
|
|
132
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36m[7m [27m[39m"');
|
|
133
|
+
await sendInput(renderInstance, 'A');
|
|
134
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mA[7m [27m[39m"');
|
|
135
|
+
await sendInput(renderInstance, 'B');
|
|
136
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot('"[36mAB[7m [27m[39m"');
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
//# sourceMappingURL=TextInput.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TextInput.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/TextInput.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import {TextInput} from './TextInput.js'\nimport {sendInput, waitForChange, waitForInputsToBeReady} from '../../../../testing/ui.js'\nimport React, {useState} from 'react'\nimport {describe, test, expect, vi} from 'vitest'\nimport {render} from 'ink-testing-library'\n\nconst ARROW_LEFT = '\\u001B[D'\nconst ARROW_RIGHT = '\\u001B[C'\nconst DELETE = '\\u007F'\n\ndescribe('TextInput', () => {\n test('default state', () => {\n const {lastFrame} = render(<TextInput value=\"\" onChange={() => {}} />)\n\n // inverted space escape sequence\n expect(lastFrame()).toMatchInlineSnapshot('\"\u001b[36m\u001b[7m \u001b[27m\u001b[39m\"')\n })\n\n test('displays value with cursor', () => {\n const {lastFrame} = render(<TextInput value=\"Hello\" onChange={() => {}} />)\n\n // inverted space escape sequence after Hello\n expect(lastFrame()).toMatchInlineSnapshot('\"\u001b[36mHello\u001b[7m \u001b[27m\u001b[39m\"')\n })\n\n test('displays placeholder', () => {\n const {lastFrame} = render(<TextInput value=\"\" placeholder=\"Placeholder\" onChange={() => {}} />)\n\n // inverted escape sequence around \"P\", laceholder after that\n expect(lastFrame()).toMatchInlineSnapshot('\"\u001b[36m\u001b[7mP\u001b[27m\u001b[2mlaceholder\u001b[22m\u001b[39m\"')\n })\n\n test('moves the cursor with arrows', async () => {\n const renderInstance = render(<TextInput value=\"Hello\" onChange={() => {}} />)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mHello\u001b[7m \u001b[27m\u001b[39m\"')\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, ARROW_LEFT)\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mHell\u001b[7mo\u001b[27m\u001b[39m\"')\n await sendInput(renderInstance, ARROW_LEFT)\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mHel\u001b[7ml\u001b[27mo\u001b[39m\"')\n await sendInput(renderInstance, ARROW_LEFT)\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mHe\u001b[7ml\u001b[27mlo\u001b[39m\"')\n await sendInput(renderInstance, ARROW_LEFT)\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mH\u001b[7me\u001b[27mllo\u001b[39m\"')\n await sendInput(renderInstance, ARROW_LEFT)\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36m\u001b[7mH\u001b[27mello\u001b[39m\"')\n // cursor can't go before the first character\n renderInstance.stdin.write(ARROW_LEFT)\n await new Promise((resolve) => setTimeout(resolve, 100))\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36m\u001b[7mH\u001b[27mello\u001b[39m\"')\n\n await sendInput(renderInstance, ARROW_RIGHT)\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mH\u001b[7me\u001b[27mllo\u001b[39m\"')\n await sendInput(renderInstance, ARROW_RIGHT)\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mHe\u001b[7ml\u001b[27mlo\u001b[39m\"')\n await sendInput(renderInstance, ARROW_RIGHT)\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mHel\u001b[7ml\u001b[27mo\u001b[39m\"')\n await sendInput(renderInstance, ARROW_RIGHT)\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mHell\u001b[7mo\u001b[27m\u001b[39m\"')\n await sendInput(renderInstance, ARROW_RIGHT)\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mHello\u001b[7m \u001b[27m\u001b[39m\"')\n // cursor can't go after the last character\n renderInstance.stdin.write(ARROW_RIGHT)\n await new Promise((resolve) => setTimeout(resolve, 100))\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mHello\u001b[7m \u001b[27m\u001b[39m\"')\n })\n\n test('moves the cursor when deleting', async () => {\n const StatefulTextInput = () => {\n const [value, setValue] = useState('Hello')\n\n return <TextInput value={value} onChange={setValue} />\n }\n\n const renderInstance = render(<StatefulTextInput />)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mHello\u001b[7m \u001b[27m\u001b[39m\"')\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, DELETE)\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mHell\u001b[7m \u001b[27m\u001b[39m\"')\n await sendInput(renderInstance, DELETE)\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mHel\u001b[7m \u001b[27m\u001b[39m\"')\n await sendInput(renderInstance, DELETE)\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mHe\u001b[7m \u001b[27m\u001b[39m\"')\n await sendInput(renderInstance, DELETE)\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mH\u001b[7m \u001b[27m\u001b[39m\"')\n await sendInput(renderInstance, DELETE)\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36m\u001b[7m \u001b[27m\u001b[39m\"')\n // cannot delete after the value has been cleared\n renderInstance.stdin.write(DELETE)\n await new Promise((resolve) => setTimeout(resolve, 100))\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36m\u001b[7m \u001b[27m\u001b[39m\"')\n })\n\n test('accepts input', async () => {\n const StatefulTextInput = () => {\n const [value, setValue] = useState('')\n\n return <TextInput value={value} onChange={setValue} />\n }\n\n const renderInstance = render(<StatefulTextInput />)\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, 'H')\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mH\u001b[7m \u001b[27m\u001b[39m\"')\n await sendInput(renderInstance, 'ello')\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mHello\u001b[7m \u001b[27m\u001b[39m\"')\n })\n\n test('onChange', async () => {\n const onChange = vi.fn()\n\n const renderInstance = render(<TextInput value=\"\" onChange={onChange} />)\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, 'X')\n\n expect(onChange).toHaveBeenCalledWith('X')\n })\n\n test('deletes at the beginning and in the middle of text', async () => {\n const StatefulTextInput = () => {\n const [value, setValue] = useState('')\n\n return <TextInput value={value} onChange={setValue} />\n }\n\n const renderInstance = render(<StatefulTextInput />)\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, 'T')\n await sendInput(renderInstance, 'e')\n await sendInput(renderInstance, 's')\n await sendInput(renderInstance, 't')\n await sendInput(renderInstance, ARROW_LEFT)\n await sendInput(renderInstance, DELETE)\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mTe\u001b[7mt\u001b[27m\u001b[39m\"')\n await sendInput(renderInstance, ARROW_LEFT)\n await sendInput(renderInstance, ARROW_LEFT)\n renderInstance.stdin.write(DELETE)\n await new Promise((resolve) => setTimeout(resolve, 100))\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36m\u001b[7mT\u001b[27met\u001b[39m\"')\n })\n\n test('adjusts cursor when text is shorter than last value', async () => {\n let resetValue = () => {}\n\n const StatefulTextInput = () => {\n const [value, setValue] = useState('')\n resetValue = () => setValue('')\n\n return <TextInput value={value} onChange={setValue} />\n }\n\n const renderInstance = render(<StatefulTextInput />)\n\n await waitForInputsToBeReady()\n await sendInput(renderInstance, 'A')\n await sendInput(renderInstance, 'B')\n\n await waitForChange(resetValue, renderInstance.lastFrame)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36m\u001b[7m \u001b[27m\u001b[39m\"')\n await sendInput(renderInstance, 'A')\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mA\u001b[7m \u001b[27m\u001b[39m\"')\n await sendInput(renderInstance, 'B')\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot('\"\u001b[36mAB\u001b[7m \u001b[27m\u001b[39m\"')\n })\n})\n"]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { TextInput } from './TextInput.js';
|
|
2
|
+
import { handleCtrlC } from '../../ui.js';
|
|
3
|
+
import useLayout from '../hooks/use-layout.js';
|
|
4
|
+
import React, { useCallback, useState } from 'react';
|
|
5
|
+
import { Box, useApp, useInput, Text } from 'ink';
|
|
6
|
+
import { figures } from 'listr2';
|
|
7
|
+
const TextPrompt = ({ message, onSubmit, placeholder }) => {
|
|
8
|
+
const { oneThird } = useLayout();
|
|
9
|
+
const [answer, setAnswer] = useState('');
|
|
10
|
+
const { exit: unmountInk } = useApp();
|
|
11
|
+
const [submitted, setSubmitted] = useState(false);
|
|
12
|
+
const [valid, setValid] = useState(false);
|
|
13
|
+
const underline = new Array(oneThird - 3).fill('▔');
|
|
14
|
+
useInput(useCallback((input, key) => {
|
|
15
|
+
handleCtrlC(input, key);
|
|
16
|
+
if (key.return) {
|
|
17
|
+
setSubmitted(true);
|
|
18
|
+
if (valid) {
|
|
19
|
+
onSubmit(answer);
|
|
20
|
+
unmountInk();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}, [answer, onSubmit, valid]));
|
|
24
|
+
const shouldShowError = submitted && !valid;
|
|
25
|
+
const color = shouldShowError ? 'red' : 'cyan';
|
|
26
|
+
const error = shouldShowError ? 'Please enter a value' : undefined;
|
|
27
|
+
return (React.createElement(Box, { flexDirection: "column", marginBottom: 1, width: oneThird },
|
|
28
|
+
React.createElement(Box, null,
|
|
29
|
+
React.createElement(Box, { marginRight: 2 },
|
|
30
|
+
React.createElement(Text, null, "?")),
|
|
31
|
+
React.createElement(Text, null, message)),
|
|
32
|
+
submitted && valid ? (React.createElement(Box, null,
|
|
33
|
+
React.createElement(Box, { marginRight: 2 },
|
|
34
|
+
React.createElement(Text, { color: "cyan" }, figures.tick)),
|
|
35
|
+
React.createElement(Box, { flexGrow: 1 },
|
|
36
|
+
React.createElement(Text, { color: "cyan" }, answer)))) : (React.createElement(Box, { flexDirection: "column" },
|
|
37
|
+
React.createElement(Box, null,
|
|
38
|
+
React.createElement(Box, { marginRight: 2 },
|
|
39
|
+
React.createElement(Text, { color: color }, `>`)),
|
|
40
|
+
React.createElement(Box, { flexGrow: 1 },
|
|
41
|
+
React.createElement(TextInput, { value: answer, onChange: (answer) => {
|
|
42
|
+
setAnswer(answer);
|
|
43
|
+
setValid(answer.length > 0);
|
|
44
|
+
setSubmitted(false);
|
|
45
|
+
}, placeholder: placeholder, color: color }))),
|
|
46
|
+
React.createElement(Box, { marginLeft: 3 },
|
|
47
|
+
React.createElement(Text, { color: color }, underline)),
|
|
48
|
+
error && (React.createElement(Box, { marginLeft: 3 },
|
|
49
|
+
React.createElement(Text, { color: color }, error)))))));
|
|
50
|
+
};
|
|
51
|
+
export { TextPrompt };
|
|
52
|
+
//# sourceMappingURL=TextPrompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TextPrompt.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/TextPrompt.tsx"],"names":[],"mappings":"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","sourcesContent":["import {TextInput} from './TextInput.js'\nimport {handleCtrlC} from '../../ui.js'\nimport useLayout from '../hooks/use-layout.js'\nimport React, {useCallback, useState} from 'react'\nimport {Box, useApp, useInput, Text} from 'ink'\nimport {figures} from 'listr2'\n\nexport interface Props {\n message: string\n onSubmit: (value: string) => void\n placeholder?: string\n}\n\nconst TextPrompt: React.FC<Props> = ({message, onSubmit, placeholder}) => {\n const {oneThird} = useLayout()\n const [answer, setAnswer] = useState<string>('')\n const {exit: unmountInk} = useApp()\n const [submitted, setSubmitted] = useState(false)\n const [valid, setValid] = useState(false)\n const underline = new Array(oneThird - 3).fill('▔')\n\n useInput(\n useCallback(\n (input, key) => {\n handleCtrlC(input, key)\n\n if (key.return) {\n setSubmitted(true)\n\n if (valid) {\n onSubmit(answer)\n unmountInk()\n }\n }\n },\n [answer, onSubmit, valid],\n ),\n )\n\n const shouldShowError = submitted && !valid\n const color = shouldShowError ? 'red' : 'cyan'\n const error = shouldShowError ? 'Please enter a value' : undefined\n\n return (\n <Box flexDirection=\"column\" marginBottom={1} width={oneThird}>\n <Box>\n <Box marginRight={2}>\n <Text>?</Text>\n </Box>\n <Text>{message}</Text>\n </Box>\n {submitted && valid ? (\n <Box>\n <Box marginRight={2}>\n <Text color=\"cyan\">{figures.tick}</Text>\n </Box>\n\n <Box flexGrow={1}>\n <Text color=\"cyan\">{answer}</Text>\n </Box>\n </Box>\n ) : (\n <Box flexDirection=\"column\">\n <Box>\n <Box marginRight={2}>\n <Text color={color}>{`>`}</Text>\n </Box>\n <Box flexGrow={1}>\n <TextInput\n value={answer}\n onChange={(answer) => {\n setAnswer(answer)\n setValid(answer.length > 0)\n setSubmitted(false)\n }}\n placeholder={placeholder}\n color={color}\n />\n </Box>\n </Box>\n <Box marginLeft={3}>\n <Text color={color}>{underline}</Text>\n </Box>\n {error && (\n <Box marginLeft={3}>\n <Text color={color}>{error}</Text>\n </Box>\n )}\n </Box>\n )}\n </Box>\n )\n}\n\nexport {TextPrompt}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|