dappbooster 3.0.1 → 3.1.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.
Files changed (57) hide show
  1. package/dist/app.d.ts +1 -2
  2. package/dist/app.js +16 -15
  3. package/dist/cli.js +96 -5
  4. package/dist/components/Ask.js +3 -10
  5. package/dist/components/Divider.d.ts +1 -1
  6. package/dist/components/Divider.js +2 -2
  7. package/dist/components/MainTitle.d.ts +1 -1
  8. package/dist/components/MainTitle.js +2 -3
  9. package/dist/components/Multiselect/MultiSelect.d.ts +1 -2
  10. package/dist/components/Multiselect/MultiSelect.js +11 -13
  11. package/dist/components/Multiselect/components/Checkbox.d.ts +1 -2
  12. package/dist/components/Multiselect/components/Checkbox.js +2 -3
  13. package/dist/components/Multiselect/components/Indicator.d.ts +1 -2
  14. package/dist/components/Multiselect/components/Indicator.js +2 -3
  15. package/dist/components/Multiselect/components/Item.d.ts +1 -2
  16. package/dist/components/Multiselect/components/Item.js +2 -2
  17. package/dist/components/steps/CloneRepo/CloneRepo.d.ts +0 -6
  18. package/dist/components/steps/CloneRepo/CloneRepo.js +26 -11
  19. package/dist/components/steps/CloneRepo/Commands.d.ts +1 -1
  20. package/dist/components/steps/CloneRepo/Commands.js +2 -15
  21. package/dist/components/steps/FileCleanup.d.ts +0 -6
  22. package/dist/components/steps/FileCleanup.js +25 -66
  23. package/dist/components/steps/Install/CustomInstallation.d.ts +1 -1
  24. package/dist/components/steps/Install/CustomInstallation.js +2 -7
  25. package/dist/components/steps/Install/FullInstallation.d.ts +1 -1
  26. package/dist/components/steps/Install/FullInstallation.js +2 -4
  27. package/dist/components/steps/Install/Install.js +32 -21
  28. package/dist/components/steps/Install/InstallAllPackages.d.ts +1 -1
  29. package/dist/components/steps/Install/InstallAllPackages.js +2 -4
  30. package/dist/components/steps/InstallationMode.js +3 -5
  31. package/dist/components/steps/OptionalPackages.d.ts +2 -8
  32. package/dist/components/steps/OptionalPackages.js +10 -36
  33. package/dist/components/steps/PostInstall.d.ts +1 -6
  34. package/dist/components/steps/PostInstall.js +7 -71
  35. package/dist/components/steps/ProjectName.js +3 -2
  36. package/dist/constants/config.d.ts +9 -2
  37. package/dist/constants/config.js +48 -16
  38. package/dist/info.d.ts +1 -0
  39. package/dist/info.js +18 -0
  40. package/dist/nonInteractive.d.ts +5 -0
  41. package/dist/nonInteractive.js +85 -0
  42. package/dist/operations/cleanupFiles.d.ts +3 -0
  43. package/dist/operations/cleanupFiles.js +77 -0
  44. package/dist/operations/cloneRepo.d.ts +1 -0
  45. package/dist/operations/cloneRepo.js +21 -0
  46. package/dist/operations/createEnvFile.d.ts +1 -0
  47. package/dist/operations/createEnvFile.js +5 -0
  48. package/dist/operations/exec.d.ts +6 -0
  49. package/dist/operations/exec.js +32 -0
  50. package/dist/operations/index.d.ts +4 -0
  51. package/dist/operations/index.js +4 -0
  52. package/dist/operations/installPackages.d.ts +3 -0
  53. package/dist/operations/installPackages.js +19 -0
  54. package/dist/utils/utils.d.ts +13 -28
  55. package/dist/utils/utils.js +25 -32
  56. package/package.json +18 -9
  57. package/readme.md +9 -4
