@shopify/cli-kit 3.16.3 → 3.18.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/CHANGELOG.md +26 -0
- package/README.md +1 -1
- package/assets/success.html +1 -1
- package/dist/analytics.d.ts +5 -5
- package/dist/analytics.js +5 -5
- package/dist/analytics.js.map +1 -1
- package/dist/api/common.d.ts +2 -2
- package/dist/api/common.js +2 -2
- package/dist/api/common.js.map +1 -1
- package/dist/api/graphql/index.d.ts +0 -2
- package/dist/api/graphql/index.js +0 -2
- package/dist/api/graphql/index.js.map +1 -1
- package/dist/api/oxygen.d.ts +5 -0
- package/dist/api/oxygen.js +30 -0
- package/dist/api/oxygen.js.map +1 -0
- package/dist/api/partners.d.ts +7 -7
- package/dist/api/partners.js +7 -7
- package/dist/api/partners.js.map +1 -1
- package/dist/api.d.ts +2 -2
- package/dist/api.js +2 -2
- package/dist/api.js.map +1 -1
- package/dist/common/object.d.ts +3 -3
- package/dist/common/object.js +3 -3
- package/dist/common/object.js.map +1 -1
- package/dist/content-tokens.js.map +1 -1
- package/dist/environment/fqdn.d.ts +3 -3
- package/dist/environment/fqdn.js +3 -3
- package/dist/environment/fqdn.js.map +1 -1
- package/dist/environment/local.d.ts +13 -13
- package/dist/environment/local.js +16 -16
- package/dist/environment/local.js.map +1 -1
- package/dist/environment/service.d.ts +1 -0
- package/dist/environment/service.js +3 -0
- package/dist/environment/service.js.map +1 -1
- package/dist/environment/spin.d.ts +12 -12
- package/dist/environment/spin.js +12 -12
- package/dist/environment/spin.js.map +1 -1
- package/dist/environment/utilities.d.ts +0 -2
- package/dist/environment/utilities.js +0 -2
- package/dist/environment/utilities.js.map +1 -1
- package/dist/environment.d.ts +3 -1
- package/dist/environment.js +3 -1
- package/dist/environment.js.map +1 -1
- package/dist/error.d.ts +1 -1
- package/dist/error.js +4 -3
- package/dist/error.js.map +1 -1
- package/dist/file.d.ts +17 -18
- package/dist/file.js +17 -18
- package/dist/file.js.map +1 -1
- package/dist/git.d.ts +1 -1
- package/dist/git.js +5 -2
- package/dist/git.js.map +1 -1
- package/dist/http/fetch.d.ts +2 -2
- package/dist/http/fetch.js +2 -2
- package/dist/http/fetch.js.map +1 -1
- package/dist/http.d.ts +1 -1
- package/dist/http.js +1 -1
- package/dist/http.js.map +1 -1
- package/dist/id.d.ts +1 -1
- package/dist/id.js +1 -1
- package/dist/id.js.map +1 -1
- package/dist/network/service.d.ts +0 -2
- package/dist/network/service.js +0 -1
- package/dist/network/service.js.map +1 -1
- package/dist/node/archiver.d.ts +2 -2
- package/dist/node/archiver.js +2 -2
- package/dist/node/archiver.js.map +1 -1
- package/dist/node/checksum.d.ts +2 -2
- package/dist/node/checksum.js +2 -2
- package/dist/node/checksum.js.map +1 -1
- package/dist/node/cli.d.ts +1 -2
- package/dist/node/cli.js +2 -8
- package/dist/node/cli.js.map +1 -1
- package/dist/node/colors.d.ts +2 -1
- package/dist/node/colors.js +2 -7
- package/dist/node/colors.js.map +1 -1
- package/dist/node/dot-env.d.ts +7 -7
- package/dist/node/dot-env.js +7 -7
- package/dist/node/dot-env.js.map +1 -1
- package/dist/node/framework.d.ts +2 -2
- package/dist/node/framework.js +2 -2
- package/dist/node/framework.js.map +1 -1
- package/dist/node/hooks/prerun.js +6 -6
- package/dist/node/hooks/prerun.js.map +1 -1
- package/dist/node/node-package-manager.d.ts +32 -28
- package/dist/node/node-package-manager.js +29 -29
- package/dist/node/node-package-manager.js.map +1 -1
- package/dist/node/ruby.d.ts +4 -4
- package/dist/node/ruby.js +5 -5
- package/dist/node/ruby.js.map +1 -1
- package/dist/os.d.ts +1 -1
- package/dist/os.js +1 -1
- package/dist/os.js.map +1 -1
- package/dist/output.d.ts +26 -34
- package/dist/output.js +23 -143
- package/dist/output.js.map +1 -1
- package/dist/path.d.ts +4 -4
- package/dist/path.js +4 -4
- package/dist/path.js.map +1 -1
- package/dist/plugins.d.ts +4 -4
- package/dist/plugins.js +4 -4
- package/dist/plugins.js.map +1 -1
- package/dist/port.d.ts +1 -1
- package/dist/port.js +1 -1
- package/dist/port.js.map +1 -1
- package/dist/private/node/ui/alert.d.ts +2 -0
- package/dist/private/node/ui/alert.js +18 -0
- package/dist/private/node/ui/alert.js.map +1 -0
- package/dist/private/node/ui/components/Alert.d.ts +17 -0
- package/dist/private/node/ui/components/Alert.js +21 -0
- package/dist/private/node/ui/components/Alert.js.map +1 -0
- package/dist/private/node/ui/components/Banner.d.ts +7 -0
- package/dist/private/node/ui/components/Banner.js +35 -0
- package/dist/private/node/ui/components/Banner.js.map +1 -0
- package/dist/private/node/ui/components/Command.d.ts +9 -0
- package/dist/private/node/ui/components/Command.js +10 -0
- package/dist/private/node/ui/components/Command.js.map +1 -0
- package/dist/private/node/ui/components/ConcurrentOutput.d.ts +48 -0
- package/dist/private/node/ui/components/ConcurrentOutput.js +98 -0
- package/dist/private/node/ui/components/ConcurrentOutput.js.map +1 -0
- package/dist/private/node/ui/components/Error.d.ts +8 -0
- package/dist/private/node/ui/components/Error.js +13 -0
- package/dist/private/node/ui/components/Error.js.map +1 -0
- package/dist/private/node/ui/components/FatalError.d.ts +7 -0
- package/dist/private/node/ui/components/FatalError.js +42 -0
- package/dist/private/node/ui/components/FatalError.js.map +1 -0
- package/dist/private/node/ui/components/FullScreen.d.ts +8 -0
- package/dist/private/node/ui/components/FullScreen.js +32 -0
- package/dist/private/node/ui/components/FullScreen.js.map +1 -0
- package/dist/private/node/ui/components/Link.d.ts +10 -0
- package/dist/private/node/ui/components/Link.js +14 -0
- package/dist/private/node/ui/components/Link.js.map +1 -0
- package/dist/private/node/ui/components/List.d.ts +13 -0
- package/dist/private/node/ui/components/List.js +19 -0
- package/dist/private/node/ui/components/List.js.map +1 -0
- package/dist/private/node/ui/components/TextAnimation.d.ts +11 -0
- package/dist/private/node/ui/components/TextAnimation.js +46 -0
- package/dist/private/node/ui/components/TextAnimation.js.map +1 -0
- package/dist/private/node/ui/components/TokenizedText.d.ts +21 -0
- package/dist/private/node/ui/components/TokenizedText.js +26 -0
- package/dist/private/node/ui/components/TokenizedText.js.map +1 -0
- package/dist/private/node/ui/error.d.ts +4 -0
- package/dist/private/node/ui/error.js +12 -0
- package/dist/private/node/ui/error.js.map +1 -0
- package/dist/private/node/ui.d.ts +10 -0
- package/dist/private/node/ui.js +47 -0
- package/dist/private/node/ui.js.map +1 -0
- package/dist/public/common/array.d.ts +4 -4
- package/dist/public/common/array.js +4 -4
- package/dist/public/common/array.js.map +1 -1
- package/dist/public/node/ui.d.ts +155 -0
- package/dist/public/node/ui.js +163 -0
- package/dist/public/node/ui.js.map +1 -0
- package/dist/secure-store.d.ts +4 -4
- package/dist/secure-store.js +4 -4
- package/dist/secure-store.js.map +1 -1
- package/dist/session/device-authorization.d.ts +5 -5
- package/dist/session/device-authorization.js +5 -5
- package/dist/session/device-authorization.js.map +1 -1
- package/dist/session/exchange.d.ts +10 -16
- package/dist/session/exchange.js +10 -16
- package/dist/session/exchange.js.map +1 -1
- package/dist/session/post-auth.js +2 -2
- package/dist/session/post-auth.js.map +1 -1
- package/dist/session/redirect-listener.js +1 -1
- package/dist/session/redirect-listener.js.map +1 -1
- package/dist/session/schema.d.ts +3 -2
- package/dist/session/schema.js +3 -2
- package/dist/session/schema.js.map +1 -1
- package/dist/session/scopes.d.ts +3 -3
- package/dist/session/scopes.js +3 -3
- package/dist/session/scopes.js.map +1 -1
- package/dist/session/store.d.ts +2 -2
- package/dist/session/store.js +2 -2
- package/dist/session/store.js.map +1 -1
- package/dist/session/token.d.ts +1 -1
- package/dist/session/token.js +1 -1
- package/dist/session/token.js.map +1 -1
- package/dist/session/validate.d.ts +4 -4
- package/dist/session/validate.js +4 -7
- package/dist/session/validate.js.map +1 -1
- package/dist/session.d.ts +10 -10
- package/dist/session.js +12 -12
- package/dist/session.js.map +1 -1
- package/dist/string.d.ts +2 -2
- package/dist/string.js +2 -2
- package/dist/string.js.map +1 -1
- package/dist/system.d.ts +6 -9
- package/dist/system.js +23 -23
- package/dist/system.js.map +1 -1
- package/dist/template.d.ts +3 -3
- package/dist/template.js +3 -3
- package/dist/template.js.map +1 -1
- package/dist/testing/fixtures/render-concurrent.d.ts +1 -0
- package/dist/testing/fixtures/render-concurrent.js +28 -0
- package/dist/testing/fixtures/render-concurrent.js.map +1 -0
- package/dist/testing/output.d.ts +1 -0
- package/dist/testing/output.js +1 -0
- package/dist/testing/output.js.map +1 -1
- package/dist/testing/store.d.ts +2 -2
- package/dist/testing/store.js +2 -2
- package/dist/testing/store.js.map +1 -1
- package/dist/testing/ui.d.ts +8 -0
- package/dist/testing/ui.js +17 -0
- package/dist/testing/ui.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/ui/inquirer/input.d.ts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.js +17 -8
- package/dist/ui.js.map +1 -1
- package/dist/version.d.ts +3 -3
- package/dist/version.js +3 -3
- package/dist/version.js.map +1 -1
- package/package.json +9 -2
- package/dist/api/graphql/functions/compile_module.d.ts +0 -15
- package/dist/api/graphql/functions/compile_module.js +0 -13
- package/dist/api/graphql/functions/compile_module.js.map +0 -1
- package/dist/api/graphql/functions/module_compilation_status.d.ts +0 -15
- package/dist/api/graphql/functions/module_compilation_status.js +0 -13
- package/dist/api/graphql/functions/module_compilation_status.js.map +0 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Banner } from './Banner.js';
|
|
2
|
+
import { Link } from './Link.js';
|
|
3
|
+
import { List } from './List.js';
|
|
4
|
+
import { TokenizedText } from './TokenizedText.js';
|
|
5
|
+
import { Box, Text } from 'ink';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
const Alert = ({ type, headline, body, nextSteps, reference, link, orderedNextSteps = false }) => {
|
|
8
|
+
return (React.createElement(Banner, { type: type },
|
|
9
|
+
React.createElement(Box, null,
|
|
10
|
+
React.createElement(Text, null, headline)),
|
|
11
|
+
body && (React.createElement(Box, { marginTop: 1 },
|
|
12
|
+
React.createElement(TokenizedText, { item: body }))),
|
|
13
|
+
nextSteps && (React.createElement(Box, { marginTop: 1 },
|
|
14
|
+
React.createElement(List, { title: "Next steps", items: nextSteps, ordered: orderedNextSteps }))),
|
|
15
|
+
reference && (React.createElement(Box, { marginTop: 1 },
|
|
16
|
+
React.createElement(List, { title: "Reference", items: reference }))),
|
|
17
|
+
link && (React.createElement(Box, { marginTop: 1 },
|
|
18
|
+
React.createElement(Link, { url: link.url, label: link.label })))));
|
|
19
|
+
};
|
|
20
|
+
export { Alert };
|
|
21
|
+
//# sourceMappingURL=Alert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Alert.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Alert.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAa,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAgB,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAC/D,OAAO,EAAC,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAA;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAA;AAezB,MAAM,KAAK,GAAyB,CAAC,EAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,gBAAgB,GAAG,KAAK,EAAC,EAAE,EAAE;IACnH,OAAO,CACL,oBAAC,MAAM,IAAC,IAAI,EAAE,IAAI;QAChB,oBAAC,GAAG;YACF,oBAAC,IAAI,QAAE,QAAQ,CAAQ,CACnB;QAEL,IAAI,IAAI,CACP,oBAAC,GAAG,IAAC,SAAS,EAAE,CAAC;YACf,oBAAC,aAAa,IAAC,IAAI,EAAE,IAAI,GAAI,CACzB,CACP;QAEA,SAAS,IAAI,CACZ,oBAAC,GAAG,IAAC,SAAS,EAAE,CAAC;YACf,oBAAC,IAAI,IAAC,KAAK,EAAC,YAAY,EAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,GAAI,CACpE,CACP;QAEA,SAAS,IAAI,CACZ,oBAAC,GAAG,IAAC,SAAS,EAAE,CAAC;YACf,oBAAC,IAAI,IAAC,KAAK,EAAC,WAAW,EAAC,KAAK,EAAE,SAAS,GAAI,CACxC,CACP;QAEA,IAAI,IAAI,CACP,oBAAC,GAAG,IAAC,SAAS,EAAE,CAAC;YACf,oBAAC,IAAI,IAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAI,CACtC,CACP,CACM,CACV,CAAA;AACH,CAAC,CAAA;AAED,OAAO,EAAC,KAAK,EAAC,CAAA","sourcesContent":["import {Banner, BannerType} from './Banner.js'\nimport {Link} from './Link.js'\nimport {List} from './List.js'\nimport {TextTokenItem, TokenizedText} from './TokenizedText.js'\nimport {Box, Text} from 'ink'\nimport React from 'react'\n\nexport interface AlertProps {\n type: Exclude<BannerType, 'error'>\n headline: string\n body?: TextTokenItem\n nextSteps?: TextTokenItem[]\n reference?: TextTokenItem[]\n link?: {\n label: string\n url: string\n }\n orderedNextSteps?: boolean\n}\n\nconst Alert: React.FC<AlertProps> = ({type, headline, body, nextSteps, reference, link, orderedNextSteps = false}) => {\n return (\n <Banner type={type}>\n <Box>\n <Text>{headline}</Text>\n </Box>\n\n {body && (\n <Box marginTop={1}>\n <TokenizedText item={body} />\n </Box>\n )}\n\n {nextSteps && (\n <Box marginTop={1}>\n <List title=\"Next steps\" items={nextSteps} ordered={orderedNextSteps} />\n </Box>\n )}\n\n {reference && (\n <Box marginTop={1}>\n <List title=\"Reference\" items={reference} />\n </Box>\n )}\n\n {link && (\n <Box marginTop={1}>\n <Link url={link.url} label={link.label} />\n </Box>\n )}\n </Banner>\n )\n}\n\nexport {Alert}\n"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Box, Text, useStdout } from 'ink';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
function typeToColor(type) {
|
|
4
|
+
return {
|
|
5
|
+
success: 'green',
|
|
6
|
+
error: 'red',
|
|
7
|
+
warning: 'yellow',
|
|
8
|
+
info: 'dim',
|
|
9
|
+
}[type];
|
|
10
|
+
}
|
|
11
|
+
const BANNER_MIN_WIDTH = 80;
|
|
12
|
+
function calculateWidth(stdout) {
|
|
13
|
+
const fullWidth = stdout?.columns ?? BANNER_MIN_WIDTH;
|
|
14
|
+
const twoThirdsOfWidth = Math.floor((fullWidth / 3) * 2);
|
|
15
|
+
let width;
|
|
16
|
+
if (fullWidth <= BANNER_MIN_WIDTH) {
|
|
17
|
+
width = fullWidth;
|
|
18
|
+
}
|
|
19
|
+
else if (twoThirdsOfWidth < BANNER_MIN_WIDTH) {
|
|
20
|
+
width = BANNER_MIN_WIDTH;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
width = twoThirdsOfWidth;
|
|
24
|
+
}
|
|
25
|
+
return width;
|
|
26
|
+
}
|
|
27
|
+
const Banner = ({ type, children }) => {
|
|
28
|
+
const { stdout } = useStdout();
|
|
29
|
+
return (React.createElement(Box, { width: calculateWidth(stdout), paddingY: 1, paddingX: 2, borderStyle: "round", flexDirection: "column", borderColor: typeToColor(type) },
|
|
30
|
+
React.createElement(Box, { marginTop: -2, marginBottom: 1, marginLeft: -1 },
|
|
31
|
+
React.createElement(Text, { dimColor: true, bold: true }, ` ${type} `)),
|
|
32
|
+
children));
|
|
33
|
+
};
|
|
34
|
+
export { Banner };
|
|
35
|
+
//# sourceMappingURL=Banner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Banner.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Banner.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAE,IAAI,EAAE,SAAS,EAAC,MAAM,KAAK,CAAA;AACxC,OAAO,KAAK,MAAM,OAAO,CAAA;AAQzB,SAAS,WAAW,CAAC,IAAmB;IACtC,OAAO;QACL,OAAO,EAAE,OAAO;QAChB,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE,QAAQ;QACjB,IAAI,EAAE,KAAK;KACZ,CAAC,IAAI,CAAC,CAAA;AACT,CAAC;AAED,MAAM,gBAAgB,GAAG,EAAE,CAAA;AAE3B,SAAS,cAAc,CAAC,MAAsC;IAC5D,MAAM,SAAS,GAAG,MAAM,EAAE,OAAO,IAAI,gBAAgB,CAAA;IACrD,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IACxD,IAAI,KAAK,CAAA;IAET,IAAI,SAAS,IAAI,gBAAgB,EAAE;QACjC,KAAK,GAAG,SAAS,CAAA;KAClB;SAAM,IAAI,gBAAgB,GAAG,gBAAgB,EAAE;QAC9C,KAAK,GAAG,gBAAgB,CAAA;KACzB;SAAM;QACL,KAAK,GAAG,gBAAgB,CAAA;KACzB;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,MAAM,MAAM,GAAoB,CAAC,EAAC,IAAI,EAAE,QAAQ,EAAC,EAAE,EAAE;IACnD,MAAM,EAAC,MAAM,EAAC,GAAG,SAAS,EAAE,CAAA;IAE5B,OAAO,CACL,oBAAC,GAAG,IACF,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,EAC7B,QAAQ,EAAE,CAAC,EACX,QAAQ,EAAE,CAAC,EACX,WAAW,EAAC,OAAO,EACnB,aAAa,EAAC,QAAQ,EACtB,WAAW,EAAE,WAAW,CAAC,IAAI,CAAC;QAE9B,oBAAC,GAAG,IAAC,SAAS,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;YACjD,oBAAC,IAAI,IAAC,QAAQ,QAAC,IAAI,UAAE,IAAI,IAAI,GAAG,CAAQ,CACpC;QACL,QAAQ,CACL,CACP,CAAA;AACH,CAAC,CAAA;AAED,OAAO,EAAC,MAAM,EAAC,CAAA","sourcesContent":["import {Box, Text, useStdout} from 'ink'\nimport React from 'react'\n\nexport type BannerType = 'success' | 'error' | 'warning' | 'info'\n\ninterface Props {\n type: BannerType\n}\n\nfunction typeToColor(type: Props['type']) {\n return {\n success: 'green',\n error: 'red',\n warning: 'yellow',\n info: 'dim',\n }[type]\n}\n\nconst BANNER_MIN_WIDTH = 80\n\nfunction calculateWidth(stdout: NodeJS.WriteStream | undefined) {\n const fullWidth = stdout?.columns ?? BANNER_MIN_WIDTH\n const twoThirdsOfWidth = Math.floor((fullWidth / 3) * 2)\n let width\n\n if (fullWidth <= BANNER_MIN_WIDTH) {\n width = fullWidth\n } else if (twoThirdsOfWidth < BANNER_MIN_WIDTH) {\n width = BANNER_MIN_WIDTH\n } else {\n width = twoThirdsOfWidth\n }\n\n return width\n}\n\nconst Banner: React.FC<Props> = ({type, children}) => {\n const {stdout} = useStdout()\n\n return (\n <Box\n width={calculateWidth(stdout)}\n paddingY={1}\n paddingX={2}\n borderStyle=\"round\"\n flexDirection=\"column\"\n borderColor={typeToColor(type)}\n >\n <Box marginTop={-2} marginBottom={1} marginLeft={-1}>\n <Text dimColor bold>{` ${type} `}</Text>\n </Box>\n {children}\n </Box>\n )\n}\n\nexport {Banner}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Text } from 'ink';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* `Command` displays a command as non-dimmed text.
|
|
5
|
+
*/
|
|
6
|
+
const Command = ({ command }) => {
|
|
7
|
+
return React.createElement(Text, null, command);
|
|
8
|
+
};
|
|
9
|
+
export { Command };
|
|
10
|
+
//# sourceMappingURL=Command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Command.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Command.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,KAAK,CAAA;AACxB,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB;;GAEG;AACH,MAAM,OAAO,GAAoB,CAAC,EAAC,OAAO,EAAiC,EAAe,EAAE;IAC1F,OAAO,oBAAC,IAAI,QAAE,OAAO,CAAQ,CAAA;AAC/B,CAAC,CAAA;AAED,OAAO,EAAC,OAAO,EAAC,CAAA","sourcesContent":["import {Text} from 'ink'\nimport React from 'react'\n\ninterface Props {\n command: string\n}\n\n/**\n * `Command` displays a command as non-dimmed text.\n */\nconst Command: React.FC<Props> = ({command}: React.PropsWithChildren<Props>): JSX.Element => {\n return <Text>{command}</Text>\n}\n\nexport {Command}\n"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { OutputProcess } from '../../../../output.js';
|
|
3
|
+
import { FunctionComponent } from 'react';
|
|
4
|
+
import AbortController from 'abort-controller';
|
|
5
|
+
import { Writable } from 'node:stream';
|
|
6
|
+
export declare type WritableStream = (process: OutputProcess, index: number) => Writable;
|
|
7
|
+
export declare type RunProcesses = (writableStream: WritableStream, unmountInk: (error?: Error | undefined) => void) => Promise<void>;
|
|
8
|
+
interface Props {
|
|
9
|
+
processes: OutputProcess[];
|
|
10
|
+
abortController: AbortController;
|
|
11
|
+
showTimestamps?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Renders output from concurrent processes to the terminal.
|
|
15
|
+
* Output will be divided in a three column layout
|
|
16
|
+
* with the left column containing the timestamp,
|
|
17
|
+
* the right column containing the output,
|
|
18
|
+
* and the middle column containing the process prefix.
|
|
19
|
+
* Every process will be rendered with a different color, up to 4 colors.
|
|
20
|
+
*
|
|
21
|
+
* For example running `shopify app dev`:
|
|
22
|
+
*
|
|
23
|
+
* ```shell
|
|
24
|
+
* 2022-10-10 13:11:03 | backend | npm
|
|
25
|
+
* 2022-10-10 13:11:03 | backend | WARN ignoring workspace config at ...
|
|
26
|
+
* 2022-10-10 13:11:03 | backend |
|
|
27
|
+
* 2022-10-10 13:11:03 | backend |
|
|
28
|
+
* 2022-10-10 13:11:03 | backend | > shopify-app-template-node@0.1.0 dev
|
|
29
|
+
* 2022-10-10 13:11:03 | backend | > cross-env NODE_ENV=development nodemon backend/index.js --watch ./backend
|
|
30
|
+
* 2022-10-10 13:11:03 | backend |
|
|
31
|
+
* 2022-10-10 13:11:03 | backend |
|
|
32
|
+
* 2022-10-10 13:11:03 | frontend |
|
|
33
|
+
* 2022-10-10 13:11:03 | frontend | > starter-react-frontend-app@0.1.0 dev
|
|
34
|
+
* 2022-10-10 13:11:03 | frontend | > cross-env NODE_ENV=development node vite-server.js
|
|
35
|
+
* 2022-10-10 13:11:03 | frontend |
|
|
36
|
+
* 2022-10-10 13:11:03 | frontend |
|
|
37
|
+
* 2022-10-10 13:11:03 | backend | [nodemon] 2.0.19
|
|
38
|
+
* 2022-10-10 13:11:03 | backend |
|
|
39
|
+
* 2022-10-10 13:11:03 | backend | [nodemon] to restart at any time, enter `rs`
|
|
40
|
+
* 2022-10-10 13:11:03 | backend | [nodemon] watching path(s): backend/
|
|
41
|
+
* 2022-10-10 13:11:03 | backend | [nodemon] watching extensions: js,mjs,json
|
|
42
|
+
* 2022-10-10 13:11:03 | backend | [nodemon] starting `node backend/index.js`
|
|
43
|
+
* 2022-10-10 13:11:03 | backend |
|
|
44
|
+
*
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
declare const ConcurrentOutput: FunctionComponent<Props>;
|
|
48
|
+
export default ConcurrentOutput;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { Box, Static, Text, useApp } from 'ink';
|
|
3
|
+
import stripAnsi from 'strip-ansi';
|
|
4
|
+
import { Writable } from 'node:stream';
|
|
5
|
+
const OUTPUT_MIN_WIDTH = 80;
|
|
6
|
+
/**
|
|
7
|
+
* Renders output from concurrent processes to the terminal.
|
|
8
|
+
* Output will be divided in a three column layout
|
|
9
|
+
* with the left column containing the timestamp,
|
|
10
|
+
* the right column containing the output,
|
|
11
|
+
* and the middle column containing the process prefix.
|
|
12
|
+
* Every process will be rendered with a different color, up to 4 colors.
|
|
13
|
+
*
|
|
14
|
+
* For example running `shopify app dev`:
|
|
15
|
+
*
|
|
16
|
+
* ```shell
|
|
17
|
+
* 2022-10-10 13:11:03 | backend | npm
|
|
18
|
+
* 2022-10-10 13:11:03 | backend | WARN ignoring workspace config at ...
|
|
19
|
+
* 2022-10-10 13:11:03 | backend |
|
|
20
|
+
* 2022-10-10 13:11:03 | backend |
|
|
21
|
+
* 2022-10-10 13:11:03 | backend | > shopify-app-template-node@0.1.0 dev
|
|
22
|
+
* 2022-10-10 13:11:03 | backend | > cross-env NODE_ENV=development nodemon backend/index.js --watch ./backend
|
|
23
|
+
* 2022-10-10 13:11:03 | backend |
|
|
24
|
+
* 2022-10-10 13:11:03 | backend |
|
|
25
|
+
* 2022-10-10 13:11:03 | frontend |
|
|
26
|
+
* 2022-10-10 13:11:03 | frontend | > starter-react-frontend-app@0.1.0 dev
|
|
27
|
+
* 2022-10-10 13:11:03 | frontend | > cross-env NODE_ENV=development node vite-server.js
|
|
28
|
+
* 2022-10-10 13:11:03 | frontend |
|
|
29
|
+
* 2022-10-10 13:11:03 | frontend |
|
|
30
|
+
* 2022-10-10 13:11:03 | backend | [nodemon] 2.0.19
|
|
31
|
+
* 2022-10-10 13:11:03 | backend |
|
|
32
|
+
* 2022-10-10 13:11:03 | backend | [nodemon] to restart at any time, enter `rs`
|
|
33
|
+
* 2022-10-10 13:11:03 | backend | [nodemon] watching path(s): backend/
|
|
34
|
+
* 2022-10-10 13:11:03 | backend | [nodemon] watching extensions: js,mjs,json
|
|
35
|
+
* 2022-10-10 13:11:03 | backend | [nodemon] starting `node backend/index.js`
|
|
36
|
+
* 2022-10-10 13:11:03 | backend |
|
|
37
|
+
*
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
const ConcurrentOutput = ({ processes, abortController, showTimestamps = true }) => {
|
|
41
|
+
const [processOutput, setProcessOutput] = useState([]);
|
|
42
|
+
const concurrentColors = ['yellow', 'cyan', 'magenta', 'green', 'blue'];
|
|
43
|
+
const prefixColumnSize = Math.max(...processes.map((process) => process.prefix.length));
|
|
44
|
+
const { exit: unmountInk } = useApp();
|
|
45
|
+
function lineColor(index) {
|
|
46
|
+
const colorIndex = index < concurrentColors.length ? index : index % concurrentColors.length;
|
|
47
|
+
return concurrentColors[colorIndex];
|
|
48
|
+
}
|
|
49
|
+
const writableStream = (process, index) => {
|
|
50
|
+
return new Writable({
|
|
51
|
+
write(chunk, _encoding, next) {
|
|
52
|
+
const lines = stripAnsi(chunk.toString('ascii')).split(/\n/);
|
|
53
|
+
setProcessOutput((previousProcessOutput) => [
|
|
54
|
+
...previousProcessOutput,
|
|
55
|
+
{
|
|
56
|
+
color: lineColor(index),
|
|
57
|
+
prefix: process.prefix,
|
|
58
|
+
lines,
|
|
59
|
+
},
|
|
60
|
+
]);
|
|
61
|
+
next();
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
const runProcesses = async () => {
|
|
66
|
+
try {
|
|
67
|
+
await Promise.all(processes.map(async (process, index) => {
|
|
68
|
+
const stdout = writableStream(process, index);
|
|
69
|
+
const stderr = writableStream(process, index);
|
|
70
|
+
await process.action(stdout, stderr, abortController.signal);
|
|
71
|
+
}));
|
|
72
|
+
unmountInk();
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
abortController.abort();
|
|
76
|
+
unmountInk();
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
82
|
+
runProcesses();
|
|
83
|
+
}, []);
|
|
84
|
+
return (React.createElement(Static, { items: processOutput }, (chunk, index) => {
|
|
85
|
+
return (React.createElement(Box, { flexDirection: "column", key: index }, chunk.lines.map((line, index) => (React.createElement(Box, { key: index, flexDirection: "row" },
|
|
86
|
+
showTimestamps && (React.createElement(Box, null,
|
|
87
|
+
React.createElement(Box, { marginRight: 1 },
|
|
88
|
+
React.createElement(Text, { color: chunk.color }, new Date().toISOString().replace(/T/, ' ').replace(/\..+/, ''))),
|
|
89
|
+
React.createElement(Text, { bold: true, color: chunk.color }, "|"))),
|
|
90
|
+
React.createElement(Box, { width: prefixColumnSize, marginX: 1 },
|
|
91
|
+
React.createElement(Text, { color: chunk.color }, chunk.prefix)),
|
|
92
|
+
React.createElement(Text, { bold: true, color: chunk.color }, "|"),
|
|
93
|
+
React.createElement(Box, { flexGrow: 1, paddingLeft: 1 },
|
|
94
|
+
React.createElement(Text, { color: chunk.color }, line)))))));
|
|
95
|
+
}));
|
|
96
|
+
};
|
|
97
|
+
export default ConcurrentOutput;
|
|
98
|
+
//# sourceMappingURL=ConcurrentOutput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConcurrentOutput.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/ConcurrentOutput.tsx"],"names":[],"mappings":"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","sourcesContent":["import {OutputProcess} from '../../../../output.js'\nimport React, {FunctionComponent, useEffect, useState} from 'react'\nimport {Box, Static, Text, useApp} from 'ink'\nimport stripAnsi from 'strip-ansi'\nimport AbortController from 'abort-controller'\nimport {Writable} from 'node:stream'\n\nexport type WritableStream = (process: OutputProcess, index: number) => Writable\nexport type RunProcesses = (\n writableStream: WritableStream,\n unmountInk: (error?: Error | undefined) => void,\n) => Promise<void>\n\ninterface Props {\n processes: OutputProcess[]\n abortController: AbortController\n showTimestamps?: boolean\n}\ninterface Chunk {\n color: string\n prefix: string\n lines: string[]\n}\n\nconst OUTPUT_MIN_WIDTH = 80\n\n/**\n * Renders output from concurrent processes to the terminal.\n * Output will be divided in a three column layout\n * with the left column containing the timestamp,\n * the right column containing the output,\n * and the middle column containing the process prefix.\n * Every process will be rendered with a different color, up to 4 colors.\n *\n * For example running `shopify app dev`:\n *\n * ```shell\n * 2022-10-10 13:11:03 | backend | npm\n * 2022-10-10 13:11:03 | backend | WARN ignoring workspace config at ...\n * 2022-10-10 13:11:03 | backend |\n * 2022-10-10 13:11:03 | backend |\n * 2022-10-10 13:11:03 | backend | > shopify-app-template-node@0.1.0 dev\n * 2022-10-10 13:11:03 | backend | > cross-env NODE_ENV=development nodemon backend/index.js --watch ./backend\n * 2022-10-10 13:11:03 | backend |\n * 2022-10-10 13:11:03 | backend |\n * 2022-10-10 13:11:03 | frontend |\n * 2022-10-10 13:11:03 | frontend | > starter-react-frontend-app@0.1.0 dev\n * 2022-10-10 13:11:03 | frontend | > cross-env NODE_ENV=development node vite-server.js\n * 2022-10-10 13:11:03 | frontend |\n * 2022-10-10 13:11:03 | frontend |\n * 2022-10-10 13:11:03 | backend | [nodemon] 2.0.19\n * 2022-10-10 13:11:03 | backend |\n * 2022-10-10 13:11:03 | backend | [nodemon] to restart at any time, enter `rs`\n * 2022-10-10 13:11:03 | backend | [nodemon] watching path(s): backend/\n * 2022-10-10 13:11:03 | backend | [nodemon] watching extensions: js,mjs,json\n * 2022-10-10 13:11:03 | backend | [nodemon] starting `node backend/index.js`\n * 2022-10-10 13:11:03 | backend |\n *\n * ```\n */\nconst ConcurrentOutput: FunctionComponent<Props> = ({processes, abortController, showTimestamps = true}) => {\n const [processOutput, setProcessOutput] = useState<Chunk[]>([])\n const concurrentColors = ['yellow', 'cyan', 'magenta', 'green', 'blue']\n const prefixColumnSize = Math.max(...processes.map((process) => process.prefix.length))\n const {exit: unmountInk} = useApp()\n\n function lineColor(index: number) {\n const colorIndex = index < concurrentColors.length ? index : index % concurrentColors.length\n return concurrentColors[colorIndex]!\n }\n\n const writableStream = (process: OutputProcess, index: number) => {\n return new Writable({\n write(chunk, _encoding, next) {\n const lines = stripAnsi(chunk.toString('ascii')).split(/\\n/)\n\n setProcessOutput((previousProcessOutput) => [\n ...previousProcessOutput,\n {\n color: lineColor(index),\n prefix: process.prefix,\n lines,\n },\n ])\n\n next()\n },\n })\n }\n\n const runProcesses = async () => {\n try {\n await Promise.all(\n processes.map(async (process, index) => {\n const stdout = writableStream(process, index)\n const stderr = writableStream(process, index)\n\n await process.action(stdout, stderr, abortController.signal)\n }),\n )\n\n unmountInk()\n } catch (error) {\n abortController.abort()\n unmountInk()\n throw error\n }\n }\n\n useEffect(() => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n runProcesses()\n }, [])\n\n return (\n <Static items={processOutput}>\n {(chunk, index) => {\n return (\n <Box flexDirection=\"column\" key={index}>\n {chunk.lines.map((line, index) => (\n <Box key={index} flexDirection=\"row\">\n {showTimestamps && (\n <Box>\n <Box marginRight={1}>\n <Text color={chunk.color}>{new Date().toISOString().replace(/T/, ' ').replace(/\\..+/, '')}</Text>\n </Box>\n\n <Text bold color={chunk.color}>\n |\n </Text>\n </Box>\n )}\n\n <Box width={prefixColumnSize} marginX={1}>\n <Text color={chunk.color}>{chunk.prefix}</Text>\n </Box>\n\n <Text bold color={chunk.color}>\n |\n </Text>\n\n <Box flexGrow={1} paddingLeft={1}>\n <Text color={chunk.color}>{line}</Text>\n </Box>\n </Box>\n ))}\n </Box>\n )\n }}\n </Static>\n )\n}\n\nexport default ConcurrentOutput\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Banner } from './Banner.js';
|
|
2
|
+
import { TokenizedText } from './TokenizedText.js';
|
|
3
|
+
import { Box, Text } from 'ink';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
const Error = ({ headline, tryMessage }) => {
|
|
6
|
+
return (React.createElement(Banner, { type: "error" },
|
|
7
|
+
React.createElement(Box, null,
|
|
8
|
+
React.createElement(Text, null, headline)),
|
|
9
|
+
tryMessage && (React.createElement(Box, { marginTop: 1 },
|
|
10
|
+
React.createElement(TokenizedText, { item: tryMessage })))));
|
|
11
|
+
};
|
|
12
|
+
export { Error };
|
|
13
|
+
//# sourceMappingURL=Error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Error.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Error.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA;AAClC,OAAO,EAAgB,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAC/D,OAAO,EAAC,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAA;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB,MAAM,KAAK,GAAyB,CAAC,EAAC,QAAQ,EAAE,UAAU,EAAC,EAAE,EAAE;IAC7D,OAAO,CACL,oBAAC,MAAM,IAAC,IAAI,EAAC,OAAO;QAClB,oBAAC,GAAG;YACF,oBAAC,IAAI,QAAE,QAAQ,CAAQ,CACnB;QAEL,UAAU,IAAI,CACb,oBAAC,GAAG,IAAC,SAAS,EAAE,CAAC;YACf,oBAAC,aAAa,IAAC,IAAI,EAAE,UAAU,GAAI,CAC/B,CACP,CACM,CACV,CAAA;AACH,CAAC,CAAA;AAED,OAAO,EAAC,KAAK,EAAC,CAAA","sourcesContent":["import {Banner} from './Banner.js'\nimport {TextTokenItem, TokenizedText} from './TokenizedText.js'\nimport {Box, Text} from 'ink'\nimport React from 'react'\n\nexport interface ErrorProps {\n headline: string\n tryMessage?: TextTokenItem\n}\n\nconst Error: React.FC<ErrorProps> = ({headline, tryMessage}) => {\n return (\n <Banner type=\"error\">\n <Box>\n <Text>{headline}</Text>\n </Box>\n\n {tryMessage && (\n <Box marginTop={1}>\n <TokenizedText item={tryMessage} />\n </Box>\n )}\n </Banner>\n )\n}\n\nexport {Error}\n"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Banner } from './Banner.js';
|
|
2
|
+
import { TokenizedText } from './TokenizedText.js';
|
|
3
|
+
import { Bug, cleanSingleStackTracePath } from '../../../../error.js';
|
|
4
|
+
import { Box, Text } from 'ink';
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import StackTracey from 'stacktracey';
|
|
7
|
+
const FatalError = ({ error }) => {
|
|
8
|
+
let stack;
|
|
9
|
+
if (error instanceof Bug) {
|
|
10
|
+
stack = new StackTracey(error);
|
|
11
|
+
stack.items.forEach((item) => {
|
|
12
|
+
item.file = cleanSingleStackTracePath(item.file);
|
|
13
|
+
});
|
|
14
|
+
stack = stack.withSources();
|
|
15
|
+
stack = stack
|
|
16
|
+
.filter((entry) => {
|
|
17
|
+
return !entry.file.includes('@oclif/core');
|
|
18
|
+
})
|
|
19
|
+
.map((item) => {
|
|
20
|
+
/** We make the paths relative to the packages/ directory */
|
|
21
|
+
const fileShortComponents = item.fileShort.split('packages/');
|
|
22
|
+
item.fileShort = fileShortComponents.length === 2 ? fileShortComponents[1] : fileShortComponents[0];
|
|
23
|
+
return item;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
return (React.createElement(Banner, { type: "error" },
|
|
27
|
+
React.createElement(Box, null,
|
|
28
|
+
React.createElement(Text, null, error.message)),
|
|
29
|
+
error.tryMessage && (React.createElement(Box, { marginTop: 1 },
|
|
30
|
+
React.createElement(TokenizedText, { item: error.tryMessage }))),
|
|
31
|
+
stack && stack.items.length !== 0 && (React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
32
|
+
React.createElement(Text, { dimColor: true }, "To investigate the issue, examine this stack trace:"),
|
|
33
|
+
stack.items.map((item, index) => (React.createElement(Box, { flexDirection: "column", key: index },
|
|
34
|
+
React.createElement(Text, null,
|
|
35
|
+
"at",
|
|
36
|
+
item.calleeShort && React.createElement(Text, { color: "yellow" }, ` ${item.calleeShort}`),
|
|
37
|
+
item.fileShort && ` (${item.fileShort}:${item.line})`),
|
|
38
|
+
React.createElement(Box, { paddingLeft: 1 },
|
|
39
|
+
React.createElement(Text, { dimColor: true }, item.sourceLine?.trim())))))))));
|
|
40
|
+
};
|
|
41
|
+
export { FatalError };
|
|
42
|
+
//# sourceMappingURL=FatalError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FatalError.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/FatalError.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAA;AAClC,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAC,GAAG,EAAE,yBAAyB,EAAQ,MAAM,sBAAsB,CAAA;AAC1E,OAAO,EAAC,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAA;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,WAAW,MAAM,aAAa,CAAA;AAMrC,MAAM,UAAU,GAA8B,CAAC,EAAC,KAAK,EAAC,EAAE,EAAE;IACxD,IAAI,KAAK,CAAA;IAET,IAAI,KAAK,YAAY,GAAG,EAAE;QACxB,KAAK,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,CAAA;QAC9B,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YAC3B,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClD,CAAC,CAAC,CAAA;QAEF,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAA;QAC3B,KAAK,GAAG,KAAK;aACV,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YAChB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAA;QAC5C,CAAC,CAAC;aACD,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACZ,4DAA4D;YAC5D,MAAM,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;YAC7D,IAAI,CAAC,SAAS,GAAG,mBAAmB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAE,CAAA;YACrG,OAAO,IAAI,CAAA;QACb,CAAC,CAAC,CAAA;KACL;IAED,OAAO,CACL,oBAAC,MAAM,IAAC,IAAI,EAAC,OAAO;QAClB,oBAAC,GAAG;YACF,oBAAC,IAAI,QAAE,KAAK,CAAC,OAAO,CAAQ,CACxB;QAEL,KAAK,CAAC,UAAU,IAAI,CACnB,oBAAC,GAAG,IAAC,SAAS,EAAE,CAAC;YACf,oBAAC,aAAa,IAAC,IAAI,EAAE,KAAK,CAAC,UAAU,GAAI,CACrC,CACP;QACA,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CACpC,oBAAC,GAAG,IAAC,SAAS,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ;YACvC,oBAAC,IAAI,IAAC,QAAQ,gEAA2D;YACxE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAChC,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,GAAG,EAAE,KAAK;gBACpC,oBAAC,IAAI;;oBACA,IAAI,CAAC,WAAW,IAAI,oBAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,IAAE,IAAI,IAAI,CAAC,WAAW,EAAE,CAAQ;oBAC1E,IAAI,CAAC,SAAS,IAAI,KAAK,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,GAAG,CACjD;gBACP,oBAAC,GAAG,IAAC,WAAW,EAAE,CAAC;oBACjB,oBAAC,IAAI,IAAC,QAAQ,UAAE,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,CAAQ,CAC3C,CACF,CACP,CAAC,CACE,CACP,CACM,CACV,CAAA;AACH,CAAC,CAAA;AAED,OAAO,EAAC,UAAU,EAAC,CAAA","sourcesContent":["import {Banner} from './Banner.js'\nimport {TokenizedText} from './TokenizedText.js'\nimport {Bug, cleanSingleStackTracePath, Fatal} from '../../../../error.js'\nimport {Box, Text} from 'ink'\nimport React from 'react'\nimport StackTracey from 'stacktracey'\n\nexport interface FatalErrorProps {\n error: Fatal\n}\n\nconst FatalError: React.FC<FatalErrorProps> = ({error}) => {\n let stack\n\n if (error instanceof Bug) {\n stack = new StackTracey(error)\n stack.items.forEach((item) => {\n item.file = cleanSingleStackTracePath(item.file)\n })\n\n stack = stack.withSources()\n stack = stack\n .filter((entry) => {\n return !entry.file.includes('@oclif/core')\n })\n .map((item) => {\n /** We make the paths relative to the packages/ directory */\n const fileShortComponents = item.fileShort.split('packages/')\n item.fileShort = fileShortComponents.length === 2 ? fileShortComponents[1]! : fileShortComponents[0]!\n return item\n })\n }\n\n return (\n <Banner type=\"error\">\n <Box>\n <Text>{error.message}</Text>\n </Box>\n\n {error.tryMessage && (\n <Box marginTop={1}>\n <TokenizedText item={error.tryMessage} />\n </Box>\n )}\n {stack && stack.items.length !== 0 && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>To investigate the issue, examine this stack trace:</Text>\n {stack.items.map((item, index) => (\n <Box flexDirection=\"column\" key={index}>\n <Text>\n at{item.calleeShort && <Text color=\"yellow\">{` ${item.calleeShort}`}</Text>}\n {item.fileShort && ` (${item.fileShort}:${item.line})`}\n </Text>\n <Box paddingLeft={1}>\n <Text dimColor>{item.sourceLine?.trim()}</Text>\n </Box>\n </Box>\n ))}\n </Box>\n )}\n </Banner>\n )\n}\n\nexport {FatalError}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* `FullScreen` renders all output in a new buffer and makes it full screen. This is useful when:
|
|
4
|
+
* - You want to preserve terminal history. `ink` [normally clears the terminal history](https://github.com/vadimdemedes/ink/issues/382) if the rendered output is taller than the terminal window. By rendering in a separate buffer history will be preserved and will be visible after pressing `Ctrl+C`.
|
|
5
|
+
* - You want to respond to the resize event of the terminal. Whenever the user resizes their terminal window the output's height and width will be recalculated and re-rendered properly.
|
|
6
|
+
*/
|
|
7
|
+
declare const FullScreen: React.FC;
|
|
8
|
+
export default FullScreen;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Box } from 'ink';
|
|
2
|
+
import React, { useEffect, useState } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* `FullScreen` renders all output in a new buffer and makes it full screen. This is useful when:
|
|
5
|
+
* - You want to preserve terminal history. `ink` [normally clears the terminal history](https://github.com/vadimdemedes/ink/issues/382) if the rendered output is taller than the terminal window. By rendering in a separate buffer history will be preserved and will be visible after pressing `Ctrl+C`.
|
|
6
|
+
* - You want to respond to the resize event of the terminal. Whenever the user resizes their terminal window the output's height and width will be recalculated and re-rendered properly.
|
|
7
|
+
*/
|
|
8
|
+
const FullScreen = (props) => {
|
|
9
|
+
const [size, setSize] = useState({
|
|
10
|
+
columns: process.stdout.columns,
|
|
11
|
+
rows: process.stdout.rows,
|
|
12
|
+
});
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
function onResize() {
|
|
15
|
+
setSize({
|
|
16
|
+
columns: process.stdout.columns,
|
|
17
|
+
rows: process.stdout.rows,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
process.stdout.on('resize', onResize);
|
|
21
|
+
// switch to an alternate buffer
|
|
22
|
+
process.stdout.write('\u001B[?1049h');
|
|
23
|
+
return () => {
|
|
24
|
+
process.stdout.off('resize', onResize);
|
|
25
|
+
// switch back to the main buffer
|
|
26
|
+
process.stdout.write('\u001B[?1049l');
|
|
27
|
+
};
|
|
28
|
+
}, []);
|
|
29
|
+
return (React.createElement(Box, { width: size.columns, height: size.rows }, props.children));
|
|
30
|
+
};
|
|
31
|
+
export default FullScreen;
|
|
32
|
+
//# sourceMappingURL=FullScreen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FullScreen.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/FullScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,EAAC,SAAS,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAA;AAEhD;;;;GAIG;AACH,MAAM,UAAU,GAAa,CAAC,KAAmC,EAAe,EAAE;IAChF,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC;QAC/B,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO;QAC/B,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;KAC1B,CAAC,CAAA;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,SAAS,QAAQ;YACf,OAAO,CAAC;gBACN,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO;gBAC/B,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;aAC1B,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;QACrC,gCAAgC;QAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAA;QACrC,OAAO,GAAG,EAAE;YACV,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;YACtC,iCAAiC;YACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAA;QACvC,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,CACL,oBAAC,GAAG,IAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,IACxC,KAAK,CAAC,QAAQ,CACX,CACP,CAAA;AACH,CAAC,CAAA;AAED,eAAe,UAAU,CAAA","sourcesContent":["import {Box} from 'ink'\nimport React, {useEffect, useState} from 'react'\n\n/**\n * `FullScreen` renders all output in a new buffer and makes it full screen. This is useful when:\n * - You want to preserve terminal history. `ink` [normally clears the terminal history](https://github.com/vadimdemedes/ink/issues/382) if the rendered output is taller than the terminal window. By rendering in a separate buffer history will be preserved and will be visible after pressing `Ctrl+C`.\n * - You want to respond to the resize event of the terminal. Whenever the user resizes their terminal window the output's height and width will be recalculated and re-rendered properly.\n */\nconst FullScreen: React.FC = (props: {children?: React.ReactNode}): JSX.Element => {\n const [size, setSize] = useState({\n columns: process.stdout.columns,\n rows: process.stdout.rows,\n })\n\n useEffect(() => {\n function onResize() {\n setSize({\n columns: process.stdout.columns,\n rows: process.stdout.rows,\n })\n }\n\n process.stdout.on('resize', onResize)\n // switch to an alternate buffer\n process.stdout.write('\\u001B[?1049h')\n return () => {\n process.stdout.off('resize', onResize)\n // switch back to the main buffer\n process.stdout.write('\\u001B[?1049l')\n }\n }, [])\n\n return (\n <Box width={size.columns} height={size.rows}>\n {props.children}\n </Box>\n )\n}\n\nexport default FullScreen\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Text, Transform } from 'ink';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import terminalLink from 'terminal-link';
|
|
4
|
+
/**
|
|
5
|
+
* `Link` displays a clickable link when supported by the terminal.
|
|
6
|
+
*/
|
|
7
|
+
const Link = ({ url, label }) => {
|
|
8
|
+
return (React.createElement(Text, null,
|
|
9
|
+
React.createElement(Text, { dimColor: true }, `${label}: `),
|
|
10
|
+
React.createElement(Transform, { transform: (children) => terminalLink(children, url, { fallback: false }) },
|
|
11
|
+
React.createElement(Text, { underline: true }, url))));
|
|
12
|
+
};
|
|
13
|
+
export { Link };
|
|
14
|
+
//# sourceMappingURL=Link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Link.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/Link.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,SAAS,EAAC,MAAM,KAAK,CAAA;AACnC,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,YAAY,MAAM,eAAe,CAAA;AAOxC;;GAEG;AACH,MAAM,IAAI,GAAoB,CAAC,EAAC,GAAG,EAAE,KAAK,EAAiC,EAAe,EAAE;IAC1F,OAAO,CACL,oBAAC,IAAI;QACH,oBAAC,IAAI,IAAC,QAAQ,UAAE,GAAG,KAAK,IAAI,CAAQ;QACpC,oBAAC,SAAS,IAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAC,QAAQ,EAAE,KAAK,EAAC,CAAC;YAChF,oBAAC,IAAI,IAAC,SAAS,UAAE,GAAG,CAAQ,CAClB,CACP,CACR,CAAA;AACH,CAAC,CAAA;AAED,OAAO,EAAC,IAAI,EAAC,CAAA","sourcesContent":["import {Text, Transform} from 'ink'\nimport React from 'react'\nimport terminalLink from 'terminal-link'\n\ninterface Props {\n url: string\n label: string\n}\n\n/**\n * `Link` displays a clickable link when supported by the terminal.\n */\nconst Link: React.FC<Props> = ({url, label}: React.PropsWithChildren<Props>): JSX.Element => {\n return (\n <Text>\n <Text dimColor>{`${label}: `}</Text>\n <Transform transform={(children) => terminalLink(children, url, {fallback: false})}>\n <Text underline>{url}</Text>\n </Transform>\n </Text>\n )\n}\n\nexport {Link}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { TextTokenItem } from './TokenizedText.js';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
interface Props {
|
|
4
|
+
title: string;
|
|
5
|
+
items: TextTokenItem[];
|
|
6
|
+
ordered?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* `List` displays an unordered or ordered list with text aligned with the bullet point
|
|
10
|
+
* and wrapped to the container width.
|
|
11
|
+
*/
|
|
12
|
+
declare const List: React.FC<Props>;
|
|
13
|
+
export { List };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { TokenizedText } from './TokenizedText.js';
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
const DOT = '•';
|
|
5
|
+
/**
|
|
6
|
+
* `List` displays an unordered or ordered list with text aligned with the bullet point
|
|
7
|
+
* and wrapped to the container width.
|
|
8
|
+
*/
|
|
9
|
+
const List = ({ title, items, ordered = false }) => {
|
|
10
|
+
return (React.createElement(Box, { flexDirection: "column" },
|
|
11
|
+
React.createElement(Text, { dimColor: true }, title),
|
|
12
|
+
items.map((item, index) => (React.createElement(Box, { key: index },
|
|
13
|
+
React.createElement(Box, null,
|
|
14
|
+
React.createElement(Text, { dimColor: true }, ` ${ordered ? `${index + 1}.` : DOT}`)),
|
|
15
|
+
React.createElement(Box, { flexGrow: 1, marginLeft: 1 },
|
|
16
|
+
React.createElement(TokenizedText, { item: item })))))));
|
|
17
|
+
};
|
|
18
|
+
export { List };
|
|
19
|
+
//# sourceMappingURL=List.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"List.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/List.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgB,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAC/D,OAAO,EAAC,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAA;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAA;AAQzB,MAAM,GAAG,GAAG,GAAG,CAAA;AAEf;;;GAGG;AACH,MAAM,IAAI,GAAoB,CAAC,EAAC,KAAK,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,EAAiC,EAAe,EAAE;IAC7G,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ;QACzB,oBAAC,IAAI,IAAC,QAAQ,UAAE,KAAK,CAAQ;QAC5B,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAC1B,oBAAC,GAAG,IAAC,GAAG,EAAE,KAAK;YACb,oBAAC,GAAG;gBACF,oBAAC,IAAI,IAAC,QAAQ,UAAE,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAQ,CAC1D;YAEN,oBAAC,GAAG,IAAC,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC;gBAC7B,oBAAC,aAAa,IAAC,IAAI,EAAE,IAAI,GAAI,CACzB,CACF,CACP,CAAC,CACE,CACP,CAAA;AACH,CAAC,CAAA;AAED,OAAO,EAAC,IAAI,EAAC,CAAA","sourcesContent":["import {TextTokenItem, TokenizedText} from './TokenizedText.js'\nimport {Box, Text} from 'ink'\nimport React from 'react'\n\ninterface Props {\n title: string\n items: TextTokenItem[]\n ordered?: boolean\n}\n\nconst DOT = '•'\n\n/**\n * `List` displays an unordered or ordered list with text aligned with the bullet point\n * and wrapped to the container width.\n */\nconst List: React.FC<Props> = ({title, items, ordered = false}: React.PropsWithChildren<Props>): JSX.Element => {\n return (\n <Box flexDirection=\"column\">\n <Text dimColor>{title}</Text>\n {items.map((item, index) => (\n <Box key={index}>\n <Box>\n <Text dimColor>{` ${ordered ? `${index + 1}.` : DOT}`}</Text>\n </Box>\n\n <Box flexGrow={1} marginLeft={1}>\n <TokenizedText item={item} />\n </Box>\n </Box>\n ))}\n </Box>\n )\n}\n\nexport {List}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
declare type AnimationName = 'rainbow' | 'pulse' | 'glitch' | 'radar' | 'neon' | 'karaoke';
|
|
3
|
+
interface Props {
|
|
4
|
+
name?: AnimationName;
|
|
5
|
+
speed?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* `TextAnimation` applies animations from [chalk-animation](https://github.com/bokub/chalk-animation) to `Text` Children
|
|
9
|
+
*/
|
|
10
|
+
declare const TextAnimation: React.FC<Props>;
|
|
11
|
+
export { TextAnimation };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { renderString } from '../../ui.js';
|
|
2
|
+
import chalkAnimation from 'chalk-animation';
|
|
3
|
+
import { Text } from 'ink';
|
|
4
|
+
import React, { useEffect, useState } from 'react';
|
|
5
|
+
const delays = {
|
|
6
|
+
rainbow: 15,
|
|
7
|
+
pulse: 16,
|
|
8
|
+
glitch: 55,
|
|
9
|
+
radar: 50,
|
|
10
|
+
neon: 500,
|
|
11
|
+
karaoke: 50,
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* `TextAnimation` applies animations from [chalk-animation](https://github.com/bokub/chalk-animation) to `Text` Children
|
|
15
|
+
*/
|
|
16
|
+
const TextAnimation = ({ name = 'rainbow', speed = 1, children, }) => {
|
|
17
|
+
const [animationTimeout, setAnimationTimeout] = useState(null);
|
|
18
|
+
const animation = chalkAnimation[name]('').stop();
|
|
19
|
+
const [frame, setFrame] = useState('');
|
|
20
|
+
const start = () => {
|
|
21
|
+
const { output } = renderString(React.createElement(Text, null, children));
|
|
22
|
+
// There's probably some clashing between `chalk-animation` and Ink's rendering mechanism
|
|
23
|
+
// (which uses `log-update`). The solution is to remove the ANSI escape sequence at the
|
|
24
|
+
// start of the frame that we're getting from `chalk-animation` that tells the terminal to
|
|
25
|
+
// clear the lines.
|
|
26
|
+
const frame = animation
|
|
27
|
+
.replace(output ?? '')
|
|
28
|
+
.frame()
|
|
29
|
+
.replace(/^\u001B\[(\d)F\u001B\[G\u001B\[2K/, ''); // eslint-disable-line no-control-regex
|
|
30
|
+
setFrame(frame);
|
|
31
|
+
setAnimationTimeout(setTimeout(() => {
|
|
32
|
+
start();
|
|
33
|
+
}, delays[name] / speed));
|
|
34
|
+
};
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
start();
|
|
37
|
+
return () => {
|
|
38
|
+
if (animationTimeout)
|
|
39
|
+
clearTimeout(animationTimeout);
|
|
40
|
+
setAnimationTimeout(null);
|
|
41
|
+
};
|
|
42
|
+
}, []);
|
|
43
|
+
return React.createElement(Text, null, frame);
|
|
44
|
+
};
|
|
45
|
+
export { TextAnimation };
|
|
46
|
+
//# sourceMappingURL=TextAnimation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TextAnimation.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/TextAnimation.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,aAAa,CAAA;AACxC,OAAO,cAAc,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAC,IAAI,EAAC,MAAM,KAAK,CAAA;AACxB,OAAO,KAAK,EAAE,EAAC,SAAS,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAA;AAShD,MAAM,MAAM,GAAqC;IAC/C,OAAO,EAAE,EAAE;IACX,KAAK,EAAE,EAAE;IACT,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,GAAG;IACT,OAAO,EAAE,EAAE;CACZ,CAAA;AAED;;GAEG;AACH,MAAM,aAAa,GAAoB,CAAC,EACtC,IAAI,GAAG,SAAS,EAChB,KAAK,GAAG,CAAC,EACT,QAAQ,GACuB,EAAe,EAAE;IAChD,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,QAAQ,CAAwB,IAAI,CAAC,CAAA;IACrF,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IACjD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAEtC,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,MAAM,EAAC,MAAM,EAAC,GAAG,YAAY,CAAC,oBAAC,IAAI,QAAE,QAAQ,CAAQ,CAAC,CAAA;QAEtD,yFAAyF;QACzF,uFAAuF;QACvF,0FAA0F;QAC1F,mBAAmB;QAEnB,MAAM,KAAK,GAAG,SAAS;aACpB,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;aACrB,KAAK,EAAE;aACP,OAAO,CAAC,mCAAmC,EAAE,EAAE,CAAC,CAAA,CAAC,uCAAuC;QAE3F,QAAQ,CAAC,KAAK,CAAC,CAAA;QAEf,mBAAmB,CACjB,UAAU,CAAC,GAAG,EAAE;YACd,KAAK,EAAE,CAAA;QACT,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CACzB,CAAA;IACH,CAAC,CAAA;IAED,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,EAAE,CAAA;QAEP,OAAO,GAAG,EAAE;YACV,IAAI,gBAAgB;gBAAE,YAAY,CAAC,gBAAgB,CAAC,CAAA;YAEpD,mBAAmB,CAAC,IAAI,CAAC,CAAA;QAC3B,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,oBAAC,IAAI,QAAE,KAAK,CAAQ,CAAA;AAC7B,CAAC,CAAA;AAED,OAAO,EAAC,aAAa,EAAC,CAAA","sourcesContent":["import {renderString} from '../../ui.js'\nimport chalkAnimation from 'chalk-animation'\nimport {Text} from 'ink'\nimport React, {useEffect, useState} from 'react'\n\ntype AnimationName = 'rainbow' | 'pulse' | 'glitch' | 'radar' | 'neon' | 'karaoke'\n\ninterface Props {\n name?: AnimationName\n speed?: number\n}\n\nconst delays: {[key in AnimationName]: number} = {\n rainbow: 15,\n pulse: 16,\n glitch: 55,\n radar: 50,\n neon: 500,\n karaoke: 50,\n}\n\n/**\n * `TextAnimation` applies animations from [chalk-animation](https://github.com/bokub/chalk-animation) to `Text` Children\n */\nconst TextAnimation: React.FC<Props> = ({\n name = 'rainbow',\n speed = 1,\n children,\n}: React.PropsWithChildren<Props>): JSX.Element => {\n const [animationTimeout, setAnimationTimeout] = useState<NodeJS.Timeout | null>(null)\n const animation = chalkAnimation[name]('').stop()\n const [frame, setFrame] = useState('')\n\n const start = () => {\n const {output} = renderString(<Text>{children}</Text>)\n\n // There's probably some clashing between `chalk-animation` and Ink's rendering mechanism\n // (which uses `log-update`). The solution is to remove the ANSI escape sequence at the\n // start of the frame that we're getting from `chalk-animation` that tells the terminal to\n // clear the lines.\n\n const frame = animation\n .replace(output ?? '')\n .frame()\n .replace(/^\\u001B\\[(\\d)F\\u001B\\[G\\u001B\\[2K/, '') // eslint-disable-line no-control-regex\n\n setFrame(frame)\n\n setAnimationTimeout(\n setTimeout(() => {\n start()\n }, delays[name] / speed),\n )\n }\n\n useEffect(() => {\n start()\n\n return () => {\n if (animationTimeout) clearTimeout(animationTimeout)\n\n setAnimationTimeout(null)\n }\n }, [])\n\n return <Text>{frame}</Text>\n}\n\nexport {TextAnimation}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface CommandToken {
|
|
3
|
+
command: string;
|
|
4
|
+
}
|
|
5
|
+
interface LinkToken {
|
|
6
|
+
link: {
|
|
7
|
+
label: string;
|
|
8
|
+
url: string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export declare type TextToken = string | CommandToken | LinkToken;
|
|
12
|
+
export declare type TextTokenItem = TextToken | TextToken[];
|
|
13
|
+
interface Props {
|
|
14
|
+
item: TextToken | TextToken[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* `TokenizedText` renders a text string with tokens that can be either strings,
|
|
18
|
+
* links, and commands.
|
|
19
|
+
*/
|
|
20
|
+
declare const TokenizedText: React.FC<Props>;
|
|
21
|
+
export { TokenizedText };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Command } from './Command.js';
|
|
2
|
+
import { Link } from './Link.js';
|
|
3
|
+
import { Text } from 'ink';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
/**
|
|
6
|
+
* `TokenizedText` renders a text string with tokens that can be either strings,
|
|
7
|
+
* links, and commands.
|
|
8
|
+
*/
|
|
9
|
+
const TokenizedText = ({ item }) => {
|
|
10
|
+
if (typeof item === 'string') {
|
|
11
|
+
return React.createElement(Text, { dimColor: true }, item);
|
|
12
|
+
}
|
|
13
|
+
else if ('command' in item) {
|
|
14
|
+
return React.createElement(Command, { command: item.command });
|
|
15
|
+
}
|
|
16
|
+
else if ('link' in item) {
|
|
17
|
+
return React.createElement(Link, { ...item.link });
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
return (React.createElement(Text, null, item.map((listItem, index) => (React.createElement(Text, { key: index },
|
|
21
|
+
React.createElement(TokenizedText, { item: listItem }),
|
|
22
|
+
index < item.length - 1 && React.createElement(Text, null, " "))))));
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
export { TokenizedText };
|
|
26
|
+
//# sourceMappingURL=TokenizedText.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenizedText.js","sourceRoot":"","sources":["../../../../../src/private/node/ui/components/TokenizedText.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,cAAc,CAAA;AACpC,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAC,IAAI,EAAC,MAAM,KAAK,CAAA;AACxB,OAAO,KAAK,MAAM,OAAO,CAAA;AAoBzB;;;GAGG;AACH,MAAM,aAAa,GAAoB,CAAC,EAAC,IAAI,EAAC,EAAE,EAAE;IAChD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;QAC5B,OAAO,oBAAC,IAAI,IAAC,QAAQ,UAAE,IAAI,CAAQ,CAAA;KACpC;SAAM,IAAI,SAAS,IAAI,IAAI,EAAE;QAC5B,OAAO,oBAAC,OAAO,IAAC,OAAO,EAAE,IAAI,CAAC,OAAO,GAAI,CAAA;KAC1C;SAAM,IAAI,MAAM,IAAI,IAAI,EAAE;QACzB,OAAO,oBAAC,IAAI,OAAK,IAAI,CAAC,IAAI,GAAI,CAAA;KAC/B;SAAM;QACL,OAAO,CACL,oBAAC,IAAI,QACF,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,CAC7B,oBAAC,IAAI,IAAC,GAAG,EAAE,KAAK;YACd,oBAAC,aAAa,IAAC,IAAI,EAAE,QAAQ,GAAI;YAChC,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,oBAAC,IAAI,YAAS,CACrC,CACR,CAAC,CACG,CACR,CAAA;KACF;AACH,CAAC,CAAA;AAED,OAAO,EAAC,aAAa,EAAC,CAAA","sourcesContent":["import {Command} from './Command.js'\nimport {Link} from './Link.js'\nimport {Text} from 'ink'\nimport React from 'react'\n\ninterface CommandToken {\n command: string\n}\n\ninterface LinkToken {\n link: {\n label: string\n url: string\n }\n}\n\nexport type TextToken = string | CommandToken | LinkToken\nexport type TextTokenItem = TextToken | TextToken[]\n\ninterface Props {\n item: TextToken | TextToken[]\n}\n\n/**\n * `TokenizedText` renders a text string with tokens that can be either strings,\n * links, and commands.\n */\nconst TokenizedText: React.FC<Props> = ({item}) => {\n if (typeof item === 'string') {\n return <Text dimColor>{item}</Text>\n } else if ('command' in item) {\n return <Command command={item.command} />\n } else if ('link' in item) {\n return <Link {...item.link} />\n } else {\n return (\n <Text>\n {item.map((listItem, index) => (\n <Text key={index}>\n <TokenizedText item={listItem} />\n {index < item.length - 1 && <Text> </Text>}\n </Text>\n ))}\n </Text>\n )\n }\n}\n\nexport {TokenizedText}\n"]}
|