dappbooster 2.0.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/app.d.ts +3 -0
  2. package/dist/app.js +49 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +6 -0
  5. package/dist/components/Ask.d.ts +11 -0
  6. package/dist/components/Ask.js +18 -0
  7. package/dist/components/Divider.d.ts +5 -0
  8. package/dist/components/Divider.js +4 -0
  9. package/dist/components/MainTitle.d.ts +3 -0
  10. package/dist/components/MainTitle.js +6 -0
  11. package/dist/components/Multiselect/MultiSelect.d.ts +33 -0
  12. package/dist/components/Multiselect/MultiSelect.js +68 -0
  13. package/dist/components/Multiselect/components/Checkbox.d.ts +6 -0
  14. package/dist/components/Multiselect/components/Checkbox.js +6 -0
  15. package/dist/components/Multiselect/components/Indicator.d.ts +6 -0
  16. package/dist/components/Multiselect/components/Indicator.js +6 -0
  17. package/dist/components/Multiselect/components/Item.d.ts +7 -0
  18. package/dist/components/Multiselect/components/Item.js +4 -0
  19. package/dist/components/Multiselect/index.d.ts +1 -0
  20. package/dist/components/Multiselect/index.js +1 -0
  21. package/dist/components/steps/CloneRepo/CloneRepo.d.ts +13 -0
  22. package/dist/components/steps/CloneRepo/CloneRepo.js +13 -0
  23. package/dist/components/steps/CloneRepo/Commands.d.ts +12 -0
  24. package/dist/components/steps/CloneRepo/Commands.js +29 -0
  25. package/dist/components/steps/FileCleanup.d.ts +18 -0
  26. package/dist/components/steps/FileCleanup.js +72 -0
  27. package/dist/components/steps/Install/CustomInstallation.d.ts +16 -0
  28. package/dist/components/steps/Install/CustomInstallation.js +31 -0
  29. package/dist/components/steps/Install/FullInstallation.d.ts +7 -0
  30. package/dist/components/steps/Install/FullInstallation.js +10 -0
  31. package/dist/components/steps/Install/Install.d.ts +12 -0
  32. package/dist/components/steps/Install/Install.js +29 -0
  33. package/dist/components/steps/Install/InstallAllPackages.d.ts +7 -0
  34. package/dist/components/steps/Install/InstallAllPackages.js +9 -0
  35. package/dist/components/steps/InstallationMode.d.ts +8 -0
  36. package/dist/components/steps/InstallationMode.js +28 -0
  37. package/dist/components/steps/OptionalPackages.d.ts +15 -0
  38. package/dist/components/steps/OptionalPackages.js +51 -0
  39. package/dist/components/steps/PostInstall.d.ts +16 -0
  40. package/dist/components/steps/PostInstall.js +79 -0
  41. package/dist/components/steps/ProjectName.d.ts +14 -0
  42. package/dist/components/steps/ProjectName.js +25 -0
  43. package/dist/constants/config.d.ts +4 -0
  44. package/dist/constants/config.js +18 -0
  45. package/dist/types/types.d.ts +10 -0
  46. package/dist/types/types.js +1 -0
  47. package/dist/utils/utils.d.ts +32 -0
  48. package/dist/utils/utils.js +47 -0
  49. package/package.json +30 -19
  50. package/readme.md +39 -0
  51. package/.nvmrc +0 -1
  52. package/.prettierrc +0 -7
  53. package/LICENSE +0 -21
  54. package/README.md +0 -36
  55. package/import/config.js +0 -17
  56. package/import/git.js +0 -56
  57. package/import/install.js +0 -199
  58. package/import/user-prompts.js +0 -145
  59. package/index.js +0 -33