package/dist/app.d.ts CHANGED
@@ -1,3 +1,2 @@
1
- import React from 'react';
2
- declare const App: () => React.JSX.Element;
1
+ declare const App: () => import("react/jsx-runtime").JSX.Element;
3
2
  export default App;
package/dist/app.js CHANGED
@@ -1,5 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
2
  import { Box } from 'ink';
2
- import React, { useState, useMemo, useCallback } from 'react';
3
+ import { useCallback, useMemo, useState } from 'react';
3
4
  import MainTitle from './components/MainTitle.js';
4
5
  import CloneRepo from './components/steps/CloneRepo/CloneRepo.js';
5
6
  import FileCleanup from './components/steps/FileCleanup.js';
@@ -14,26 +15,27 @@ const App = () => {
14
15
  const [currentStep, setCurrentStep] = useState(1);
15
16
  const [setupType, setSetupType] = useState();
16
17
  const [selectedFeatures, setSelectedFeatures] = useState();
17
- const finishStep = useCallback(() => setCurrentStep(currentStep + 1), [currentStep]);
18
+ const finishStep = useCallback(() => setCurrentStep((prevStep) => prevStep + 1), []);
18
19
  const onSelectSetupType = useCallback((item) => setSetupType(item), []);
19
20
  const onSelectSelectedFeatures = useCallback((selectedItems) => setSelectedFeatures([...selectedItems]), []);
21
+ const skipFeatures = setupType?.value === 'full';
20
22
  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: {
23
+ _jsx(ProjectName, { onCompletion: finishStep, onSubmit: setProjectName, projectName: projectName }, 1),
24
+ _jsx(CloneRepo, { onCompletion: finishStep, projectName: projectName }, 2),
25
+ _jsx(InstallationMode, { onCompletion: finishStep, onSelect: onSelectSetupType }, 3),
26
+ _jsx(OptionalPackages, { onCompletion: finishStep, onSubmit: onSelectSelectedFeatures, skip: skipFeatures }, 4),
27
+ _jsx(Install, { installationConfig: {
26
28
  installationType: setupType?.value,
27
29
  selectedFeatures: selectedFeatures,
28
- }, onCompletion: finishStep, projectName: projectName, key: 5 }),
29
- React.createElement(FileCleanup, { installationConfig: {
30
+ }, onCompletion: finishStep, projectName: projectName }, 5),
31
+ _jsx(FileCleanup, { installationConfig: {
30
32
  installationType: setupType?.value,
31
33
  selectedFeatures: selectedFeatures,
32
- }, onCompletion: finishStep, projectName: projectName, key: 6 }),
33
- React.createElement(PostInstall, { projectName: projectName, installationConfig: {
34
+ }, onCompletion: finishStep, projectName: projectName }, 6),
35
+ _jsx(PostInstall, { projectName: projectName, installationConfig: {
34
36
  installationType: setupType?.value,
35
37
  selectedFeatures: selectedFeatures,
36
- }, key: 7 }),
38
+ } }, 7),
37
39
  ], [
38
40
  finishStep,
39
41
  onSelectSelectedFeatures,
@@ -41,9 +43,8 @@ const App = () => {
41
43
  selectedFeatures,
42
44
  onSelectSetupType,
43
45
  projectName,
46
+ skipFeatures,
44
47
  ]);
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
+ return (_jsxs(Box, { flexDirection: 'column', rowGap: 1, width: 80, children: [_jsx(MainTitle, {}), steps.map((item, index) => canShowStep(currentStep, index + 1) && item)] }));
48
49
  };
49
50
  export default App;
