@shopify/cli-kit 3.37.0 → 3.39.0
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/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/private/common/json.d.ts +2 -2
- package/dist/private/common/lodash.d.ts +4 -4
- package/dist/private/common/ts/overloaded-parameters.d.ts +5 -5
- package/dist/private/node/api/graphql.js +7 -7
- package/dist/private/node/api/graphql.js.map +1 -1
- package/dist/private/node/api/headers.d.ts +1 -1
- package/dist/private/node/api.d.ts +2 -0
- package/dist/{network → private/node}/api.js +0 -0
- package/dist/private/node/api.js.map +1 -0
- package/dist/private/node/conf-store.js +4 -4
- package/dist/private/node/conf-store.js.map +1 -1
- package/dist/private/node/constants.d.ts +2 -2
- package/dist/{content-tokens.d.ts → private/node/content-tokens.d.ts} +11 -11
- package/dist/{content-tokens.js → private/node/content-tokens.js} +3 -3
- package/dist/private/node/content-tokens.js.map +1 -0
- package/dist/private/node/environment/service.d.ts +1 -1
- package/dist/private/node/error-handler.d.ts +2 -0
- package/dist/private/node/error-handler.js +5 -0
- package/dist/private/node/error-handler.js.map +1 -0
- package/dist/private/node/secure-store.js +4 -4
- package/dist/private/node/secure-store.js.map +1 -1
- package/dist/private/node/session/authorize.js +3 -3
- package/dist/private/node/session/authorize.js.map +1 -1
- package/dist/private/node/session/device-authorization.js +6 -6
- package/dist/private/node/session/device-authorization.js.map +1 -1
- package/dist/private/node/session/exchange.d.ts +1 -1
- package/dist/private/node/session/exchange.js.map +1 -1
- package/dist/private/node/session/identity-token-validation.js +5 -5
- package/dist/private/node/session/identity-token-validation.js.map +1 -1
- package/dist/private/node/session/identity.d.ts +1 -1
- package/dist/private/node/session/identity.js.map +1 -1
- package/dist/private/node/session/redirect-listener.d.ts +1 -1
- package/dist/private/node/session/redirect-listener.js +7 -7
- package/dist/private/node/session/redirect-listener.js.map +1 -1
- package/dist/private/node/session/schema.d.ts +3 -3
- package/dist/private/node/session/scopes.d.ts +1 -1
- package/dist/private/node/session/scopes.js +1 -1
- package/dist/private/node/session/scopes.js.map +1 -1
- package/dist/private/node/session/store.js +4 -4
- package/dist/private/node/session/store.js.map +1 -1
- package/dist/private/node/session/validate.d.ts +1 -1
- package/dist/private/node/session/validate.js +2 -2
- package/dist/private/node/session/validate.js.map +1 -1
- package/dist/private/node/session.d.ts +4 -4
- package/dist/private/node/session.js +19 -19
- package/dist/private/node/session.js.map +1 -1
- package/dist/private/node/ui/alert.js +1 -1
- package/dist/private/node/ui/alert.js.map +1 -1
- package/dist/private/node/ui/components/Alert.test.js +1 -1
- package/dist/private/node/ui/components/Alert.test.js.map +1 -1
- package/dist/private/node/ui/components/AutocompletePrompt.d.ts +9 -2
- package/dist/private/node/ui/components/AutocompletePrompt.js +8 -4
- package/dist/private/node/ui/components/AutocompletePrompt.js.map +1 -1
- package/dist/private/node/ui/components/AutocompletePrompt.test.js +62 -8
- package/dist/private/node/ui/components/AutocompletePrompt.test.js.map +1 -1
- package/dist/private/node/ui/components/Banner.d.ts +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.d.ts +3 -3
- package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.test.js +1 -1
- package/dist/private/node/ui/components/ConcurrentOutput.test.js.map +1 -1
- package/dist/private/node/ui/components/FatalError.test.js +1 -1
- package/dist/private/node/ui/components/FatalError.test.js.map +1 -1
- package/dist/private/node/ui/components/List.test.js +1 -1
- package/dist/private/node/ui/components/List.test.js.map +1 -1
- package/dist/private/node/ui/components/SelectInput.d.ts +3 -1
- package/dist/private/node/ui/components/SelectInput.js +8 -2
- package/dist/private/node/ui/components/SelectInput.js.map +1 -1
- package/dist/private/node/ui/components/SelectInput.test.js +26 -0
- package/dist/private/node/ui/components/SelectInput.test.js.map +1 -1
- package/dist/private/node/ui/components/SelectPrompt.test.js +1 -1
- package/dist/private/node/ui/components/SelectPrompt.test.js.map +1 -1
- package/dist/private/node/ui/components/Table/Row.d.ts +1 -1
- package/dist/private/node/ui/components/Table/ScalarDict.d.ts +1 -1
- package/dist/private/node/ui/components/Table/Table.d.ts +1 -1
- package/dist/private/node/ui/components/Tasks.d.ts +5 -1
- package/dist/private/node/ui/components/Tasks.js +31 -6
- package/dist/private/node/ui/components/Tasks.js.map +1 -1
- package/dist/private/node/ui/components/Tasks.test.js +260 -20
- package/dist/private/node/ui/components/Tasks.test.js.map +1 -1
- package/dist/private/node/ui/components/TextPrompt.test.js +1 -1
- package/dist/private/node/ui/components/TextPrompt.test.js.map +1 -1
- package/dist/private/node/ui/components/TokenizedText.d.ts +2 -2
- 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.d.ts +2 -2
- package/dist/private/node/ui.js +1 -1
- package/dist/private/node/ui.js.map +1 -1
- package/dist/public/common/string.d.ts +1 -1
- package/dist/public/common/string.js +1 -1
- package/dist/public/common/string.js.map +1 -1
- package/dist/{private → public}/common/ts/deep-required.d.ts +2 -1
- package/dist/{private → public}/common/ts/deep-required.js +0 -0
- package/dist/public/common/ts/deep-required.js.map +1 -0
- package/dist/public/common/ts/pick-by-prefix.d.ts +2 -1
- package/dist/public/common/ts/pick-by-prefix.js.map +1 -1
- package/dist/public/common/version.d.ts +1 -1
- package/dist/public/common/version.js +1 -1
- package/dist/public/common/version.js.map +1 -1
- package/dist/public/node/analytics.js +5 -5
- package/dist/public/node/analytics.js.map +1 -1
- package/dist/public/node/api/admin.js +2 -2
- package/dist/public/node/api/admin.js.map +1 -1
- package/dist/public/node/api/http.d.ts +1 -0
- package/dist/public/node/api/http.js +1 -1
- package/dist/public/node/archiver.d.ts +20 -6
- package/dist/public/node/archiver.js +16 -15
- package/dist/public/node/archiver.js.map +1 -1
- package/dist/public/node/base-command.js +4 -4
- package/dist/public/node/base-command.js.map +1 -1
- package/dist/public/node/crypto.d.ts +1 -1
- package/dist/public/node/dot-env.js +4 -2
- package/dist/public/node/dot-env.js.map +1 -1
- package/dist/public/node/environment/local.d.ts +1 -1
- package/dist/public/node/environment/spin.d.ts +1 -1
- package/dist/public/node/environment/spin.js +2 -2
- package/dist/public/node/environment/spin.js.map +1 -1
- package/dist/public/node/error-handler.d.ts +1 -2
- package/dist/public/node/error-handler.js +15 -5
- package/dist/public/node/error-handler.js.map +1 -1
- package/dist/public/node/error.d.ts +5 -5
- package/dist/public/node/error.js +1 -1
- package/dist/public/node/error.js.map +1 -1
- package/dist/public/node/fs.d.ts +24 -4
- package/dist/public/node/fs.js +50 -21
- package/dist/public/node/fs.js.map +1 -1
- package/dist/public/node/git.d.ts +9 -1
- package/dist/public/node/git.js +39 -9
- package/dist/public/node/git.js.map +1 -1
- package/dist/public/node/github.js +2 -2
- package/dist/public/node/github.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/public/node/http.d.ts +9 -1
- package/dist/public/node/http.js +37 -3
- package/dist/public/node/http.js.map +1 -1
- package/dist/public/node/liquid.js +2 -2
- package/dist/public/node/liquid.js.map +1 -1
- package/dist/public/node/metadata.d.ts +7 -7
- package/dist/public/node/monorail.d.ts +6 -6
- package/dist/public/node/monorail.js +4 -4
- package/dist/public/node/monorail.js.map +1 -1
- package/dist/public/node/node-package-manager.d.ts +5 -5
- package/dist/public/node/node-package-manager.js +9 -9
- package/dist/public/node/node-package-manager.js.map +1 -1
- package/dist/public/node/os.d.ts +2 -2
- package/dist/public/node/os.js +2 -2
- package/dist/public/node/os.js.map +1 -1
- package/dist/public/node/output.d.ts +188 -0
- package/dist/{output.js → public/node/output.js} +129 -50
- package/dist/public/node/output.js.map +1 -0
- package/dist/public/node/path.d.ts +1 -1
- package/dist/public/node/plugins/tunnel.d.ts +5 -5
- package/dist/public/node/plugins.d.ts +4 -4
- package/dist/public/node/result.d.ts +1 -1
- package/dist/public/node/ruby.d.ts +1 -1
- package/dist/public/node/ruby.js +7 -5
- package/dist/public/node/ruby.js.map +1 -1
- package/dist/public/node/session.d.ts +1 -1
- package/dist/public/node/session.js +9 -9
- package/dist/public/node/session.js.map +1 -1
- package/dist/public/node/system.d.ts +1 -1
- package/dist/public/node/system.js +2 -2
- package/dist/public/node/system.js.map +1 -1
- package/dist/public/node/tcp.js +4 -4
- package/dist/public/node/tcp.js.map +1 -1
- package/dist/public/node/testing/output.js +10 -9
- package/dist/public/node/testing/output.js.map +1 -1
- package/dist/public/node/ui.d.ts +11 -6
- package/dist/public/node/ui.js +5 -4
- package/dist/public/node/ui.js.map +1 -1
- package/dist/public/node/vscode.js +4 -4
- package/dist/public/node/vscode.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/ui.d.ts +6 -20
- package/dist/ui.js +8 -28
- package/dist/ui.js.map +1 -1
- package/package.json +6 -7
- package/dist/content-tokens.js.map +0 -1
- package/dist/network/api.d.ts +0 -2
- package/dist/network/api.js.map +0 -1
- package/dist/output.d.ts +0 -129
- package/dist/output.js.map +0 -1
- package/dist/private/common/ts/deep-required.js.map +0 -1
- package/dist/private/node/simple-definitions.d.ts +0 -4
- package/dist/private/node/simple-definitions.js +0 -2
- package/dist/private/node/simple-definitions.js.map +0 -1
|
@@ -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,QAAQ,EAAC,MAAM,
|
|
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,QAAQ,EAAC,MAAM,mCAAmC,CAAA;AAC1D,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAC,MAAM,kCAAkC,CAAA;AACpF,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,MAAM,EAAC,MAAM,qBAAqB,CAAA;AAE1C,QAAQ,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE;IAChC,IAAI,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;QAChD,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAExD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;KASpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,kBAAkB,CAAC,CAAA;QAC9C,KAAK,CAAC,KAAK,GAAG;;;;;;KAMb,CAAA;QAED,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAExD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;KAapD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,kBAAkB,CAAC,CAAA;QAC9C,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,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAExD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;;;;;;;;KAoBpD,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,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC,CAAA;QAExD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;KASpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {FatalError} from './FatalError.js'\nimport {unstyled} from '../../../../public/node/output.js'\nimport {AbortError, BugError, ExternalError} from '../../../../public/node/error.js'\nimport {describe, expect, test} from 'vitest'\nimport React from 'react'\nimport {render} from 'ink-testing-library'\n\ndescribe('FatalError', async () => {\n test('renders correctly with a just a message and tryMessage', async () => {\n const error = new AbortError('test', 'try this')\n const {lastFrame} = render(<FatalError error={error} />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\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 BugError('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 {lastFrame} = render(<FatalError error={error} />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\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 BugError('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 {lastFrame} = render(<FatalError error={error} />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\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 {lastFrame} = render(<FatalError error={error} />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"── external error ──────────────────────────────────────────────────────────────\n\n Error coming from \\`yarn install\\`\n\n Unexpected error\n\n ────────────────────────────────────────────────────────────────────────────────\n \"\n `)\n })\n})\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { List } from './List.js';
|
|
2
|
-
import { unstyled } from '../../../../output.js';
|
|
2
|
+
import { unstyled } from '../../../../public/node/output.js';
|
|
3
3
|
import { describe, expect, test } from 'vitest';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { render } from 'ink-testing-library';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"List.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/List.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAC,QAAQ,EAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"List.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/List.test.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAC,QAAQ,EAAC,MAAM,mCAAmC,CAAA;AAC1D,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAC,MAAM,QAAQ,CAAA;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,MAAM,EAAC,MAAM,qBAAqB,CAAA;AAE1C,QAAQ,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE;IAC1B,IAAI,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;QACzC,MAAM,OAAO,GAAG;YACd,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;YACrC,OAAO,EAAE,KAAK;SACf,CAAA;QAED,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,IAAI,OAAK,OAAO,GAAI,CAAC,CAAA;QAEjD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;KAKpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,OAAO,GAAG;YACd,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;YACrC,OAAO,EAAE,IAAI;SACd,CAAA;QAED,MAAM,EAAC,SAAS,EAAC,GAAG,MAAM,CAAC,oBAAC,IAAI,OAAK,OAAO,GAAI,CAAC,CAAA;QAEjD,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;KAIpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import {List} from './List.js'\nimport {unstyled} from '../../../../public/node/output.js'\nimport {describe, expect, test} from 'vitest'\nimport React from 'react'\nimport {render} from 'ink-testing-library'\n\ndescribe('List', async () => {\n test('renders unordered items', async () => {\n const options = {\n title: 'List title',\n items: ['Item 1', 'Item 2', 'Item 3'],\n ordered: false,\n }\n\n const {lastFrame} = render(<List {...options} />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"List title\n • Item 1\n • Item 2\n • Item 3\"\n `)\n })\n\n test('renders ordered items', async () => {\n const options = {\n items: ['Item 1', 'Item 2', 'Item 3'],\n ordered: true,\n }\n\n const {lastFrame} = render(<List {...options} />)\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \" 1. Item 1\n 2. Item 2\n 3. Item 3\"\n `)\n })\n})\n"]}
|
|
@@ -9,6 +9,8 @@ export interface Props<T> {
|
|
|
9
9
|
highlightedTerm?: string;
|
|
10
10
|
loading?: boolean;
|
|
11
11
|
errorMessage?: string;
|
|
12
|
+
hasMorePages?: boolean;
|
|
13
|
+
morePagesMessage?: string;
|
|
12
14
|
}
|
|
13
15
|
export interface Item<T> {
|
|
14
16
|
label: string;
|
|
@@ -16,4 +18,4 @@ export interface Item<T> {
|
|
|
16
18
|
key?: string;
|
|
17
19
|
group?: string;
|
|
18
20
|
}
|
|
19
|
-
export default function SelectInput<T>({ items, onChange, enableShortcuts, focus, emptyMessage, defaultValue, highlightedTerm, loading, errorMessage, }: React.PropsWithChildren<Props<T>>): JSX.Element | null;
|
|
21
|
+
export default function SelectInput<T>({ items, onChange, enableShortcuts, focus, emptyMessage, defaultValue, highlightedTerm, loading, errorMessage, hasMorePages, morePagesMessage, }: React.PropsWithChildren<Props<T>>): JSX.Element | null;
|
|
@@ -42,7 +42,7 @@ function SelectItemsGroup({ title, items, selectedIndex, hasMarginTop, enableSho
|
|
|
42
42
|
React.createElement(Text, { color: isSelected ? 'cyan' : undefined }, enableShortcuts ? `(${item.key}) ${label}` : label)));
|
|
43
43
|
})));
|
|
44
44
|
}
|
|
45
|
-
export default function SelectInput({ items, onChange, enableShortcuts = true, focus = true, emptyMessage = 'No items to select.', defaultValue, highlightedTerm, loading = false, errorMessage, }) {
|
|
45
|
+
export default function SelectInput({ items, onChange, enableShortcuts = true, focus = true, emptyMessage = 'No items to select.', defaultValue, highlightedTerm, loading = false, errorMessage, hasMorePages = false, morePagesMessage, }) {
|
|
46
46
|
const defaultValueIndex = defaultValue ? items.findIndex((item) => item.value === defaultValue.value) : -1;
|
|
47
47
|
const initialIndex = defaultValueIndex === -1 ? 0 : defaultValueIndex;
|
|
48
48
|
const inputStack = useRef(null);
|
|
@@ -120,7 +120,13 @@ export default function SelectInput({ items, onChange, enableShortcuts = true, f
|
|
|
120
120
|
return (React.createElement(Box, { flexDirection: "column" },
|
|
121
121
|
groupTitles.map((title, index) => (React.createElement(SelectItemsGroup, { title: title, selectedIndex: selectedIndex, items: groupedItems[title], key: title, hasMarginTop: index !== 0, enableShortcuts: enableShortcuts, highlightedTerm: highlightedTerm }))),
|
|
122
122
|
ungroupedItems.length > 0 && (React.createElement(SelectItemsGroup, { title: ungroupedItemsTitle, selectedIndex: selectedIndex, items: ungroupedItems, hasMarginTop: groupTitles.length > 0, enableShortcuts: enableShortcuts, highlightedTerm: highlightedTerm })),
|
|
123
|
-
React.createElement(Box, { marginTop: 1, marginLeft: 3 },
|
|
123
|
+
React.createElement(Box, { marginTop: 1, marginLeft: 3, flexDirection: "column" },
|
|
124
|
+
hasMorePages && (React.createElement(Text, null,
|
|
125
|
+
React.createElement(Text, { bold: true },
|
|
126
|
+
"1-",
|
|
127
|
+
items.length,
|
|
128
|
+
" of many"),
|
|
129
|
+
morePagesMessage ? ` ${morePagesMessage}` : null)),
|
|
124
130
|
React.createElement(Text, { dimColor: true },
|
|
125
131
|
"Press ",
|
|
126
132
|
figures.arrowUp,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectInput.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/SelectInput.tsx"],"names":[],"mappings":"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","sourcesContent":["import {isEqual} from '../../../../public/common/lang.js'\nimport {groupBy, partition} from '../../../../public/common/collection.js'\nimport {mapValues} from '../../../../public/common/object.js'\nimport React, {useState, useEffect, useRef, useCallback} from 'react'\nimport {Box, Key, useInput, Text} from 'ink'\nimport {debounce} from '@shopify/cli-kit/common/function'\nimport chalk from 'chalk'\nimport figures from 'figures'\n\nexport interface Props<T> {\n items: Item<T>[]\n onChange: (item: Item<T> | undefined) => void\n enableShortcuts?: boolean\n focus?: boolean\n emptyMessage?: string\n defaultValue?: Item<T>\n highlightedTerm?: string\n loading?: boolean\n errorMessage?: string\n}\n\nexport interface Item<T> {\n label: string\n value: T\n key?: string\n group?: string\n}\n\ninterface ItemWithIndex<T> extends Item<T> {\n key: string\n index: number\n}\n\nfunction highlightedLabel(label: string, term: string | undefined) {\n if (!term) {\n return label\n }\n\n const regex = new RegExp(term, 'i')\n return label.replace(regex, (match) => {\n return chalk.bold(match)\n })\n}\n\nfunction groupItems<T>(items: Item<T>[]): [{[key: string]: ItemWithIndex<T>[]}, ItemWithIndex<T>[]] {\n let index = 0\n\n const [withGroup, withoutGroup] = partition(items, 'group')\n\n const withGroupMapped = mapValues(groupBy(withGroup, 'group'), (groupItems) =>\n groupItems.map((groupItem) => {\n const item = {...groupItem, key: groupItem.key ?? (index + 1).toString(), index}\n index += 1\n return item\n }),\n )\n const withoutGroupMapped = withoutGroup.map((item) => {\n const newItem = {...item, key: item.key ?? (index + 1).toString(), index}\n index += 1\n return newItem\n })\n\n return [withGroupMapped, withoutGroupMapped]\n}\n\ninterface SelectItemsGroupProps<T> {\n title: string | undefined\n items: ItemWithIndex<T>[]\n selectedIndex: number\n hasMarginTop: boolean\n enableShortcuts: boolean\n highlightedTerm?: string\n}\n\nfunction SelectItemsGroup<T>({\n title,\n items,\n selectedIndex,\n hasMarginTop,\n enableShortcuts,\n highlightedTerm,\n}: SelectItemsGroupProps<T>): JSX.Element {\n return (\n <Box key={title} flexDirection=\"column\" marginTop={hasMarginTop ? 1 : 0}>\n {title && (\n <Box marginLeft={3}>\n <Text bold>{title}</Text>\n </Box>\n )}\n\n {items.map((item) => {\n const isSelected = item.index === selectedIndex\n const label = highlightedLabel(item.label, highlightedTerm)\n\n return (\n <Box key={item.key}>\n <Box marginRight={2}>{isSelected ? <Text color=\"cyan\">{`>`}</Text> : <Text> </Text>}</Box>\n\n <Text color={isSelected ? 'cyan' : undefined}>{enableShortcuts ? `(${item.key}) ${label}` : label}</Text>\n </Box>\n )\n })}\n </Box>\n )\n}\n\nexport default function SelectInput<T>({\n items,\n onChange,\n enableShortcuts = true,\n focus = true,\n emptyMessage = 'No items to select.',\n defaultValue,\n highlightedTerm,\n loading = false,\n errorMessage,\n}: React.PropsWithChildren<Props<T>>): JSX.Element | null {\n const defaultValueIndex = defaultValue ? items.findIndex((item) => item.value === defaultValue.value) : -1\n const initialIndex = defaultValueIndex === -1 ? 0 : defaultValueIndex\n const inputStack = useRef<string | null>(null)\n const [selectedIndex, setSelectedIndex] = useState(initialIndex)\n const [groupedItems, ungroupedItems] = groupItems(items)\n const groupedItemsValues = [...Object.values(groupedItems).flat(), ...ungroupedItems]\n const keys = groupedItemsValues.map((item) => item.key)\n const groupTitles = Object.keys(groupedItems)\n const previousItems = useRef<Item<T>[]>(items)\n\n const changeSelection = useCallback(\n (index: number) => {\n const groupedItem = groupedItemsValues.find((item) => item.index === index)!\n setSelectedIndex(index)\n onChange(items.find((item) => item.value === groupedItem.value))\n },\n [items],\n )\n\n useEffect(() => {\n if (items.length === 0) {\n // reset selection when items are empty\n onChange(undefined)\n } else if (\n // reset index when items change\n !isEqual(\n previousItems.current.map((item) => item.value),\n items.map((item) => item.value),\n )\n ) {\n changeSelection(0)\n }\n\n previousItems.current = items\n }, [items])\n\n const handleArrows = useCallback(\n (key: Key) => {\n const lastIndex = items.length - 1\n\n if (key.upArrow) {\n changeSelection(selectedIndex === 0 ? lastIndex : selectedIndex - 1)\n } else if (key.downArrow) {\n changeSelection(selectedIndex === lastIndex ? 0 : selectedIndex + 1)\n }\n },\n [selectedIndex, items],\n )\n\n const handleShortcuts = useCallback(\n (input: string) => {\n if (keys.includes(input)) {\n const groupedItem = groupedItemsValues.find((item) => item.key === input)\n if (groupedItem !== undefined) {\n changeSelection(groupedItem.index)\n }\n }\n },\n [items],\n )\n\n const debounceHandleShortcuts = useCallback(\n debounce((newInputStack) => {\n handleShortcuts(newInputStack)\n inputStack.current = null\n }, 300),\n [],\n )\n\n useInput(\n (input, key) => {\n // check that no special modifier (shift, control, etc.) is being pressed\n if (enableShortcuts && input.length > 0 && Object.values(key).every((value) => value === false)) {\n const newInputStack = inputStack.current === null ? input : inputStack.current + input\n\n inputStack.current = newInputStack\n debounceHandleShortcuts(newInputStack)\n } else {\n debounceHandleShortcuts.cancel()\n inputStack.current = null\n handleArrows(key)\n }\n },\n {isActive: focus},\n )\n\n const ungroupedItemsTitle = groupTitles.length > 0 ? 'Other' : undefined\n\n if (loading) {\n return (\n <Box marginLeft={3}>\n <Text dimColor>Loading...</Text>\n </Box>\n )\n } else if (errorMessage && errorMessage.length > 0) {\n return (\n <Box marginLeft={3}>\n <Text color=\"red\">{errorMessage}</Text>\n </Box>\n )\n } else if (items.length === 0) {\n return (\n <Box marginLeft={3}>\n <Text dimColor>{emptyMessage}</Text>\n </Box>\n )\n } else {\n return (\n <Box flexDirection=\"column\">\n {groupTitles.map((title, index) => (\n <SelectItemsGroup\n title={title}\n selectedIndex={selectedIndex}\n items={groupedItems[title]!}\n key={title}\n hasMarginTop={index !== 0}\n enableShortcuts={enableShortcuts}\n highlightedTerm={highlightedTerm}\n ></SelectItemsGroup>\n ))}\n\n {ungroupedItems.length > 0 && (\n <SelectItemsGroup\n title={ungroupedItemsTitle}\n selectedIndex={selectedIndex}\n items={ungroupedItems}\n hasMarginTop={groupTitles.length > 0}\n enableShortcuts={enableShortcuts}\n highlightedTerm={highlightedTerm}\n ></SelectItemsGroup>\n )}\n\n <Box marginTop={1} marginLeft={3}>\n <Text dimColor>\n Press {figures.arrowUp}\n {figures.arrowDown} arrows to select, enter to confirm\n </Text>\n </Box>\n </Box>\n )\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SelectInput.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/SelectInput.tsx"],"names":[],"mappings":"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","sourcesContent":["import {isEqual} from '../../../../public/common/lang.js'\nimport {groupBy, partition} from '../../../../public/common/collection.js'\nimport {mapValues} from '../../../../public/common/object.js'\nimport React, {useState, useEffect, useRef, useCallback} from 'react'\nimport {Box, Key, useInput, Text} from 'ink'\nimport {debounce} from '@shopify/cli-kit/common/function'\nimport chalk from 'chalk'\nimport figures from 'figures'\n\nexport interface Props<T> {\n items: Item<T>[]\n onChange: (item: Item<T> | undefined) => void\n enableShortcuts?: boolean\n focus?: boolean\n emptyMessage?: string\n defaultValue?: Item<T>\n highlightedTerm?: string\n loading?: boolean\n errorMessage?: string\n hasMorePages?: boolean\n morePagesMessage?: string\n}\n\nexport interface Item<T> {\n label: string\n value: T\n key?: string\n group?: string\n}\n\ninterface ItemWithIndex<T> extends Item<T> {\n key: string\n index: number\n}\n\nfunction highlightedLabel(label: string, term: string | undefined) {\n if (!term) {\n return label\n }\n\n const regex = new RegExp(term, 'i')\n return label.replace(regex, (match) => {\n return chalk.bold(match)\n })\n}\n\nfunction groupItems<T>(items: Item<T>[]): [{[key: string]: ItemWithIndex<T>[]}, ItemWithIndex<T>[]] {\n let index = 0\n\n const [withGroup, withoutGroup] = partition(items, 'group')\n\n const withGroupMapped = mapValues(groupBy(withGroup, 'group'), (groupItems) =>\n groupItems.map((groupItem) => {\n const item = {...groupItem, key: groupItem.key ?? (index + 1).toString(), index}\n index += 1\n return item\n }),\n )\n const withoutGroupMapped = withoutGroup.map((item) => {\n const newItem = {...item, key: item.key ?? (index + 1).toString(), index}\n index += 1\n return newItem\n })\n\n return [withGroupMapped, withoutGroupMapped]\n}\n\ninterface SelectItemsGroupProps<T> {\n title: string | undefined\n items: ItemWithIndex<T>[]\n selectedIndex: number\n hasMarginTop: boolean\n enableShortcuts: boolean\n highlightedTerm?: string\n}\n\nfunction SelectItemsGroup<T>({\n title,\n items,\n selectedIndex,\n hasMarginTop,\n enableShortcuts,\n highlightedTerm,\n}: SelectItemsGroupProps<T>): JSX.Element {\n return (\n <Box key={title} flexDirection=\"column\" marginTop={hasMarginTop ? 1 : 0}>\n {title && (\n <Box marginLeft={3}>\n <Text bold>{title}</Text>\n </Box>\n )}\n\n {items.map((item) => {\n const isSelected = item.index === selectedIndex\n const label = highlightedLabel(item.label, highlightedTerm)\n\n return (\n <Box key={item.key}>\n <Box marginRight={2}>{isSelected ? <Text color=\"cyan\">{`>`}</Text> : <Text> </Text>}</Box>\n\n <Text color={isSelected ? 'cyan' : undefined}>{enableShortcuts ? `(${item.key}) ${label}` : label}</Text>\n </Box>\n )\n })}\n </Box>\n )\n}\n\nexport default function SelectInput<T>({\n items,\n onChange,\n enableShortcuts = true,\n focus = true,\n emptyMessage = 'No items to select.',\n defaultValue,\n highlightedTerm,\n loading = false,\n errorMessage,\n hasMorePages = false,\n morePagesMessage,\n}: React.PropsWithChildren<Props<T>>): JSX.Element | null {\n const defaultValueIndex = defaultValue ? items.findIndex((item) => item.value === defaultValue.value) : -1\n const initialIndex = defaultValueIndex === -1 ? 0 : defaultValueIndex\n const inputStack = useRef<string | null>(null)\n const [selectedIndex, setSelectedIndex] = useState(initialIndex)\n const [groupedItems, ungroupedItems] = groupItems(items)\n const groupedItemsValues = [...Object.values(groupedItems).flat(), ...ungroupedItems]\n const keys = groupedItemsValues.map((item) => item.key)\n const groupTitles = Object.keys(groupedItems)\n const previousItems = useRef<Item<T>[]>(items)\n\n const changeSelection = useCallback(\n (index: number) => {\n const groupedItem = groupedItemsValues.find((item) => item.index === index)!\n setSelectedIndex(index)\n onChange(items.find((item) => item.value === groupedItem.value))\n },\n [items],\n )\n\n useEffect(() => {\n if (items.length === 0) {\n // reset selection when items are empty\n onChange(undefined)\n } else if (\n // reset index when items change\n !isEqual(\n previousItems.current.map((item) => item.value),\n items.map((item) => item.value),\n )\n ) {\n changeSelection(0)\n }\n\n previousItems.current = items\n }, [items])\n\n const handleArrows = useCallback(\n (key: Key) => {\n const lastIndex = items.length - 1\n\n if (key.upArrow) {\n changeSelection(selectedIndex === 0 ? lastIndex : selectedIndex - 1)\n } else if (key.downArrow) {\n changeSelection(selectedIndex === lastIndex ? 0 : selectedIndex + 1)\n }\n },\n [selectedIndex, items],\n )\n\n const handleShortcuts = useCallback(\n (input: string) => {\n if (keys.includes(input)) {\n const groupedItem = groupedItemsValues.find((item) => item.key === input)\n if (groupedItem !== undefined) {\n changeSelection(groupedItem.index)\n }\n }\n },\n [items],\n )\n\n const debounceHandleShortcuts = useCallback(\n debounce((newInputStack) => {\n handleShortcuts(newInputStack)\n inputStack.current = null\n }, 300),\n [],\n )\n\n useInput(\n (input, key) => {\n // check that no special modifier (shift, control, etc.) is being pressed\n if (enableShortcuts && input.length > 0 && Object.values(key).every((value) => value === false)) {\n const newInputStack = inputStack.current === null ? input : inputStack.current + input\n\n inputStack.current = newInputStack\n debounceHandleShortcuts(newInputStack)\n } else {\n debounceHandleShortcuts.cancel()\n inputStack.current = null\n handleArrows(key)\n }\n },\n {isActive: focus},\n )\n\n const ungroupedItemsTitle = groupTitles.length > 0 ? 'Other' : undefined\n\n if (loading) {\n return (\n <Box marginLeft={3}>\n <Text dimColor>Loading...</Text>\n </Box>\n )\n } else if (errorMessage && errorMessage.length > 0) {\n return (\n <Box marginLeft={3}>\n <Text color=\"red\">{errorMessage}</Text>\n </Box>\n )\n } else if (items.length === 0) {\n return (\n <Box marginLeft={3}>\n <Text dimColor>{emptyMessage}</Text>\n </Box>\n )\n } else {\n return (\n <Box flexDirection=\"column\">\n {groupTitles.map((title, index) => (\n <SelectItemsGroup\n title={title}\n selectedIndex={selectedIndex}\n items={groupedItems[title]!}\n key={title}\n hasMarginTop={index !== 0}\n enableShortcuts={enableShortcuts}\n highlightedTerm={highlightedTerm}\n ></SelectItemsGroup>\n ))}\n\n {ungroupedItems.length > 0 && (\n <SelectItemsGroup\n title={ungroupedItemsTitle}\n selectedIndex={selectedIndex}\n items={ungroupedItems}\n hasMarginTop={groupTitles.length > 0}\n enableShortcuts={enableShortcuts}\n highlightedTerm={highlightedTerm}\n ></SelectItemsGroup>\n )}\n\n <Box marginTop={1} marginLeft={3} flexDirection=\"column\">\n {hasMorePages && (\n <Text>\n <Text bold>1-{items.length} of many</Text>\n {morePagesMessage ? ` ${morePagesMessage}` : null}\n </Text>\n )}\n <Text dimColor>\n Press {figures.arrowUp}\n {figures.arrowDown} arrows to select, enter to confirm\n </Text>\n </Box>\n </Box>\n )\n }\n}\n"]}
|
|
@@ -312,5 +312,31 @@ describe('SelectInput', async () => {
|
|
|
312
312
|
[2mPress ↑↓ arrows to select, enter to confirm[22m"
|
|
313
313
|
`);
|
|
314
314
|
});
|
|
315
|
+
test('shows if there are more pages', async () => {
|
|
316
|
+
const items = [
|
|
317
|
+
{
|
|
318
|
+
label: 'First',
|
|
319
|
+
value: 'first',
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
label: 'Second',
|
|
323
|
+
value: 'second',
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
label: 'Third',
|
|
327
|
+
value: 'third',
|
|
328
|
+
},
|
|
329
|
+
];
|
|
330
|
+
const renderInstance = render(React.createElement(SelectInput, { items: items, onChange: () => { }, morePagesMessage: "Keep scrolling to see more items", hasMorePages: true }));
|
|
331
|
+
await waitForInputsToBeReady();
|
|
332
|
+
expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`
|
|
333
|
+
"[36m>[39m [36m(1) First[39m
|
|
334
|
+
(2) Second
|
|
335
|
+
(3) Third
|
|
336
|
+
|
|
337
|
+
[1m1-3 of many[22m Keep scrolling to see more items
|
|
338
|
+
[2mPress ↑↓ arrows to select, enter to confirm[22m"
|
|
339
|
+
`);
|
|
340
|
+
});
|
|
315
341
|
});
|
|
316
342
|
//# sourceMappingURL=SelectInput.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectInput.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/SelectInput.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import SelectInput from './SelectInput.js'\nimport {sendInputAndWait, sendInputAndWaitForChange, 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_UP = '\\u001B[A'\nconst ARROW_DOWN = '\\u001B[B'\n\ndescribe('SelectInput', async () => {\n test('move up with up arrow key', async () => {\n const onChange = vi.fn()\n\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ARROW_UP)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n (2) Second\n \u001b[36m>\u001b[39m \u001b[36m(3) Third\u001b[39m\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[2]!)\n })\n\n test('move down with down arrow key', async () => {\n const onChange = vi.fn()\n\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n \u001b[36m>\u001b[39m \u001b[36m(2) Second\u001b[39m\n (3) Third\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[1]!)\n })\n\n test('handles keys with multiple digits', async () => {\n const onChange = vi.fn()\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Tenth',\n value: 'tenth',\n key: '10',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, '1', '0')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n (2) Second\n \u001b[36m>\u001b[39m \u001b[36m(10) Tenth\u001b[39m\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[2]!)\n })\n\n test('handles pressing non existing keys', async () => {\n const onChange = vi.fn()\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Tenth',\n value: 'tenth',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n await waitForInputsToBeReady()\n // nothing changes when pressing a key that doesn't exist\n await sendInputAndWait(renderInstance, 100, '4')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[36m>\u001b[39m \u001b[36m(1) First\u001b[39m\n (2) Second\n (3) Tenth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).not.toHaveBeenCalled()\n })\n\n test('handles custom keys', async () => {\n const onChange = vi.fn()\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n key: 't',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, 't')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n (2) Second\n \u001b[36m>\u001b[39m \u001b[36m(t) Third\u001b[39m\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[2]!)\n })\n\n test('rotate after reaching the end of the list', async () => {\n const onChange = vi.fn()\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[36m>\u001b[39m \u001b[36m(1) First\u001b[39m\n (2) Second\n (3) Third\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[0]!)\n })\n\n test('support groups', async () => {\n const onChange = vi.fn()\n\n const items = [\n {label: 'first', value: 'first', group: 'Automations', key: 'f'},\n {label: 'second', value: 'second', group: 'Automations', key: 's'},\n {label: 'third', value: 'third', group: 'Merchant Admin'},\n {label: 'fourth', value: 'fourth', group: 'Merchant Admin'},\n {label: 'fifth', value: 'fifth', key: 'a'},\n {label: 'sixth', value: 'sixth'},\n {label: 'seventh', value: 'seventh'},\n {label: 'eighth', value: 'eighth'},\n {label: 'ninth', value: 'ninth'},\n {label: 'tenth', value: 'tenth'},\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" \u001b[1mAutomations\u001b[22m\n \u001b[36m>\u001b[39m \u001b[36m(f) first\u001b[39m\n (s) second\n\n \u001b[1mMerchant Admin\u001b[22m\n (3) third\n (4) fourth\n\n \u001b[1mOther\u001b[22m\n (a) fifth\n (6) sixth\n (7) seventh\n (8) eighth\n (9) ninth\n (10) tenth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, 'a')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" \u001b[1mAutomations\u001b[22m\n (f) first\n (s) second\n\n \u001b[1mMerchant Admin\u001b[22m\n (3) third\n (4) fourth\n\n \u001b[1mOther\u001b[22m\n \u001b[36m>\u001b[39m \u001b[36m(a) fifth\u001b[39m\n (6) sixth\n (7) seventh\n (8) eighth\n (9) ninth\n (10) tenth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[4]!)\n\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" \u001b[1mAutomations\u001b[22m\n (f) first\n (s) second\n\n \u001b[1mMerchant Admin\u001b[22m\n (3) third\n (4) fourth\n\n \u001b[1mOther\u001b[22m\n (a) fifth\n (6) sixth\n \u001b[36m>\u001b[39m \u001b[36m(7) seventh\u001b[39m\n (8) eighth\n (9) ninth\n (10) tenth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[6]!)\n })\n\n test('allows disabling shortcuts', async () => {\n const onChange = vi.fn()\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} enableShortcuts={false} />)\n\n await waitForInputsToBeReady()\n // input doesn't change on shortcut pressed\n await sendInputAndWait(renderInstance, 100, '2')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[36m>\u001b[39m \u001b[36mFirst\u001b[39m\n Second\n Third\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).not.toHaveBeenCalled()\n })\n\n test('accepts a default value', async () => {\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(\n <SelectInput items={items} onChange={() => {}} defaultValue={{label: 'Second', value: 'second'}} />,\n )\n\n await waitForInputsToBeReady()\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n \u001b[36m>\u001b[39m \u001b[36m(2) Second\u001b[39m\n (3) Third\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n })\n})\n"]}
|
|
1
|
+
{"version":3,"file":"SelectInput.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/SelectInput.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import SelectInput from './SelectInput.js'\nimport {sendInputAndWait, sendInputAndWaitForChange, 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_UP = '\\u001B[A'\nconst ARROW_DOWN = '\\u001B[B'\n\ndescribe('SelectInput', async () => {\n test('move up with up arrow key', async () => {\n const onChange = vi.fn()\n\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ARROW_UP)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n (2) Second\n \u001b[36m>\u001b[39m \u001b[36m(3) Third\u001b[39m\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[2]!)\n })\n\n test('move down with down arrow key', async () => {\n const onChange = vi.fn()\n\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n \u001b[36m>\u001b[39m \u001b[36m(2) Second\u001b[39m\n (3) Third\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[1]!)\n })\n\n test('handles keys with multiple digits', async () => {\n const onChange = vi.fn()\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Tenth',\n value: 'tenth',\n key: '10',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, '1', '0')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n (2) Second\n \u001b[36m>\u001b[39m \u001b[36m(10) Tenth\u001b[39m\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[2]!)\n })\n\n test('handles pressing non existing keys', async () => {\n const onChange = vi.fn()\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Tenth',\n value: 'tenth',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n await waitForInputsToBeReady()\n // nothing changes when pressing a key that doesn't exist\n await sendInputAndWait(renderInstance, 100, '4')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[36m>\u001b[39m \u001b[36m(1) First\u001b[39m\n (2) Second\n (3) Tenth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).not.toHaveBeenCalled()\n })\n\n test('handles custom keys', async () => {\n const onChange = vi.fn()\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n key: 't',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, 't')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n (2) Second\n \u001b[36m>\u001b[39m \u001b[36m(t) Third\u001b[39m\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[2]!)\n })\n\n test('rotate after reaching the end of the list', async () => {\n const onChange = vi.fn()\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[36m>\u001b[39m \u001b[36m(1) First\u001b[39m\n (2) Second\n (3) Third\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[0]!)\n })\n\n test('support groups', async () => {\n const onChange = vi.fn()\n\n const items = [\n {label: 'first', value: 'first', group: 'Automations', key: 'f'},\n {label: 'second', value: 'second', group: 'Automations', key: 's'},\n {label: 'third', value: 'third', group: 'Merchant Admin'},\n {label: 'fourth', value: 'fourth', group: 'Merchant Admin'},\n {label: 'fifth', value: 'fifth', key: 'a'},\n {label: 'sixth', value: 'sixth'},\n {label: 'seventh', value: 'seventh'},\n {label: 'eighth', value: 'eighth'},\n {label: 'ninth', value: 'ninth'},\n {label: 'tenth', value: 'tenth'},\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} />)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" \u001b[1mAutomations\u001b[22m\n \u001b[36m>\u001b[39m \u001b[36m(f) first\u001b[39m\n (s) second\n\n \u001b[1mMerchant Admin\u001b[22m\n (3) third\n (4) fourth\n\n \u001b[1mOther\u001b[22m\n (a) fifth\n (6) sixth\n (7) seventh\n (8) eighth\n (9) ninth\n (10) tenth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, 'a')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" \u001b[1mAutomations\u001b[22m\n (f) first\n (s) second\n\n \u001b[1mMerchant Admin\u001b[22m\n (3) third\n (4) fourth\n\n \u001b[1mOther\u001b[22m\n \u001b[36m>\u001b[39m \u001b[36m(a) fifth\u001b[39m\n (6) sixth\n (7) seventh\n (8) eighth\n (9) ninth\n (10) tenth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[4]!)\n\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n await sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" \u001b[1mAutomations\u001b[22m\n (f) first\n (s) second\n\n \u001b[1mMerchant Admin\u001b[22m\n (3) third\n (4) fourth\n\n \u001b[1mOther\u001b[22m\n (a) fifth\n (6) sixth\n \u001b[36m>\u001b[39m \u001b[36m(7) seventh\u001b[39m\n (8) eighth\n (9) ninth\n (10) tenth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).toHaveBeenCalledWith(items[6]!)\n })\n\n test('allows disabling shortcuts', async () => {\n const onChange = vi.fn()\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(<SelectInput items={items} onChange={onChange} enableShortcuts={false} />)\n\n await waitForInputsToBeReady()\n // input doesn't change on shortcut pressed\n await sendInputAndWait(renderInstance, 100, '2')\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[36m>\u001b[39m \u001b[36mFirst\u001b[39m\n Second\n Third\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n expect(onChange).not.toHaveBeenCalled()\n })\n\n test('accepts a default value', async () => {\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(\n <SelectInput items={items} onChange={() => {}} defaultValue={{label: 'Second', value: 'second'}} />,\n )\n\n await waitForInputsToBeReady()\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \" (1) First\n \u001b[36m>\u001b[39m \u001b[36m(2) Second\u001b[39m\n (3) Third\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n })\n\n test('shows if there are more pages', async () => {\n const items = [\n {\n label: 'First',\n value: 'first',\n },\n {\n label: 'Second',\n value: 'second',\n },\n {\n label: 'Third',\n value: 'third',\n },\n ]\n\n const renderInstance = render(\n <SelectInput\n items={items}\n onChange={() => {}}\n morePagesMessage=\"Keep scrolling to see more items\"\n hasMorePages\n />,\n )\n\n await waitForInputsToBeReady()\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"\u001b[36m>\u001b[39m \u001b[36m(1) First\u001b[39m\n (2) Second\n (3) Third\n\n \u001b[1m1-3 of many\u001b[22m Keep scrolling to see more items\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\"\n `)\n })\n})\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SelectPrompt } from './SelectPrompt.js';
|
|
2
2
|
import { getLastFrameAfterUnmount, sendInputAndWaitForChange, waitForInputsToBeReady } from '../../testing/ui.js';
|
|
3
|
-
import { unstyled } from '../../../../output.js';
|
|
3
|
+
import { unstyled } from '../../../../public/node/output.js';
|
|
4
4
|
import { describe, expect, test, vi } from 'vitest';
|
|
5
5
|
import React from 'react';
|
|
6
6
|
import { render } from 'ink-testing-library';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectPrompt.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/SelectPrompt.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import {SelectPrompt} from './SelectPrompt.js'\nimport {getLastFrameAfterUnmount, sendInputAndWaitForChange, waitForInputsToBeReady} from '../../testing/ui.js'\nimport {unstyled} from '../../../../output.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('SelectPrompt', 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 sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n await sendInputAndWaitForChange(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('renders groups', async () => {\n const items = [\n {label: 'first', value: 'first', group: 'Automations', key: 'f'},\n {label: 'second', value: 'second', group: 'Automations', key: 's'},\n {label: 'third', value: 'third', group: 'Merchant Admin'},\n {label: 'fourth', value: 'fourth', group: 'Merchant Admin'},\n {label: 'fifth', value: 'fifth', key: 'a'},\n {label: 'sixth', value: 'sixth'},\n {label: 'seventh', value: 'seventh'},\n {label: 'eighth', value: 'eighth'},\n {label: 'ninth', value: 'ninth'},\n {label: 'tenth', value: 'tenth'},\n ]\n\n const renderInstance = render(\n <SelectPrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n onSubmit={() => {}}\n />,\n )\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures?\n\n \u001b[1mAutomations\u001b[22m\n \u001b[36m>\u001b[39m \u001b[36m(f) first\u001b[39m\n (s) second\n\n \u001b[1mMerchant Admin\u001b[22m\n (3) third\n (4) fourth\n\n \u001b[1mOther\u001b[22m\n (a) fifth\n (6) sixth\n (7) seventh\n (8) eighth\n (9) ninth\n (10) tenth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n })\n\n test('supports an info table', async () => {\n const items = [\n {label: 'first', value: 'first'},\n {label: 'second', value: 'second'},\n {label: 'third', value: 'third'},\n {label: 'fourth', value: 'fourth'},\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(1) first\u001b[39m\n (2) second\n (3) third\n (4) fourth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n })\n\n test(\"it doesn't submit if there are no choices\", async () => {\n const onEnter = vi.fn()\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const items: any[] = []\n\n const renderInstance = render(\n <SelectPrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n onSubmit={onEnter}\n />,\n )\n\n expect(unstyled(getLastFrameAfterUnmount(renderInstance)!)).toContain(\n 'ERROR SelectPrompt requires at least one choice',\n )\n })\n\n test(\"doesn't append a colon to the message if it ends with a question mark\", async () => {\n const {lastFrame} = render(\n <SelectPrompt choices={[{label: 'a', value: 'a'}]} onSubmit={() => {}} message=\"Test question?\" />,\n )\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"? Test question?\n\n > (1) a\n\n Press ↑↓ arrows to select, enter to confirm\n \"\n `)\n })\n\n test('accepts a default value', async () => {\n const onEnter = vi.fn()\n const items = [\n {label: 'a', value: 'a'},\n {label: 'b', value: 'b'},\n ]\n\n const renderInstance = render(\n <SelectPrompt choices={items} onSubmit={onEnter} message=\"Test question?\" defaultValue=\"b\" />,\n )\n\n expect(unstyled(renderInstance.lastFrame()!)).toMatchInlineSnapshot(`\n \"? Test question?\n\n (1) a\n > (2) b\n\n Press ↑↓ arrows to select, enter to confirm\n \"\n `)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ENTER)\n\n expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`\n \"? Test question?\n \u001b[36m✔\u001b[39m \u001b[36mb\u001b[39m\n \"\n `)\n expect(onEnter).toHaveBeenCalledWith(items[1]!.value)\n })\n\n test('can submit the initial value', async () => {\n const onEnter = vi.fn()\n const items = [\n {label: 'a', value: 'a'},\n {label: 'b', value: 'b'},\n ]\n\n const renderInstance = render(<SelectPrompt choices={items} onSubmit={onEnter} message=\"Test question?\" />)\n\n expect(unstyled(renderInstance.lastFrame()!)).toMatchInlineSnapshot(`\n \"? Test question?\n\n > (1) a\n (2) b\n\n Press ↑↓ arrows to select, enter to confirm\n \"\n `)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ENTER)\n\n expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`\n \"? Test question?\n \u001b[36m✔\u001b[39m \u001b[36ma\u001b[39m\n \"\n `)\n expect(onEnter).toHaveBeenCalledWith(items[0]!.value)\n })\n})\n"]}
|
|
1
|
+
{"version":3,"file":"SelectPrompt.test.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/SelectPrompt.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import {SelectPrompt} from './SelectPrompt.js'\nimport {getLastFrameAfterUnmount, sendInputAndWaitForChange, waitForInputsToBeReady} from '../../testing/ui.js'\nimport {unstyled} from '../../../../public/node/output.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('SelectPrompt', 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 sendInputAndWaitForChange(renderInstance, ARROW_DOWN)\n await sendInputAndWaitForChange(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('renders groups', async () => {\n const items = [\n {label: 'first', value: 'first', group: 'Automations', key: 'f'},\n {label: 'second', value: 'second', group: 'Automations', key: 's'},\n {label: 'third', value: 'third', group: 'Merchant Admin'},\n {label: 'fourth', value: 'fourth', group: 'Merchant Admin'},\n {label: 'fifth', value: 'fifth', key: 'a'},\n {label: 'sixth', value: 'sixth'},\n {label: 'seventh', value: 'seventh'},\n {label: 'eighth', value: 'eighth'},\n {label: 'ninth', value: 'ninth'},\n {label: 'tenth', value: 'tenth'},\n ]\n\n const renderInstance = render(\n <SelectPrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n onSubmit={() => {}}\n />,\n )\n\n expect(renderInstance.lastFrame()).toMatchInlineSnapshot(`\n \"? Associate your project with the org Castile Ventures?\n\n \u001b[1mAutomations\u001b[22m\n \u001b[36m>\u001b[39m \u001b[36m(f) first\u001b[39m\n (s) second\n\n \u001b[1mMerchant Admin\u001b[22m\n (3) third\n (4) fourth\n\n \u001b[1mOther\u001b[22m\n (a) fifth\n (6) sixth\n (7) seventh\n (8) eighth\n (9) ninth\n (10) tenth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n })\n\n test('supports an info table', async () => {\n const items = [\n {label: 'first', value: 'first'},\n {label: 'second', value: 'second'},\n {label: 'third', value: 'third'},\n {label: 'fourth', value: 'fourth'},\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(1) first\u001b[39m\n (2) second\n (3) third\n (4) fourth\n\n \u001b[2mPress ↑↓ arrows to select, enter to confirm\u001b[22m\n \"\n `)\n })\n\n test(\"it doesn't submit if there are no choices\", async () => {\n const onEnter = vi.fn()\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const items: any[] = []\n\n const renderInstance = render(\n <SelectPrompt\n message=\"Associate your project with the org Castile Ventures?\"\n choices={items}\n onSubmit={onEnter}\n />,\n )\n\n expect(unstyled(getLastFrameAfterUnmount(renderInstance)!)).toContain(\n 'ERROR SelectPrompt requires at least one choice',\n )\n })\n\n test(\"doesn't append a colon to the message if it ends with a question mark\", async () => {\n const {lastFrame} = render(\n <SelectPrompt choices={[{label: 'a', value: 'a'}]} onSubmit={() => {}} message=\"Test question?\" />,\n )\n\n expect(unstyled(lastFrame()!)).toMatchInlineSnapshot(`\n \"? Test question?\n\n > (1) a\n\n Press ↑↓ arrows to select, enter to confirm\n \"\n `)\n })\n\n test('accepts a default value', async () => {\n const onEnter = vi.fn()\n const items = [\n {label: 'a', value: 'a'},\n {label: 'b', value: 'b'},\n ]\n\n const renderInstance = render(\n <SelectPrompt choices={items} onSubmit={onEnter} message=\"Test question?\" defaultValue=\"b\" />,\n )\n\n expect(unstyled(renderInstance.lastFrame()!)).toMatchInlineSnapshot(`\n \"? Test question?\n\n (1) a\n > (2) b\n\n Press ↑↓ arrows to select, enter to confirm\n \"\n `)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ENTER)\n\n expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`\n \"? Test question?\n \u001b[36m✔\u001b[39m \u001b[36mb\u001b[39m\n \"\n `)\n expect(onEnter).toHaveBeenCalledWith(items[1]!.value)\n })\n\n test('can submit the initial value', async () => {\n const onEnter = vi.fn()\n const items = [\n {label: 'a', value: 'a'},\n {label: 'b', value: 'b'},\n ]\n\n const renderInstance = render(<SelectPrompt choices={items} onSubmit={onEnter} message=\"Test question?\" />)\n\n expect(unstyled(renderInstance.lastFrame()!)).toMatchInlineSnapshot(`\n \"? Test question?\n\n > (1) a\n (2) b\n\n Press ↑↓ arrows to select, enter to confirm\n \"\n `)\n\n await waitForInputsToBeReady()\n await sendInputAndWaitForChange(renderInstance, ENTER)\n\n expect(getLastFrameAfterUnmount(renderInstance)).toMatchInlineSnapshot(`\n \"? Test question?\n \u001b[36m✔\u001b[39m \u001b[36ma\u001b[39m\n \"\n `)\n expect(onEnter).toHaveBeenCalledWith(items[0]!.value)\n })\n})\n"]}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
export interface Task<TContext = unknown> {
|
|
3
3
|
title: string;
|
|
4
|
-
task: (ctx: TContext) => Promise<void | Task<TContext>[]>;
|
|
4
|
+
task: (ctx: TContext, task: Task<TContext>) => Promise<void | Task<TContext>[]>;
|
|
5
|
+
retry?: number;
|
|
6
|
+
retryCount?: number;
|
|
7
|
+
errors?: Error[];
|
|
8
|
+
skip?: (ctx: TContext) => boolean;
|
|
5
9
|
}
|
|
6
10
|
export interface Props<TContext> {
|
|
7
11
|
tasks: Task<TContext>[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TextAnimation } from './TextAnimation.js';
|
|
2
2
|
import useLayout from '../hooks/use-layout.js';
|
|
3
3
|
import useAsyncAndUnmount from '../hooks/use-async-and-unmount.js';
|
|
4
|
-
|
|
4
|
+
import { isUnitTest } from '../../../../public/node/environment/local.js';
|
|
5
5
|
import { Box, Text } from 'ink';
|
|
6
6
|
import React, { useRef, useState } from 'react';
|
|
7
7
|
const loadingBarChar = '▀';
|
|
@@ -11,7 +11,31 @@ var TasksState;
|
|
|
11
11
|
TasksState["Success"] = "success";
|
|
12
12
|
TasksState["Failure"] = "failure";
|
|
13
13
|
})(TasksState || (TasksState = {}));
|
|
14
|
-
function
|
|
14
|
+
async function runTask(task, ctx) {
|
|
15
|
+
task.retryCount = 0;
|
|
16
|
+
task.errors = [];
|
|
17
|
+
const retry = task?.retry && task?.retry > 0 ? task.retry + 1 : 1;
|
|
18
|
+
for (let retries = 1; retries <= retry; retries++) {
|
|
19
|
+
try {
|
|
20
|
+
if (task.skip?.(ctx)) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
// eslint-disable-next-line no-await-in-loop
|
|
24
|
+
return await task.task(ctx, task);
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
if (retries === retry) {
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
task.errors.push(error);
|
|
33
|
+
task.retryCount = retries;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function Tasks({ tasks, silent = isUnitTest() }) {
|
|
15
39
|
const { twoThirds } = useLayout();
|
|
16
40
|
const loadingBar = new Array(twoThirds).fill(loadingBarChar).join('');
|
|
17
41
|
const [currentTask, setCurrentTask] = useState(tasks[0]);
|
|
@@ -21,12 +45,13 @@ function Tasks({ tasks, silent = false }) {
|
|
|
21
45
|
for (const task of tasks) {
|
|
22
46
|
setCurrentTask(task);
|
|
23
47
|
// eslint-disable-next-line no-await-in-loop
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
48
|
+
const subTasks = await runTask(task, ctx.current);
|
|
49
|
+
// subtasks
|
|
50
|
+
if (Array.isArray(subTasks) && subTasks.length > 0 && subTasks.every((task) => 'task' in task)) {
|
|
51
|
+
for (const subTask of subTasks) {
|
|
27
52
|
setCurrentTask(subTask);
|
|
28
53
|
// eslint-disable-next-line no-await-in-loop
|
|
29
|
-
await subTask
|
|
54
|
+
await runTask(subTask, ctx.current);
|
|
30
55
|
}
|
|
31
56
|
}
|
|
32
57
|
}
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"Tasks.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Tasks.tsx"],"names":[],"mappings":"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","sourcesContent":["import {TextAnimation} from './TextAnimation.js'\nimport useLayout from '../hooks/use-layout.js'\nimport useAsyncAndUnmount from '../hooks/use-async-and-unmount.js'\nimport {isUnitTest} from '../../../../public/node/environment/local.js'\nimport {Box, Text} from 'ink'\nimport React, {useRef, useState} from 'react'\n\nconst loadingBarChar = '▀'\n\nexport interface Task<TContext = unknown> {\n title: string\n task: (ctx: TContext, task: Task<TContext>) => Promise<void | Task<TContext>[]>\n retry?: number\n retryCount?: number\n errors?: Error[]\n skip?: (ctx: TContext) => boolean\n}\n\nexport interface Props<TContext> {\n tasks: Task<TContext>[]\n silent?: boolean\n}\n\nenum TasksState {\n Loading = 'loading',\n Success = 'success',\n Failure = 'failure',\n}\n\nasync function runTask<TContext>(task: Task<TContext>, ctx: TContext) {\n task.retryCount = 0\n task.errors = []\n const retry = task?.retry && task?.retry > 0 ? task.retry + 1 : 1\n\n for (let retries = 1; retries <= retry; retries++) {\n try {\n if (task.skip?.(ctx)) {\n return\n }\n // eslint-disable-next-line no-await-in-loop\n return await task.task(ctx, task)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n if (retries === retry) {\n throw error\n } else {\n task.errors.push(error)\n task.retryCount = retries\n }\n }\n }\n}\n\nfunction Tasks<TContext>({tasks, silent = isUnitTest()}: React.PropsWithChildren<Props<TContext>>) {\n const {twoThirds} = useLayout()\n const loadingBar = new Array(twoThirds).fill(loadingBarChar).join('')\n const [currentTask, setCurrentTask] = useState<Task<TContext>>(tasks[0]!)\n const [state, setState] = useState<TasksState>(TasksState.Loading)\n const ctx = useRef<TContext>({} as TContext)\n\n const runTasks = async () => {\n for (const task of tasks) {\n setCurrentTask(task)\n\n // eslint-disable-next-line no-await-in-loop\n const subTasks = await runTask(task, ctx.current)\n\n // subtasks\n if (Array.isArray(subTasks) && subTasks.length > 0 && subTasks.every((task) => 'task' in task)) {\n for (const subTask of subTasks) {\n setCurrentTask(subTask)\n // eslint-disable-next-line no-await-in-loop\n await runTask(subTask, ctx.current)\n }\n }\n }\n }\n\n useAsyncAndUnmount(runTasks, {\n onFulfilled: () => setState(TasksState.Success),\n onRejected: () => setState(TasksState.Failure),\n })\n\n if (silent) {\n return null\n }\n\n return state === TasksState.Loading ? (\n <Box flexDirection=\"column\">\n <TextAnimation text={loadingBar} />\n <Text>{currentTask.title} ...</Text>\n </Box>\n ) : null\n}\n\nexport {Tasks}\n"]}
|