package/dist/app.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const App: () => React.JSX.Element;
3
+ export default App;
package/dist/app.js ADDED
@@ -0,0 +1,49 @@
1
+ import { Box } from 'ink';
2
+ import React, { useState, useMemo, useCallback } from 'react';
3
+ import MainTitle from './components/MainTitle.js';
4
+ import CloneRepo from './components/steps/CloneRepo/CloneRepo.js';
5
+ import FileCleanup from './components/steps/FileCleanup.js';
6
+ import Install from './components/steps/Install/Install.js';
7
+ import InstallationMode from './components/steps/InstallationMode.js';
8
+ import OptionalPackages from './components/steps/OptionalPackages.js';
9
+ import PostInstall from './components/steps/PostInstall.js';
10
+ import ProjectName from './components/steps/ProjectName.js';
11
+ import { canShowStep } from './utils/utils.js';
12
+ const App = () => {
13
+ const [projectName, setProjectName] = useState('');
14
+ const [currentStep, setCurrentStep] = useState(1);
15
+ const [setupType, setSetupType] = useState();
16
+ const [selectedFeatures, setSelectedFeatures] = useState();
17
+ const finishStep = useCallback(() => setCurrentStep(currentStep + 1), [currentStep]);
18
+ const onSelectSetupType = useCallback((item) => setSetupType(item), []);
19
+ const onSelectSelectedFeatures = useCallback((selectedItems) => setSelectedFeatures([...selectedItems]), []);
20
+ const steps = useMemo(() => [
21
+ React.createElement(ProjectName, { onCompletion: finishStep, onSubmit: setProjectName, projectName: projectName, key: 1 }),
22
+ React.createElement(CloneRepo, { onCompletion: finishStep, projectName: projectName, key: 2 }),
23
+ React.createElement(InstallationMode, { onCompletion: finishStep, onSelect: onSelectSetupType, key: 3 }),
24
+ React.createElement(OptionalPackages, { installation: setupType?.value, onCompletion: finishStep, onSubmit: onSelectSelectedFeatures, key: 4 }),
25
+ React.createElement(Install, { installationConfig: {
26
+ installationType: setupType?.value,
27
+ selectedFeatures: selectedFeatures,
28
+ }, onCompletion: finishStep, projectName: projectName, key: 5 }),
29
+ React.createElement(FileCleanup, { installationConfig: {
30
+ installationType: setupType?.value,
31
+ selectedFeatures: selectedFeatures,
32
+ }, onCompletion: finishStep, projectName: projectName, key: 6 }),
33
+ React.createElement(PostInstall, { projectName: projectName, installationConfig: {
34
+ installationType: setupType?.value,
35
+ selectedFeatures: selectedFeatures,
36
+ }, key: 7 }),
37
+ ], [
38
+ finishStep,
39
+ onSelectSelectedFeatures,
40
+ setupType?.value,
41
+ selectedFeatures,
42
+ onSelectSetupType,
43
+ projectName,
44
+ ]);
45
+ return (React.createElement(Box, { flexDirection: 'column', rowGap: 1, width: 80 },
46
+ React.createElement(MainTitle, null),
47
+ steps.map((item, index) => canShowStep(currentStep, index + 1) && item)));
48
+ };
49
+ export default App;
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ import { render } from 'ink';
3
+ import React from 'react';
4
+ import App from './app.js';
5
+ console.clear();
6
+ render(React.createElement(App, null));
@@ -0,0 +1,11 @@
1
+ import { type FC } from 'react';
2
+ interface Props {
3
+ answer?: string;
4
+ errorMessage?: string;
5
+ onSubmit: (value: string) => void;
6
+ question: string;
7
+ tip?: string;
8
+ placeholder?: string;
9
+ }
10
+ declare const Ask: FC<Props>;
11
+ export default Ask;
@@ -0,0 +1,18 @@
1
+ import { Box, Text } from 'ink';
2
+ import TextInput from 'ink-text-input';
3
+ import React, { useMemo, useState } from 'react';
4
+ import { isAnswerConfirmed } from '../utils/utils.js';
5
+ const Ask = ({ question, onSubmit, answer, tip, errorMessage, placeholder }) => {
6
+ const [input, setInput] = useState('');
7
+ const answered = useMemo(() => isAnswerConfirmed(answer, errorMessage), [answer, errorMessage]);
8
+ return (React.createElement(Box, { flexDirection: 'column', rowGap: 1 },
9
+ React.createElement(Box, { flexDirection: 'column' },
10
+ React.createElement(Box, null,
11
+ React.createElement(Text, { color: 'whiteBright' },
12
+ question,
13
+ ": "),
14
+ answered ? (React.createElement(Text, { bold: true, color: 'green' }, answer)) : (React.createElement(TextInput, { onChange: setInput, onSubmit: onSubmit, placeholder: placeholder, value: input }))),
15
+ tip && React.createElement(Text, { color: 'gray' }, tip)),
16
+ errorMessage && (React.createElement(Text, { bold: true, color: 'red' }, errorMessage))));
17
+ };
18
+ export default Ask;
@@ -0,0 +1,5 @@
1
+ import { type FC } from 'react';
2
+ declare const Divider: FC<{
3
+ title: string;
4
+ }>;
5
+ export default Divider;
@@ -0,0 +1,4 @@
1
+ import BaseDivider from 'ink-divider';
2
+ import React from 'react';
3
+ const Divider = ({ title }) => (React.createElement(BaseDivider, { titlePadding: 2, titleColor: 'whiteBright', title: title }));
4
+ export default Divider;
@@ -0,0 +1,3 @@
1
+ import { type FC } from 'react';
2
+ declare const MainTitle: FC;
3
+ export default MainTitle;
@@ -0,0 +1,6 @@
1
+ import BigText from 'ink-big-text';
2
+ import Gradient from 'ink-gradient';
3
+ import React from 'react';
4
+ const MainTitle = () => (React.createElement(Gradient, { colors: ['#ff438c', '#bb1d79', '#8b46a4', '#6a2581'] },
5
+ React.createElement(BigText, { lineHeight: 1, font: 'chrome', text: "dAppBooster" })));
6
+ export default MainTitle;
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import CheckBox from './components/Checkbox.js';
3
+ import Indicator from './components/Indicator.js';
4
+ import ItemComponent from './components/Item.js';
5
+ type Item<T> = {
6
+ label: string;
7
+ value: T;
8
+ key?: string | number;
9
+ };
10
+ type MultiSelectProps<T> = {
11
+ items: Item<T>[];
12
+ defaultSelected?: Item<T>[];
13
+ focus?: boolean;
14
+ initialIndex?: number;
15
+ indicatorComponent?: React.FC<{
16
+ isHighlighted: boolean;
17
+ }>;
18
+ checkboxComponent?: React.FC<{
19
+ isSelected: boolean;
20
+ }>;
21
+ itemComponent?: React.FC<{
22
+ isHighlighted: boolean;
23
+ label: string;
24
+ }>;
25
+ limit?: number | null;
26
+ onSelect?: (selectedItem: Item<T>) => void;
27
+ onUnselect?: (unselectedItem: Item<T>) => void;
28
+ onSubmit?: (selectedItems: Item<T>[]) => void;
29
+ onHighlight?: (highlightedItem: Item<T>) => void;
30
+ };
31
+ declare const MultiSelect: <T>({ items, defaultSelected, focus, initialIndex, indicatorComponent, checkboxComponent, itemComponent, limit, onSelect, onUnselect, onSubmit, onHighlight, }: MultiSelectProps<T>) => React.JSX.Element;
32
+ export default MultiSelect;
33
+ export { Indicator, ItemComponent, CheckBox, type Item };
@@ -0,0 +1,68 @@
1
+ import { Box, useInput } from 'ink';
2
+ import React, { useCallback, useState } from 'react';
3
+ import CheckBox from './components/Checkbox.js';
4
+ import Indicator from './components/Indicator.js';
5
+ import ItemComponent from './components/Item.js';
6
+ const MultiSelect = ({ items = [], defaultSelected = [], focus = true, initialIndex = 0, indicatorComponent = Indicator, checkboxComponent = CheckBox, itemComponent = ItemComponent, limit = null, onSelect = () => { }, onUnselect = () => { }, onSubmit = () => { }, onHighlight = () => { }, }) => {
7
+ const [highlightedIndex, setHighlightedIndex] = useState(initialIndex);
8
+ const [selectedItems, setSelectedItems] = useState(defaultSelected);
9
+ const hasLimit = limit !== null && limit < items.length;
10
+ const slicedItems = hasLimit ? items.slice(0, limit) : items;
11
+ const includesItems = useCallback((item, selectedItems) => {
12
+ return (selectedItems.filter((selectedItem) => selectedItem.value === item.value && selectedItem.label === item.label).length > 0);
13
+ }, []);
14
+ const handleSelect = useCallback((item) => {
15
+ if (includesItems(item, selectedItems)) {
16
+ const newSelectedItems = selectedItems.filter((selectedItem) => selectedItem.value !== item.value && selectedItem.label !== item.label);
17
+ setSelectedItems(newSelectedItems);
18
+ onUnselect(item);
19
+ }
20
+ else {
21
+ const newSelectedItems = [...selectedItems, item];
22
+ setSelectedItems(newSelectedItems);
23
+ onSelect(item);
24
+ }
25
+ }, [selectedItems, onSelect, onUnselect, includesItems]);
26
+ const handleSubmit = useCallback(() => {
27
+ onSubmit(selectedItems);
28
+ }, [selectedItems, onSubmit]);
29
+ useInput(useCallback((input, key) => {
30
+ if (key.upArrow) {
31
+ setHighlightedIndex((prevIndex) => {
32
+ const index = prevIndex === 0 ? slicedItems.length - 1 : prevIndex - 1;
33
+ // biome-ignore lint/style/noNonNullAssertion: <explanation>
34
+ onHighlight(slicedItems[index]);
35
+ return index;
36
+ });
37
+ }
38
+ else if (key.downArrow) {
39
+ setHighlightedIndex((prevIndex) => {
40
+ const index = prevIndex === slicedItems.length - 1 ? 0 : prevIndex + 1;
41
+ // biome-ignore lint/style/noNonNullAssertion: <explanation>
42
+ onHighlight(slicedItems[index]);
43
+ return index;
44
+ });
45
+ }
46
+ else if (key.return) {
47
+ handleSubmit();
48
+ }
49
+ else if (input === ' ') {
50
+ // biome-ignore lint/style/noNonNullAssertion: <explanation>
51
+ handleSelect(slicedItems[highlightedIndex]);
52
+ }
53
+ }, [onHighlight, handleSelect, handleSubmit, slicedItems, highlightedIndex]), { isActive: focus });
54
+ return (React.createElement(Box, { flexDirection: "column" }, slicedItems.map((item, index) => {
55
+ const key = item.key || item.label;
56
+ const isHighlighted = index === highlightedIndex;
57
+ const isSelected = includesItems(item, selectedItems);
58
+ return (React.createElement(Box, { key: key },
59
+ React.createElement(indicatorComponent, { isHighlighted }),
60
+ React.createElement(checkboxComponent, { isSelected }),
61
+ React.createElement(itemComponent, {
62
+ ...item,
63
+ isHighlighted,
64
+ })));
65
+ })));
66
+ };
67
+ export default MultiSelect;
68
+ export { Indicator, ItemComponent, CheckBox };
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ type CheckBoxProps = {
3
+ isSelected: boolean;
4
+ };
5
+ declare const CheckBox: ({ isSelected }: CheckBoxProps) => React.JSX.Element;
6
+ export default CheckBox;
@@ -0,0 +1,6 @@
1
+ import figures from 'figures';
2
+ import { Box, Text } from 'ink';
3
+ import React from 'react';
4
+ const CheckBox = ({ isSelected = false }) => (React.createElement(Box, { marginRight: 1 },
5
+ React.createElement(Text, { color: isSelected ? 'green' : 'white' }, isSelected ? figures.circleFilled : figures.circle)));
6
+ export default CheckBox;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ type IndicatorProps = {
3
+ isHighlighted: boolean;
4
+ };
5
+ declare const Indicator: ({ isHighlighted }: IndicatorProps) => React.JSX.Element;
6
+ export default Indicator;
@@ -0,0 +1,6 @@
1
+ import figures from 'figures';
2
+ import { Box, Text } from 'ink';
3
+ import React from 'react';
4
+ const Indicator = ({ isHighlighted = false }) => (React.createElement(Box, { marginRight: 1 },
5
+ React.createElement(Text, { color: isHighlighted ? 'green' : undefined }, isHighlighted ? figures.pointer : ' ')));
6
+ export default Indicator;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ type ItemProps = {
3
+ isHighlighted: boolean;
4
+ label: string;
5
+ };
6
+ declare const Item: ({ isHighlighted, label }: ItemProps) => React.JSX.Element;
7
+ export default Item;
@@ -0,0 +1,4 @@
1
+ import { Text } from 'ink';
2
+ import React from 'react';
3
+ const Item = ({ isHighlighted = false, label }) => (React.createElement(Text, { color: isHighlighted ? 'green' : 'white', bold: isHighlighted }, label));
4
+ export default Item;
@@ -0,0 +1 @@
1
+ export { default, type Item, Indicator, CheckBox, ItemComponent } from './MultiSelect.js';
@@ -0,0 +1 @@
1
+ export { default, Indicator, CheckBox, ItemComponent } from './MultiSelect.js';
@@ -0,0 +1,13 @@
1
+ import { type FC } from 'react';
2
+ interface Props {
3
+ projectName: string;
4
+ onCompletion: () => void;
5
+ }
6
+ /**
7
+ * Step for cloning the repository.
8
+ * @param projectName
9
+ * @param onCompletion
10
+ * @constructor
11
+ */
12
+ declare const CloneRepo: FC<Props>;
13
+ export default CloneRepo;
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import Divider from '../../Divider.js';
3
+ import Commands from './Commands.js';
4
+ /**
5
+ * Step for cloning the repository.
6
+ * @param projectName
7
+ * @param onCompletion
8
+ * @constructor
9
+ */
10
+ const CloneRepo = ({ projectName, onCompletion }) => (React.createElement(React.Fragment, null,
11
+ React.createElement(Divider, { title: 'Git tasks' }),
12
+ React.createElement(Commands, { projectName: projectName, onCompletion: onCompletion })));
13
+ export default CloneRepo;
@@ -0,0 +1,12 @@
1
+ import { type FC } from 'react';
2
+ interface Props {
3
+ projectName: string;
4
+ onCompletion: () => void;
5
+ }
6
+ /**
7
+ * Executes all the commands to clone the dAppBooster repository.
8
+ * @param projectName
9
+ * @param onCompletion
10
+ */
11
+ declare const Commands: FC<Props>;
12
+ export default Commands;
@@ -0,0 +1,29 @@
1
+ import { join } from 'node:path';
2
+ import * as process from 'node:process';
3
+ import { Box, Text } from 'ink';
4
+ import { Script, Spawn } from 'ink-spawn';
5
+ import React from 'react';
6
+ import { repoUrl } from '../../../constants/config.js';
7
+ /**
8
+ * Executes all the commands to clone the dAppBooster repository.
9
+ * @param projectName
10
+ * @param onCompletion
11
+ */
12
+ const Commands = ({ projectName, onCompletion }) => {
13
+ const projectFolder = join(process.cwd(), projectName);
14
+ return (React.createElement(Box, { flexDirection: 'column', gap: 0 },
15
+ React.createElement(Script, null,
16
+ React.createElement(Box, { columnGap: 1 },
17
+ React.createElement(Text, { color: 'whiteBright' }, "Cloning dAppBooster in"),
18
+ React.createElement(Text, { italic: true }, projectName)),
19
+ React.createElement(Spawn, { shell: true, silent: true, successText: 'Done!', failureText: `Failed to clone the project, check if a folder called "${projectName}" already exists and your read/write permissions...`, runningText: 'Working...', command: "git", args: ['clone', '--depth', '1', '--no-checkout', repoUrl, projectName] }),
20
+ React.createElement(Text, { color: 'whiteBright' }, "Fetching tags"),
21
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: 'git', args: ['fetch', '--tags'], runningText: 'Working...', successText: 'Done!', failureText: 'Error...' }),
22
+ React.createElement(Text, { color: 'whiteBright' }, "Checking out latest tag"),
23
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, command: "git", args: ['checkout $(git describe --tags `git rev-list --tags --max-count=1`)'], successText: "Done!", failureText: 'Error...' }),
24
+ React.createElement(Text, { color: 'whiteBright' }, "Removing .git folder"),
25
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, command: "rm", args: ['-rf', '.git'], successText: "Done!", failureText: 'Error...' }),
26
+ React.createElement(Text, { color: 'whiteBright' }, "Initializing Git repository"),
27
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, command: "git", args: ['init'], successText: "Done!", failureText: 'Error...', onCompletion: onCompletion }))));
28
+ };
29
+ export default Commands;
@@ -0,0 +1,18 @@
1
+ import { type FC } from 'react';
2
+ import type { InstallationType, MultiSelectItem } from '../../types/types.js';
3
+ interface Props {
4
+ onCompletion: () => void;
5
+ projectName: string;
6
+ installationConfig: {
7
+ installationType: InstallationType | undefined;
8
+ selectedFeatures?: Array<MultiSelectItem>;
9
+ };
10
+ }
11
+ /**
12
+ * Performs file cleanup after the installation process
13
+ * @param onCompletion
14
+ * @param installation
15
+ * @param projectName
16
+ */
17
+ declare const FileCleanup: FC<Props>;
18
+ export default FileCleanup;
@@ -0,0 +1,72 @@
1
+ import { readFileSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { Box, Text } from 'ink';
4
+ import { Script, Spawn } from 'ink-spawn';
5
+ import React, { useMemo } from 'react';
6
+ import { featureSelected, getProjectFolder } from '../../utils/utils.js';
7
+ import Divider from '../Divider.js';
8
+ const packageJSONCleanup = (projectFolder, selectedFeatures) => {
9
+ const packageJSONPath = join(projectFolder, 'package.json');
10
+ const packageJSON = JSON.parse(readFileSync(packageJSONPath, 'utf8'));
11
+ if (!featureSelected('subgraph', selectedFeatures)) {
12
+ packageJSON.scripts['subgraph-codegen'] = undefined;
13
+ }
14
+ if (!featureSelected('typedoc', selectedFeatures)) {
15
+ packageJSON.scripts['typedoc:build'] = undefined;
16
+ }
17
+ if (!featureSelected('vocs', selectedFeatures)) {
18
+ packageJSON.scripts['docs:build'] = undefined;
19
+ packageJSON.scripts['docs:dev'] = undefined;
20
+ packageJSON.scripts['docs:preview'] = undefined;
21
+ }
22
+ if (!featureSelected('husky', selectedFeatures)) {
23
+ packageJSON.scripts.prepare = undefined;
24
+ }
25
+ writeFileSync(packageJSONPath, `${JSON.stringify(packageJSON, null, 2)}\n`);
26
+ };
27
+ /**
28
+ * Performs file cleanup after the installation process
29
+ * @param onCompletion
30
+ * @param installation
31
+ * @param projectName
32
+ */
33
+ const FileCleanup = ({ onCompletion, installationConfig, projectName }) => {
34
+ const { installationType, selectedFeatures } = installationConfig;
35
+ const projectFolder = useMemo(() => getProjectFolder(projectName), [projectName]);
36
+ const currentHomeFolder = `${projectFolder}/src/components/pageComponents/home`;
37
+ return (React.createElement(React.Fragment, null,
38
+ React.createElement(Divider, { title: 'File cleanup' }),
39
+ React.createElement(Box, { flexDirection: 'column', gap: 0 },
40
+ React.createElement(Script, null,
41
+ installationType === 'custom' && (React.createElement(Script, { onCompletion: () => packageJSONCleanup(projectFolder, selectedFeatures) },
42
+ !featureSelected('demo', selectedFeatures) && (React.createElement(Script, null,
43
+ React.createElement(Text, { color: 'whiteBright' }, "Component demos"),
44
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: "rm", args: ['-rf', currentHomeFolder], runningText: 'Removing home files...', successText: 'Done!', failureText: 'Error...' }),
45
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: "mkdir", args: ['-p', currentHomeFolder], runningText: 'Creating home folder...', successText: 'Done!', failureText: 'Error...' }),
46
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: "cp", args: ['./.install-files/home/index.tsx', currentHomeFolder], runningText: 'Creating new home page index file...', successText: 'Done!', failureText: 'Error...' }))),
47
+ !featureSelected('subgraph', selectedFeatures) && (React.createElement(Script, null,
48
+ React.createElement(Text, { color: 'whiteBright' }, "Subgraph"),
49
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: "rm", args: ['-rf', './src/subgraphs'], runningText: 'Removing subgraphs folder...', successText: 'Done!', failureText: 'Error...' }),
50
+ featureSelected('demo', selectedFeatures) && (React.createElement(Script, null,
51
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: "rm", args: ['-rf', `${currentHomeFolder}/Examples/demos/subgraphs`], runningText: 'Removing subgraphs demos folder...', successText: 'Done!', failureText: 'Error...' }),
52
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: "rm", args: [`${currentHomeFolder}/Examples/index.tsx`], runningText: 'Removing examples index file...', successText: 'Done!', failureText: 'Error...' }),
53
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: "cp", args: [
54
+ './.install-files/home/Examples/index.tsx',
55
+ `${currentHomeFolder}/Examples/index.tsx`,
56
+ ], runningText: 'Creating new examples index file...', successText: 'Done!', failureText: 'Error...' }))))),
57
+ !featureSelected('typedoc', selectedFeatures) && (React.createElement(Script, null,
58
+ React.createElement(Text, { color: 'whiteBright' }, "Typedoc"),
59
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: "rm", args: ['./typedoc.json'], runningText: 'Removing config...', successText: 'Done!', failureText: 'Error...' }))),
60
+ !featureSelected('vocs', selectedFeatures) && (React.createElement(Script, null,
61
+ React.createElement(Text, { color: 'whiteBright' }, "Vocs"),
62
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: "rm", args: ['./vocs.config.ts'], runningText: 'Removing config...', successText: 'Done!', failureText: 'Error...' }),
63
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: "rm", args: ['-rf', './docs'], runningText: 'Removing docs folder...', successText: 'Done!', failureText: 'Error...' }))),
64
+ !featureSelected('husky', selectedFeatures) && (React.createElement(Script, null,
65
+ React.createElement(Text, { color: 'whiteBright' }, "Husky"),
66
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: "rm", args: ['-rf', './.husky'], runningText: 'Removing Husky folder...', successText: 'Done!', failureText: 'Error...' }),
67
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: "rm", args: ['./.lintstagedrc.mjs'], runningText: 'Removing lint-staged config...', successText: 'Done!', failureText: 'Error...' }),
68
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: "rm", args: ['./commitlint.config.js'], runningText: 'Removing commitlint config...', successText: 'Done!', failureText: 'Error...' }))))),
69
+ React.createElement(Text, { color: 'whiteBright' }, "Install script"),
70
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: "rm", args: ['-rf', './.install-files'], runningText: 'Removing folder...', successText: 'Done!', failureText: 'Error...', onCompletion: onCompletion })))));
71
+ };
72
+ export default FileCleanup;
@@ -0,0 +1,16 @@
1
+ import { type FC } from 'react';
2
+ import type { MultiSelectItem } from '../../../types/types.js';
3
+ interface Props {
4
+ onCompletion: () => void;
5
+ projectFolder: string;
6
+ selectedFeatures?: Array<MultiSelectItem>;
7
+ }
8
+ /**
9
+ * Performs a custom installation based on the selected features: basically we tell `pnpm` what
10
+ * features to remove (everything's included in package.json by default to simplify things)
11
+ * @param onCompletion
12
+ * @param selectedFeatures
13
+ * @param projectFolder
14
+ */
15
+ declare const CustomInstallation: FC<Props>;
16
+ export default CustomInstallation;
@@ -0,0 +1,31 @@
1
+ import { Box, Text } from 'ink';
2
+ import { Script, Spawn } from 'ink-spawn';
3
+ import React from 'react';
4
+ import { getPackages } from '../../../utils/utils.js';
5
+ import InstallAllPackages from './InstallAllPackages.js';
6
+ /**
7
+ * Performs a custom installation based on the selected features: basically we tell `pnpm` what
8
+ * features to remove (everything's included in package.json by default to simplify things)
9
+ * @param onCompletion
10
+ * @param selectedFeatures
11
+ * @param projectFolder
12
+ */
13
+ const CustomInstallation = ({ onCompletion, selectedFeatures, projectFolder }) => {
14
+ // Collects the packages to remove based on the selected features and makes
15
+ // a string out of them so that we can pass it to `pnpm remove` command.
16
+ const packagesToRemove = [
17
+ ...getPackages('subgraph', selectedFeatures),
18
+ ...getPackages('typedoc', selectedFeatures),
19
+ ...getPackages('vocs', selectedFeatures),
20
+ ...getPackages('husky', selectedFeatures),
21
+ ]
22
+ .join(' ')
23
+ .trim();
24
+ return (React.createElement(Box, { flexDirection: 'column', gap: 0 }, !packagesToRemove ? (React.createElement(Script, null,
25
+ React.createElement(InstallAllPackages, { projectFolder: projectFolder, onCompletion: onCompletion }))) : (React.createElement(Script, null,
26
+ React.createElement(Text, { color: 'whiteBright' }, "Installing packages"),
27
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: 'pnpm', args: ['remove', packagesToRemove], runningText: 'Working...', successText: 'Done!', failureText: 'Error...' }),
28
+ React.createElement(Text, { color: 'whiteBright' }, "Executing post-install scripts"),
29
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: 'pnpm', args: ['run', 'postinstall'], runningText: 'Working...', successText: 'Done!', failureText: 'Error...', onCompletion: onCompletion })))));
30
+ };
31
+ export default CustomInstallation;
@@ -0,0 +1,7 @@
1
+ import { type FC } from 'react';
2
+ interface Props {
3
+ projectFolder: string;
4
+ onCompletion?: () => void;
5
+ }
6
+ declare const FullInstallation: FC<Props>;
7
+ export default FullInstallation;
@@ -0,0 +1,10 @@
1
+ import { Box } from 'ink';
2
+ import { Script } from 'ink-spawn';
3
+ import React from 'react';
4
+ import InstallAllPackages from './InstallAllPackages.js';
5
+ const FullInstallation = ({ onCompletion, projectFolder }) => {
6
+ return (React.createElement(Box, { flexDirection: 'column', gap: 0 },
7
+ React.createElement(Script, null,
8
+ React.createElement(InstallAllPackages, { projectFolder: projectFolder, onCompletion: onCompletion }))));
9
+ };
10
+ export default FullInstallation;
@@ -0,0 +1,12 @@
1
+ import { type FC } from 'react';
2
+ import type { InstallationType, MultiSelectItem } from '../../../types/types.js';
3
+ interface Props {
4
+ installationConfig: {
5
+ installationType: InstallationType | undefined;
6
+ selectedFeatures?: Array<MultiSelectItem>;
7
+ };
8
+ projectName: string;
9
+ onCompletion: () => void;
10
+ }
11
+ declare const Install: FC<Props>;
12
+ export default Install;
@@ -0,0 +1,29 @@
1
+ import { Box, Text } from 'ink';
2
+ import { Script, Spawn } from 'ink-spawn';
3
+ import React, { useMemo } from 'react';
4
+ import { getProjectFolder } from '../../../utils/utils.js';
5
+ import Divider from '../../Divider.js';
6
+ import CustomInstallation from './CustomInstallation.js';
7
+ import FullInstallation from './FullInstallation.js';
8
+ const Install = ({ projectName, onCompletion, installationConfig }) => {
9
+ const { installationType, selectedFeatures } = installationConfig;
10
+ const projectFolder = useMemo(() => getProjectFolder(projectName), [projectName]);
11
+ const title = installationType
12
+ ? installationType[0]?.toUpperCase() + installationType.slice(1)
13
+ : '';
14
+ return (React.createElement(React.Fragment, null,
15
+ React.createElement(Divider, { title: `${title ?? 'Full'} installation` }),
16
+ React.createElement(Box, { flexDirection: 'column', gap: 0 },
17
+ React.createElement(Script, null,
18
+ React.createElement(Box, { columnGap: 1 },
19
+ React.createElement(Text, { color: 'whiteBright' },
20
+ "Creating",
21
+ ' ',
22
+ React.createElement(Text, { italic: true, color: 'white' }, ".env.local"),
23
+ ' ',
24
+ "file")),
25
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: 'cp', args: ['.env.example', '.env.local'], runningText: 'Working...', successText: 'Done!', failureText: 'Error...' }),
26
+ installationType === 'full' && (React.createElement(FullInstallation, { onCompletion: onCompletion, projectFolder: projectFolder })),
27
+ installationType === 'custom' && (React.createElement(CustomInstallation, { selectedFeatures: selectedFeatures, onCompletion: onCompletion, projectFolder: projectFolder }))))));
28
+ };
29
+ export default Install;
@@ -0,0 +1,7 @@
1
+ import { type FC } from 'react';
2
+ interface Props {
3
+ onCompletion?: () => void;
4
+ projectFolder: string;
5
+ }
6
+ declare const InstallAllPackages: FC<Props>;
7
+ export default InstallAllPackages;
@@ -0,0 +1,9 @@
1
+ import { Text } from 'ink';
2
+ import { Spawn } from 'ink-spawn';
3
+ import React from 'react';
4
+ const InstallAllPackages = ({ projectFolder, onCompletion }) => {
5
+ return (React.createElement(React.Fragment, null,
6
+ React.createElement(Text, { color: 'whiteBright' }, "Installing packages"),
7
+ React.createElement(Spawn, { shell: true, cwd: projectFolder, silent: true, command: 'pnpm', args: ['i'], runningText: 'Working...', successText: 'Done!', failureText: 'Error...', onCompletion: onCompletion })));
8
+ };
9
+ export default InstallAllPackages;
@@ -0,0 +1,8 @@
1
+ import { type FC } from 'react';
2
+ import type { InstallationSelectItem } from '../../types/types.js';
3
+ interface Props {
4
+ onCompletion: () => void;
5
+ onSelect: (item: InstallationSelectItem) => void;
6
+ }
7
+ declare const InstallationMode: FC<Props>;
8
+ export default InstallationMode;
@@ -0,0 +1,28 @@
1
+ import figures from 'figures';
2
+ import { Text } from 'ink';
3
+ import SelectInput from 'ink-select-input';
4
+ import React, { useState } from 'react';
5
+ import Divider from '../Divider.js';
6
+ const installationTypeItems = [
7
+ {
8
+ label: 'Full',
9
+ value: 'full',
10
+ },
11
+ {
12
+ label: 'Custom',
13
+ value: 'custom',
14
+ },
15
+ ];
16
+ const InstallationMode = ({ onCompletion, onSelect }) => {
17
+ const [isFocused, setIsFocused] = useState(true);
18
+ const handleSelect = (item) => {
19
+ onSelect(item);
20
+ onCompletion();
21
+ setIsFocused(false);
22
+ };
23
+ return (React.createElement(React.Fragment, null,
24
+ React.createElement(Divider, { title: 'Installation setup' }),
25
+ React.createElement(Text, { color: 'whiteBright' }, "Choose installation type"),
26
+ React.createElement(SelectInput, { indicatorComponent: ({ isSelected }) => (React.createElement(Text, { color: "green" }, isSelected ? `${figures.pointer} ` : ' ')), itemComponent: ({ label, isSelected }) => (React.createElement(Text, { color: isSelected ? 'green' : 'white', bold: isSelected }, label)), isFocused: isFocused, items: installationTypeItems, onSelect: handleSelect })));
27
+ };
28
+ export default InstallationMode;