package/dist/cli.js CHANGED
@@ -1,6 +1,97 @@
1
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));
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import process from 'node:process';
4
+ import meow from 'meow';
5
+ import { getInfoOutput } from './info.js';
6
+ import { runNonInteractive } from './nonInteractive.js';
7
+ const cli = meow(`
8
+ Usage
9
+ $ dappbooster [options]
10
+
11
+ Options
12
+ --name <string> Project name (alphanumeric, underscores)
13
+ --mode <full|custom> Installation mode
14
+ --features <list> Comma-separated features (with --mode=custom):
15
+ demo Component demos and example pages
16
+ subgraph TheGraph subgraph integration (requires API key)
17
+ typedoc TypeDoc API documentation generation
18
+ vocs Vocs documentation site
19
+ husky Git hooks with Husky, lint-staged, commitlint
20
+ --non-interactive, --ni Run without prompts (auto-enabled when not a TTY)
21
+ --info Output feature metadata as JSON
22
+ --help Show this help
23
+ --version Show version
24
+
25
+ Non-interactive mode
26
+ Requires --name and --mode. Outputs JSON to stdout.
27
+ Activates automatically when stdout is not a TTY.
28
+ Use --ni to force non-interactive mode in a TTY environment.
29
+
30
+ AI agents: non-interactive mode activates automatically. Run --info
31
+ to discover available features, then pass --name and --mode flags.
32
+ Output is JSON for easy parsing.
33
+
34
+ Examples
35
+ Interactive:
36
+ $ dappbooster
37
+
38
+ Full install (non-interactive):
39
+ $ dappbooster --ni --name my_dapp --mode full
40
+
41
+ Custom install with specific features:
42
+ $ dappbooster --ni --name my_dapp --mode custom --features demo,subgraph
43
+
44
+ Get feature metadata:
45
+ $ dappbooster --info
46
+ `, {
47
+ importMeta: import.meta,
48
+ flags: {
49
+ name: {
50
+ type: 'string',
51
+ },
52
+ mode: {
53
+ type: 'string',
54
+ },
55
+ features: {
56
+ type: 'string',
57
+ },
58
+ nonInteractive: {
59
+ type: 'boolean',
60
+ default: false,
61
+ },
62
+ ni: {
63
+ type: 'boolean',
64
+ default: false,
65
+ },
66
+ info: {
67
+ type: 'boolean',
68
+ default: false,
69
+ },
70
+ },
71
+ });
72
+ if (cli.flags.info) {
73
+ console.log(getInfoOutput());
74
+ }
75
+ else if (cli.flags.nonInteractive || cli.flags.ni || !process.stdout.isTTY) {
76
+ runNonInteractive({
77
+ name: cli.flags.name,
78
+ mode: cli.flags.mode,
79
+ features: cli.flags.features,
80
+ }).catch((error) => {
81
+ if (process.exitCode === 1) {
82
+ return;
83
+ }
84
+ const message = error instanceof Error ? error.message : String(error);
85
+ console.log(JSON.stringify({ success: false, error: message }, null, 2));
86
+ process.exitCode = 1;
87
+ });
88
+ }
89
+ else {
90
+ const run = async () => {
91
+ console.clear();
92
+ const { render } = await import('ink');
93
+ const { default: App } = await import('./app.js');
94
+ render(_jsx(App, {}));
95
+ };
96
+ run().catch(console.error);
97
+ }
@@ -1,18 +1,11 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
2
  import { Box, Text } from 'ink';
2
3
  import TextInput from 'ink-text-input';
3
- import React, { useMemo, useState } from 'react';
4
+ import { useMemo, useState } from 'react';
4
5
  import { isAnswerConfirmed } from '../utils/utils.js';
5
6
  const Ask = ({ question, onSubmit, answer, tip, errorMessage, placeholder }) => {
6
7
  const [input, setInput] = useState('');
7
8
  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))));
9
+ return (_jsxs(Box, { flexDirection: 'column', rowGap: 1, children: [_jsxs(Box, { flexDirection: 'column', children: [_jsxs(Box, { children: [_jsxs(Text, { color: 'whiteBright', children: [question, ": "] }), answered ? (_jsx(Text, { bold: true, color: 'green', children: answer })) : (_jsx(TextInput, { onChange: setInput, onSubmit: onSubmit, placeholder: placeholder, value: input }))] }), tip && _jsx(Text, { color: 'gray', children: tip })] }), errorMessage && (_jsx(Text, { bold: true, color: 'red', children: errorMessage }))] }));
17
10
  };
18
11
  export default Ask;
@@ -1,4 +1,4 @@
1
- import { type FC } from 'react';
1
+ import type { FC } from 'react';
2
2
  declare const Divider: FC<{
3
3
  title: string;
4
4
  }>;
@@ -1,4 +1,4 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
1
2
  import BaseDivider from 'ink-divider';
2
- import React from 'react';
3
- const Divider = ({ title }) => (React.createElement(BaseDivider, { titlePadding: 2, titleColor: 'whiteBright', title: title }));
3
+ const Divider = ({ title }) => (_jsx(BaseDivider, { titlePadding: 2, titleColor: 'whiteBright', title: title }));
4
4
  export default Divider;
@@ -1,3 +1,3 @@
1
- import { type FC } from 'react';
1
+ import type { FC } from 'react';
2
2
  declare const MainTitle: FC;
3
3
  export default MainTitle;
@@ -1,6 +1,5 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
1
2
  import BigText from 'ink-big-text';
2
3
  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" })));
4
+ const MainTitle = () => (_jsx(Gradient, { colors: ['#ff438c', '#bb1d79', '#8b46a4', '#6a2581'], children: _jsx(BigText, { lineHeight: 1, font: 'chrome', text: "dAppBooster" }) }));
6
5
  export default MainTitle;
@@ -1,4 +1,3 @@
1
- import React from 'react';
2
1
  import CheckBox from './components/Checkbox.js';
3
2
  import Indicator from './components/Indicator.js';
4
3
  import ItemComponent from './components/Item.js';
@@ -28,6 +27,6 @@ type MultiSelectProps<T> = {
28
27
  onSubmit?: (selectedItems: Item<T>[]) => void;
29
28
  onHighlight?: (highlightedItem: Item<T>) => void;
30
29
  };
31
- declare const MultiSelect: <T>({ items, defaultSelected, focus, initialIndex, indicatorComponent, checkboxComponent, itemComponent, limit, onSelect, onUnselect, onSubmit, onHighlight, }: MultiSelectProps<T>) => React.JSX.Element;
30
+ declare const MultiSelect: <T>({ items, defaultSelected, focus, initialIndex, indicatorComponent, checkboxComponent, itemComponent, limit, onSelect, onUnselect, onSubmit, onHighlight, }: MultiSelectProps<T>) => import("react/jsx-runtime").JSX.Element;
32
31
  export default MultiSelect;
33
32
  export { Indicator, ItemComponent, CheckBox, type Item };
@@ -1,5 +1,6 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
2
  import { Box, useInput } from 'ink';
2
- import React, { useCallback, useState } from 'react';
3
+ import { createElement, useCallback, useState } from 'react';
3
4
  import CheckBox from './components/Checkbox.js';
4
5
  import Indicator from './components/Indicator.js';
5
6
  import ItemComponent from './components/Item.js';
@@ -51,18 +52,15 @@ const MultiSelect = ({ items = [], defaultSelected = [], focus = true, initialIn
51
52
  handleSelect(slicedItems[highlightedIndex]);
52
53
  }
53
54
  }, [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
- })));
55
+ return (_jsx(Box, { flexDirection: "column", children: slicedItems.map((item, index) => {
56
+ const key = item.key || item.label;
57
+ const isHighlighted = index === highlightedIndex;
58
+ const isSelected = includesItems(item, selectedItems);
59
+ return (_jsxs(Box, { children: [createElement(indicatorComponent, { isHighlighted }), createElement(checkboxComponent, { isSelected }), createElement(itemComponent, {
60
+ ...item,
61
+ isHighlighted,
62
+ })] }, key));
63
+ }) }));
66
64
  };
67
65
  export default MultiSelect;
68
66
  export { Indicator, ItemComponent, CheckBox };
@@ -1,6 +1,5 @@
1
- import React from 'react';
2
1
  type CheckBoxProps = {
3
2
  isSelected: boolean;
4
3
  };
5
- declare const CheckBox: ({ isSelected }: CheckBoxProps) => React.JSX.Element;
4
+ declare const CheckBox: ({ isSelected }: CheckBoxProps) => import("react/jsx-runtime").JSX.Element;
6
5
  export default CheckBox;
@@ -1,6 +1,5 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
1
2
  import figures from 'figures';
2
3
  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)));
4
+ const CheckBox = ({ isSelected = false }) => (_jsx(Box, { marginRight: 1, children: _jsx(Text, { color: isSelected ? 'green' : 'white', children: isSelected ? figures.circleFilled : figures.circle }) }));
6
5
  export default CheckBox;
@@ -1,6 +1,5 @@
1
- import React from 'react';
2
1
  type IndicatorProps = {
3
2
  isHighlighted: boolean;
4
3
  };
5
- declare const Indicator: ({ isHighlighted }: IndicatorProps) => React.JSX.Element;
4
+ declare const Indicator: ({ isHighlighted }: IndicatorProps) => import("react/jsx-runtime").JSX.Element;
6
5
  export default Indicator;
@@ -1,6 +1,5 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
1
2
  import figures from 'figures';
2
3
  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 : ' ')));
4
+ const Indicator = ({ isHighlighted = false }) => (_jsx(Box, { marginRight: 1, children: _jsx(Text, { color: isHighlighted ? 'green' : undefined, children: isHighlighted ? figures.pointer : ' ' }) }));
6
5
  export default Indicator;
@@ -1,7 +1,6 @@
1
- import React from 'react';
2
1
  type ItemProps = {
3
2
  isHighlighted: boolean;
4
3
  label: string;
5
4
  };
6
- declare const Item: ({ isHighlighted, label }: ItemProps) => React.JSX.Element;
5
+ declare const Item: ({ isHighlighted, label }: ItemProps) => import("react/jsx-runtime").JSX.Element;
7
6
  export default Item;
@@ -1,4 +1,4 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
1
2
  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));
3
+ const Item = ({ isHighlighted = false, label }) => (_jsx(Text, { color: isHighlighted ? 'green' : 'white', bold: isHighlighted, children: label }));
4
4
  export default Item;
@@ -3,11 +3,5 @@ interface Props {
3
3
  projectName: string;
4
4
  onCompletion: () => void;
5
5
  }
6
- /**
7
- * Step for cloning the repository.
8
- * @param projectName
9
- * @param onCompletion
10
- * @constructor
11
- */
12
6
  declare const CloneRepo: FC<Props>;
13
7
  export default CloneRepo;
@@ -1,13 +1,28 @@
1
- import React from 'react';
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Text } from 'ink';
3
+ import { useCallback, useEffect, useState } from 'react';
4
+ import { cloneRepo } from '../../../operations/index.js';
5
+ import { deriveStepDisplay } from '../../../utils/utils.js';
2
6
  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 })));
7
+ const CloneRepo = ({ projectName, onCompletion }) => {
8
+ const [steps, setSteps] = useState([]);
9
+ const [status, setStatus] = useState('running');
10
+ const [errorMessage, setErrorMessage] = useState('');
11
+ const handleProgress = useCallback((step) => {
12
+ setSteps((prev) => [...prev, step]);
13
+ }, []);
14
+ useEffect(() => {
15
+ cloneRepo(projectName, handleProgress)
16
+ .then(() => {
17
+ setStatus('done');
18
+ onCompletion();
19
+ })
20
+ .catch((error) => {
21
+ setStatus('error');
22
+ setErrorMessage(error instanceof Error ? error.message : String(error));
23
+ });
24
+ }, [projectName, onCompletion, handleProgress]);
25
+ const { completedSteps, currentStep, failedStep } = deriveStepDisplay(steps, status);
26
+ return (_jsxs(_Fragment, { children: [_jsx(Divider, { title: 'Git tasks' }), completedSteps.map((step) => (_jsxs(Text, { children: [_jsx(Text, { color: 'green', children: '\u2714' }), " ", step] }, step))), currentStep && (_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: '\u25CB' }), " ", currentStep, " ", _jsx(Text, { dimColor: true, children: "Working..." })] })), failedStep && (_jsxs(Text, { children: [_jsx(Text, { color: 'red', children: '\u2717' }), " ", failedStep, " ", _jsx(Text, { color: 'red', children: "Error" })] })), status === 'error' && _jsxs(Text, { color: 'red', children: ["Failed to clone: ", errorMessage] })] }));
27
+ };
13
28
  export default CloneRepo;
@@ -1,4 +1,4 @@
1
- import { type FC } from 'react';
1
+ import type { FC } from 'react';
2
2
  interface Props {
3
3
  projectName: string;
4
4
  onCompletion: () => void;
@@ -1,8 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
2
  import { join } from 'node:path';
2
3
  import * as process from 'node:process';
3
4
  import { Box, Text } from 'ink';
4
5
  import { Script, Spawn } from 'ink-spawn';
5
- import React from 'react';
6
6
  import { repoUrl } from '../../../constants/config.js';
7
7
  /**
8
8
  * Executes all the commands to clone the dAppBooster repository.
@@ -11,19 +11,6 @@ import { repoUrl } from '../../../constants/config.js';
11
11
  */
12
12
  const Commands = ({ projectName, onCompletion }) => {
13
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 }))));
14
+ return (_jsx(Box, { flexDirection: 'column', gap: 0, children: _jsxs(Script, { children: [_jsxs(Box, { columnGap: 1, children: [_jsx(Text, { color: 'whiteBright', children: "Cloning dAppBooster in" }), _jsx(Text, { italic: true, children: projectName })] }), _jsx(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] }), _jsx(Text, { color: 'whiteBright', children: "Fetching tags" }), _jsx(Spawn, { shell: true, cwd: projectFolder, silent: true, command: 'git', args: ['fetch', '--tags'], runningText: 'Working...', successText: 'Done!', failureText: 'Error...' }), _jsx(Text, { color: 'whiteBright', children: "Checking out latest tag" }), _jsx(Spawn, { shell: true, cwd: projectFolder, command: "git", args: ['checkout $(git describe --tags `git rev-list --tags --max-count=1`)'], successText: "Done!", failureText: 'Error...' }), _jsx(Text, { color: 'whiteBright', children: "Removing .git folder" }), _jsx(Spawn, { shell: true, cwd: projectFolder, command: "rm", args: ['-rf', '.git'], successText: "Done!", failureText: 'Error...' }), _jsx(Text, { color: 'whiteBright', children: "Initializing Git repository" }), _jsx(Spawn, { shell: true, cwd: projectFolder, command: "git", args: ['init'], successText: "Done!", failureText: 'Error...', onCompletion: onCompletion })] }) }));
28
15
  };
29
16
  export default Commands;
@@ -8,11 +8,5 @@ interface Props {
8
8
  selectedFeatures?: Array<MultiSelectItem>;
9
9
  };
10
10
  }
11
- /**
12
- * Performs file cleanup after the installation process
13
- * @param onCompletion
14
- * @param installation
15
- * @param projectName
16
- */
17
11
  declare const FileCleanup: FC<Props>;
18
12
  export default FileCleanup;
@@ -1,72 +1,31 @@
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';
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Text } from 'ink';
3
+ import { useCallback, useEffect, useMemo, useState } from 'react';
4
+ import { cleanupFiles } from '../../operations/index.js';
5
+ import { deriveStepDisplay, getProjectFolder } from '../../utils/utils.js';
7
6
  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
7
  const FileCleanup = ({ onCompletion, installationConfig, projectName }) => {
34
8
  const { installationType, selectedFeatures } = installationConfig;
35
9
  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 })))));
10
+ const [steps, setSteps] = useState([]);
11
+ const [status, setStatus] = useState('running');
12
+ const [errorMessage, setErrorMessage] = useState('');
13
+ const handleProgress = useCallback((step) => {
14
+ setSteps((prev) => [...prev, step]);
15
+ }, []);
16
+ useEffect(() => {
17
+ const features = selectedFeatures?.map((f) => f.value) ?? [];
18
+ cleanupFiles(projectFolder, installationType ?? 'full', features, handleProgress)
19
+ .then(() => {
20
+ setStatus('done');
21
+ onCompletion();
22
+ })
23
+ .catch((error) => {
24
+ setStatus('error');
25
+ setErrorMessage(error instanceof Error ? error.message : String(error));
26
+ });
27
+ }, [projectFolder, installationType, selectedFeatures, onCompletion, handleProgress]);
28
+ const { completedSteps, currentStep, failedStep } = deriveStepDisplay(steps, status);
29
+ return (_jsxs(_Fragment, { children: [_jsx(Divider, { title: 'File cleanup' }), completedSteps.map((step) => (_jsxs(Text, { children: [_jsx(Text, { color: 'green', children: '\u2714' }), " ", step] }, step))), currentStep && (_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: '\u25CB' }), " ", currentStep, " ", _jsx(Text, { dimColor: true, children: "Working..." })] })), failedStep && (_jsxs(Text, { children: [_jsx(Text, { color: 'red', children: '\u2717' }), " ", failedStep, " ", _jsx(Text, { color: 'red', children: "Error" })] })), status === 'error' && _jsxs(Text, { color: 'red', children: ["Cleanup failed: ", errorMessage] })] }));
71
30
  };
72
31
  export default FileCleanup;
@@ -1,4 +1,4 @@
1
- import { type FC } from 'react';
1
+ import type { FC } from 'react';
2
2
  import type { MultiSelectItem } from '../../../types/types.js';
3
3
  interface Props {
4
4
  onCompletion: () => void;
@@ -1,6 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
2
  import { Box, Text } from 'ink';
2
3
  import { Script, Spawn } from 'ink-spawn';
3
- import React from 'react';
4
4
  import { getPackages } from '../../../utils/utils.js';
5
5
  import InstallAllPackages from './InstallAllPackages.js';
6
6
  /**
@@ -21,11 +21,6 @@ const CustomInstallation = ({ onCompletion, selectedFeatures, projectFolder }) =
21
21
  ]
22
22
  .join(' ')
23
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 })))));
24
+ return (_jsx(Box, { flexDirection: 'column', gap: 0, children: !packagesToRemove ? (_jsx(Script, { children: _jsx(InstallAllPackages, { projectFolder: projectFolder, onCompletion: onCompletion }) })) : (_jsxs(Script, { children: [_jsx(Text, { color: 'whiteBright', children: "Installing packages" }), _jsx(Spawn, { shell: true, cwd: projectFolder, silent: true, command: 'pnpm', args: ['remove', packagesToRemove], runningText: 'Working...', successText: 'Done!', failureText: 'Error...' }), _jsx(Text, { color: 'whiteBright', children: "Executing post-install scripts" }), _jsx(Spawn, { shell: true, cwd: projectFolder, silent: true, command: 'pnpm', args: ['run', 'postinstall'], runningText: 'Working...', successText: 'Done!', failureText: 'Error...', onCompletion: onCompletion })] })) }));
30
25
  };
31
26
  export default CustomInstallation;
@@ -1,4 +1,4 @@
1
- import { type FC } from 'react';
1
+ import type { FC } from 'react';
2
2
  interface Props {
3
3
  projectFolder: string;
4
4
  onCompletion?: () => void;
@@ -1,10 +1,8 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
1
2
  import { Box } from 'ink';
2
3
  import { Script } from 'ink-spawn';
3
- import React from 'react';
4
4
  import InstallAllPackages from './InstallAllPackages.js';
5
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 }))));
6
+ return (_jsx(Box, { flexDirection: 'column', gap: 0, children: _jsx(Script, { children: _jsx(InstallAllPackages, { projectFolder: projectFolder, onCompletion: onCompletion }) }) }));
9
7
  };
10
8
  export default FullInstallation;