zard-cli 1.0.0-beta.9 → 1.1.0-alpha.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 (237) hide show
  1. package/README.md +60 -188
  2. package/commands/add/component-installer.d.ts +4 -1
  3. package/commands/add/component-installer.d.ts.map +1 -1
  4. package/commands/add/component-installer.js +33 -5
  5. package/commands/add/component-installer.js.map +1 -1
  6. package/commands/add/component-selector.d.ts +6 -0
  7. package/commands/add/component-selector.d.ts.map +1 -1
  8. package/commands/add/component-selector.js +9 -27
  9. package/commands/add/component-selector.js.map +1 -1
  10. package/commands/add/dark-mode-setup.d.ts +2 -0
  11. package/commands/add/dark-mode-setup.d.ts.map +1 -1
  12. package/commands/add/dark-mode-setup.js +5 -11
  13. package/commands/add/dark-mode-setup.js.map +1 -1
  14. package/commands/add/dependency-resolver.d.ts +1 -1
  15. package/commands/add/dependency-resolver.d.ts.map +1 -1
  16. package/commands/add/dependency-resolver.js +5 -6
  17. package/commands/add/dependency-resolver.js.map +1 -1
  18. package/commands/add/index.d.ts.map +1 -1
  19. package/commands/add/index.js +127 -85
  20. package/commands/add/index.js.map +1 -1
  21. package/commands/add/wizard.d.ts +31 -0
  22. package/commands/add/wizard.d.ts.map +1 -0
  23. package/commands/add/wizard.js +289 -0
  24. package/commands/add/wizard.js.map +1 -0
  25. package/commands/init/config-prompter.d.ts +59 -56
  26. package/commands/init/config-prompter.d.ts.map +1 -1
  27. package/commands/init/config-prompter.js +76 -74
  28. package/commands/init/config-prompter.js.map +1 -1
  29. package/commands/init/dependencies.d.ts +1 -8
  30. package/commands/init/dependencies.d.ts.map +1 -1
  31. package/commands/init/dependencies.js +36 -16
  32. package/commands/init/dependencies.js.map +1 -1
  33. package/commands/init/index.d.ts.map +1 -1
  34. package/commands/init/index.js +132 -86
  35. package/commands/init/index.js.map +1 -1
  36. package/commands/init/project-kind.d.ts +82 -0
  37. package/commands/init/project-kind.d.ts.map +1 -0
  38. package/commands/init/project-kind.js +166 -0
  39. package/commands/init/project-kind.js.map +1 -0
  40. package/commands/init/steps.d.ts +16 -0
  41. package/commands/init/steps.d.ts.map +1 -0
  42. package/commands/init/steps.js +151 -0
  43. package/commands/init/steps.js.map +1 -0
  44. package/commands/init/tailwind-setup.d.ts +9 -2
  45. package/commands/init/tailwind-setup.d.ts.map +1 -1
  46. package/commands/init/tailwind-setup.js +33 -9
  47. package/commands/init/tailwind-setup.js.map +1 -1
  48. package/commands/init/theme-loader.d.ts.map +1 -1
  49. package/commands/init/theme-loader.js +1 -3
  50. package/commands/init/theme-loader.js.map +1 -1
  51. package/commands/init/tsconfig-updater.d.ts +8 -1
  52. package/commands/init/tsconfig-updater.d.ts.map +1 -1
  53. package/commands/init/tsconfig-updater.js +30 -11
  54. package/commands/init/tsconfig-updater.js.map +1 -1
  55. package/commands/init/update-angular-config.d.ts.map +1 -1
  56. package/commands/init/update-angular-config.js +28 -47
  57. package/commands/init/update-angular-config.js.map +1 -1
  58. package/commands/init/vite-setup.d.ts +10 -0
  59. package/commands/init/vite-setup.d.ts.map +1 -0
  60. package/commands/init/vite-setup.js +60 -0
  61. package/commands/init/vite-setup.js.map +1 -0
  62. package/commands/init/wizard.d.ts +30 -0
  63. package/commands/init/wizard.d.ts.map +1 -0
  64. package/commands/init/wizard.js +560 -0
  65. package/commands/init/wizard.js.map +1 -0
  66. package/core/registry/registry-data.d.ts.map +1 -1
  67. package/core/registry/registry-data.js +359 -61
  68. package/core/registry/registry-data.js.map +1 -1
  69. package/core/themes/theme-definitions.d.ts +5 -5
  70. package/core/themes/theme-definitions.d.ts.map +1 -1
  71. package/core/themes/theme-definitions.js +15 -11
  72. package/core/themes/theme-definitions.js.map +1 -1
  73. package/index.js +40 -4
  74. package/index.js.map +1 -1
  75. package/package.json +58 -61
  76. package/ui/blocks.d.ts +70 -0
  77. package/ui/blocks.d.ts.map +1 -0
  78. package/ui/blocks.js +116 -0
  79. package/ui/blocks.js.map +1 -0
  80. package/ui/brand.d.ts +14 -0
  81. package/ui/brand.d.ts.map +1 -0
  82. package/ui/brand.js +35 -0
  83. package/ui/brand.js.map +1 -0
  84. package/ui/engine/animation/index.d.ts +39 -0
  85. package/ui/engine/animation/index.d.ts.map +1 -0
  86. package/ui/engine/animation/index.js +103 -0
  87. package/ui/engine/animation/index.js.map +1 -0
  88. package/ui/engine/ansi/index.d.ts +52 -0
  89. package/ui/engine/ansi/index.d.ts.map +1 -0
  90. package/ui/engine/ansi/index.js +117 -0
  91. package/ui/engine/ansi/index.js.map +1 -0
  92. package/ui/engine/components/index.d.ts +211 -0
  93. package/ui/engine/components/index.d.ts.map +1 -0
  94. package/ui/engine/components/index.js +109 -0
  95. package/ui/engine/components/index.js.map +1 -0
  96. package/ui/engine/cursor/index.d.ts +17 -0
  97. package/ui/engine/cursor/index.d.ts.map +1 -0
  98. package/ui/engine/cursor/index.js +41 -0
  99. package/ui/engine/cursor/index.js.map +1 -0
  100. package/ui/engine/diff/index.d.ts +27 -0
  101. package/ui/engine/diff/index.d.ts.map +1 -0
  102. package/ui/engine/diff/index.js +57 -0
  103. package/ui/engine/diff/index.js.map +1 -0
  104. package/ui/engine/events/index.d.ts +24 -0
  105. package/ui/engine/events/index.d.ts.map +1 -0
  106. package/ui/engine/events/index.js +60 -0
  107. package/ui/engine/events/index.js.map +1 -0
  108. package/ui/engine/focus/index.d.ts +25 -0
  109. package/ui/engine/focus/index.d.ts.map +1 -0
  110. package/ui/engine/focus/index.js +77 -0
  111. package/ui/engine/focus/index.js.map +1 -0
  112. package/ui/engine/frame/index.d.ts +48 -0
  113. package/ui/engine/frame/index.d.ts.map +1 -0
  114. package/ui/engine/frame/index.js +0 -0
  115. package/ui/engine/frame/index.js.map +1 -0
  116. package/ui/engine/index.d.ts +28 -0
  117. package/ui/engine/index.d.ts.map +1 -0
  118. package/ui/engine/index.js +28 -0
  119. package/ui/engine/index.js.map +1 -0
  120. package/ui/engine/input/index.d.ts +36 -0
  121. package/ui/engine/input/index.d.ts.map +1 -0
  122. package/ui/engine/input/index.js +224 -0
  123. package/ui/engine/input/index.js.map +1 -0
  124. package/ui/engine/layout/index.d.ts +42 -0
  125. package/ui/engine/layout/index.d.ts.map +1 -0
  126. package/ui/engine/layout/index.js +241 -0
  127. package/ui/engine/layout/index.js.map +1 -0
  128. package/ui/engine/renderer/index.d.ts +43 -0
  129. package/ui/engine/renderer/index.d.ts.map +1 -0
  130. package/ui/engine/renderer/index.js +619 -0
  131. package/ui/engine/renderer/index.js.map +1 -0
  132. package/ui/engine/scheduler/index.d.ts +22 -0
  133. package/ui/engine/scheduler/index.d.ts.map +1 -0
  134. package/ui/engine/scheduler/index.js +77 -0
  135. package/ui/engine/scheduler/index.js.map +1 -0
  136. package/ui/engine/screen/index.d.ts +39 -0
  137. package/ui/engine/screen/index.d.ts.map +1 -0
  138. package/ui/engine/screen/index.js +255 -0
  139. package/ui/engine/screen/index.js.map +1 -0
  140. package/ui/engine/terminal/index.d.ts +38 -0
  141. package/ui/engine/terminal/index.d.ts.map +1 -0
  142. package/ui/engine/terminal/index.js +104 -0
  143. package/ui/engine/terminal/index.js.map +1 -0
  144. package/ui/engine/testing/index.d.ts +27 -0
  145. package/ui/engine/testing/index.d.ts.map +1 -0
  146. package/ui/engine/testing/index.js +63 -0
  147. package/ui/engine/testing/index.js.map +1 -0
  148. package/ui/engine/theme/index.d.ts +27 -0
  149. package/ui/engine/theme/index.d.ts.map +1 -0
  150. package/ui/engine/theme/index.js +129 -0
  151. package/ui/engine/theme/index.js.map +1 -0
  152. package/ui/engine/utils/index.d.ts +12 -0
  153. package/ui/engine/utils/index.d.ts.map +1 -0
  154. package/ui/engine/utils/index.js +143 -0
  155. package/ui/engine/utils/index.js.map +1 -0
  156. package/ui/gate.d.ts +19 -0
  157. package/ui/gate.d.ts.map +1 -0
  158. package/ui/gate.js +36 -0
  159. package/ui/gate.js.map +1 -0
  160. package/ui/index.d.ts +18 -0
  161. package/ui/index.d.ts.map +1 -0
  162. package/ui/index.js +18 -0
  163. package/ui/index.js.map +1 -0
  164. package/ui/log-sink.d.ts +24 -0
  165. package/ui/log-sink.d.ts.map +1 -0
  166. package/ui/log-sink.js +35 -0
  167. package/ui/log-sink.js.map +1 -0
  168. package/ui/output.d.ts +14 -0
  169. package/ui/output.d.ts.map +1 -0
  170. package/ui/output.js +28 -0
  171. package/ui/output.js.map +1 -0
  172. package/ui/report.d.ts +30 -0
  173. package/ui/report.d.ts.map +1 -0
  174. package/ui/report.js +45 -0
  175. package/ui/report.js.map +1 -0
  176. package/ui/runner.d.ts +57 -0
  177. package/ui/runner.d.ts.map +1 -0
  178. package/ui/runner.js +119 -0
  179. package/ui/runner.js.map +1 -0
  180. package/ui/style.d.ts +24 -0
  181. package/ui/style.d.ts.map +1 -0
  182. package/ui/style.js +44 -0
  183. package/ui/style.js.map +1 -0
  184. package/ui/testing/fake-tty.d.ts +26 -0
  185. package/ui/testing/fake-tty.d.ts.map +1 -0
  186. package/ui/testing/fake-tty.js +61 -0
  187. package/ui/testing/fake-tty.js.map +1 -0
  188. package/ui/text-input.d.ts +30 -0
  189. package/ui/text-input.d.ts.map +1 -0
  190. package/ui/text-input.js +87 -0
  191. package/ui/text-input.js.map +1 -0
  192. package/ui/theme.d.ts +10 -0
  193. package/ui/theme.d.ts.map +1 -0
  194. package/ui/theme.js +20 -0
  195. package/ui/theme.js.map +1 -0
  196. package/utils/config.d.ts +48 -69
  197. package/utils/config.d.ts.map +1 -1
  198. package/utils/config.js +43 -7
  199. package/utils/config.js.map +1 -1
  200. package/utils/errors.d.ts +16 -0
  201. package/utils/errors.d.ts.map +1 -0
  202. package/utils/errors.js +31 -0
  203. package/utils/errors.js.map +1 -0
  204. package/utils/get-package-info.js +4 -4
  205. package/utils/get-package-info.js.map +1 -1
  206. package/utils/get-project-info.d.ts +30 -0
  207. package/utils/get-project-info.d.ts.map +1 -1
  208. package/utils/get-project-info.js +195 -6
  209. package/utils/get-project-info.js.map +1 -1
  210. package/utils/http-client.d.ts +8 -0
  211. package/utils/http-client.d.ts.map +1 -0
  212. package/utils/http-client.js +68 -0
  213. package/utils/http-client.js.map +1 -0
  214. package/utils/logger.d.ts +16 -1
  215. package/utils/logger.d.ts.map +1 -1
  216. package/utils/logger.js +104 -12
  217. package/utils/logger.js.map +1 -1
  218. package/utils/package-manager.d.ts +44 -1
  219. package/utils/package-manager.d.ts.map +1 -1
  220. package/utils/package-manager.js +210 -14
  221. package/utils/package-manager.js.map +1 -1
  222. package/utils/registry.d.ts +14 -2
  223. package/utils/registry.d.ts.map +1 -1
  224. package/utils/registry.js +52 -24
  225. package/utils/registry.js.map +1 -1
  226. package/utils/source-file.d.ts +40 -0
  227. package/utils/source-file.d.ts.map +1 -0
  228. package/utils/source-file.js +104 -0
  229. package/utils/source-file.js.map +1 -0
  230. package/utils/theme-selector.d.ts +1 -1
  231. package/utils/theme-selector.d.ts.map +1 -1
  232. package/utils/theme-selector.js +6 -6
  233. package/utils/theme-selector.js.map +1 -1
  234. package/utils/fetch-component.d.ts +0 -3
  235. package/utils/fetch-component.d.ts.map +0 -1
  236. package/utils/fetch-component.js +0 -75
  237. package/utils/fetch-component.js.map +0 -1
@@ -1,17 +1,19 @@
1
- import { installComponent } from '../../commands/add/component-installer.js';
1
+ import { installComponent, validateTargetPath } from '../../commands/add/component-installer.js';
2
2
  import { selectComponents } from '../../commands/add/component-selector.js';
3
3
  import { updateProvideZardWithDarkMode } from '../../commands/add/dark-mode-setup.js';
4
- import { resolveDependencies, getTargetDir } from '../../commands/add/dependency-resolver.js';
4
+ import { getAllComponentNames, getTargetDir, resolveDependencies, } from '../../commands/add/dependency-resolver.js';
5
+ import { runAddWizard } from '../../commands/add/wizard.js';
6
+ import { indexHtmlFor } from '../../commands/init/project-kind.js';
5
7
  import { injectThemeScript } from '../../commands/init/theme-loader.js';
8
+ import { isInteractive, printReport, WizardCancelledError } from '../../ui/index.js';
6
9
  import { getConfig, resolveConfigPaths } from '../../utils/config.js';
10
+ import { CliError } from '../../utils/errors.js';
7
11
  import { getProjectInfo } from '../../utils/get-project-info.js';
8
12
  import { logger, spinner } from '../../utils/logger.js';
9
- import { installPackages } from '../../utils/package-manager.js';
10
- import chalk from 'chalk';
13
+ import { filterInstalledPackages, installPackagesWithRetry } from '../../utils/package-manager.js';
11
14
  import { Command } from 'commander';
12
15
  import { existsSync } from 'node:fs';
13
16
  import * as path from 'node:path';
14
- import prompts from 'prompts';
15
17
  export const add = new Command()
16
18
  .name('add')
17
19
  .description('add a component to your project')
@@ -24,114 +26,154 @@ export const add = new Command()
24
26
  .action(async (components, options) => {
25
27
  const cwd = path.resolve(options.cwd);
26
28
  validateWorkingDirectory(cwd);
29
+ if (options.path) {
30
+ validateTargetPath(path.resolve(cwd, options.path), cwd);
31
+ }
27
32
  const config = await loadConfiguration(cwd);
28
- await validateProject(cwd);
33
+ const projectInfo = await validateProject(cwd);
29
34
  const resolvedConfig = await resolveConfigPaths(cwd, config);
30
- const selectedComponents = await selectComponents(components, options.all);
31
- const addSpinner = spinner('Resolving components...').start();
32
- const { componentsToInstall, dependenciesToInstall } = await resolveDependencies(selectedComponents, resolvedConfig, cwd, options);
33
- addSpinner.stop();
34
- if (componentsToInstall.length === 0) {
35
- logger.info('All components already installed.');
35
+ const preselected = await selectComponents(components, options.all);
36
+ warnOnPrereleaseAngular(projectInfo.angularVersionRaw);
37
+ const actions = {
38
+ loadNames: () => getAllComponentNames(),
39
+ resolve: async (names) => {
40
+ const { componentsToInstall, dependenciesToInstall } = await resolveDependencies(names, resolvedConfig, cwd, options);
41
+ return {
42
+ components: componentsToInstall,
43
+ dependencies: resolveCompatibleVersions(dependenciesToInstall, projectInfo.angularVersion),
44
+ };
45
+ },
46
+ installDependencies: (packages) => installDependencies(packages, cwd, config.packageManager),
47
+ installComponent: (component) => installComponent(component.name, getTargetDir(component, resolvedConfig, cwd, options.path), resolvedConfig, {
48
+ customPath: Boolean(options.path),
49
+ }),
50
+ setupDarkMode: async (indexHtml) => {
51
+ await injectThemeScript(cwd, indexHtml);
52
+ await updateProvideZardWithDarkMode(cwd, resolvedConfig);
53
+ },
54
+ defaultIndexHtml: indexHtmlFor(config.projectType, config.baseUrl),
55
+ };
56
+ if (!isInteractive()) {
57
+ await runHeadless(preselected, options, actions);
36
58
  return;
37
59
  }
38
- if (!options.yes) {
39
- const shouldProceed = await confirmInstallation(componentsToInstall.length, dependenciesToInstall.size);
40
- if (!shouldProceed) {
60
+ try {
61
+ const { installed, logs } = await runAddWizard({
62
+ preselected,
63
+ skipConfirmation: options.yes,
64
+ ...actions,
65
+ });
66
+ reportSuccess(installed, logs);
67
+ }
68
+ catch (error) {
69
+ if (error instanceof WizardCancelledError) {
70
+ printReport({ status: 'cancelled', headline: error.message, notes: ['No files were written.'] });
41
71
  process.exit(0);
42
72
  }
73
+ throw error;
43
74
  }
44
- await installDependencies(dependenciesToInstall, cwd, config.packageManager);
45
- await installComponents(componentsToInstall, cwd, resolvedConfig, options);
46
- const isDarkModeBeingInstalled = componentsToInstall.some(c => c.name === 'dark-mode');
47
- if (isDarkModeBeingInstalled) {
48
- await setupDarkMode(cwd, resolvedConfig);
49
- }
50
- logger.break();
51
- logger.success('Done!');
52
75
  });
76
+ /**
77
+ * Caminho sem UI — CI, pipes e terminais não interativos.
78
+ *
79
+ * Sem alguém para escolher na lista, os componentes precisam vir por argumento
80
+ * ou via `--all`; a confirmação é dispensada porque não há como respondê-la.
81
+ */
82
+ async function runHeadless(preselected, options, actions) {
83
+ if (!preselected.length) {
84
+ throw new CliError('No components specified. Pass the component names or --all when running without an interactive terminal.', 'NO_COMPONENTS');
85
+ }
86
+ const resolveSpinner = spinner('Resolving components...').start();
87
+ const { components, dependencies } = await actions.resolve(preselected);
88
+ resolveSpinner.stop();
89
+ if (components.length === 0) {
90
+ logger.info('All components already installed.');
91
+ return;
92
+ }
93
+ if (dependencies.length) {
94
+ const depsSpinner = spinner('Installing dependencies...').start();
95
+ await actions.installDependencies(dependencies);
96
+ depsSpinner.succeed('Dependencies installed');
97
+ }
98
+ const installed = [];
99
+ const failed = [];
100
+ for (const component of components) {
101
+ const componentSpinner = spinner(`Installing ${component.name}...`).start();
102
+ try {
103
+ await actions.installComponent(component);
104
+ installed.push(component.name);
105
+ componentSpinner.succeed(component.name);
106
+ }
107
+ catch (error) {
108
+ failed.push(component.name);
109
+ componentSpinner.fail(component.name);
110
+ logger.debug(`Failed to install ${component.name}: ${error instanceof Error ? error.message : error}`);
111
+ }
112
+ }
113
+ if (components.some(component => component.name === 'dark-mode')) {
114
+ logger.warn('Dark mode needs an index.html path; run `zard-cli add dark-mode` interactively to configure it.');
115
+ }
116
+ if (failed.length) {
117
+ throw new CliError(`Failed to install: ${failed.join(', ')}`, 'INSTALL_FAILED');
118
+ }
119
+ reportSuccess(installed, []);
120
+ }
121
+ function reportSuccess(installed, logs) {
122
+ if (!installed.length) {
123
+ printReport({ status: 'success', headline: 'All components are already installed.', logs });
124
+ return;
125
+ }
126
+ printReport({
127
+ status: 'success',
128
+ headline: `Installed ${installed.length} component${installed.length > 1 ? 's' : ''}.`,
129
+ items: [...installed],
130
+ logs,
131
+ });
132
+ }
53
133
  function validateWorkingDirectory(cwd) {
54
134
  if (!existsSync(cwd)) {
55
- logger.error(`The path ${cwd} does not exist. Please try again.`);
56
- process.exit(1);
135
+ throw new CliError(`The path ${cwd} does not exist. Please try again.`, 'INVALID_CWD');
57
136
  }
58
137
  }
59
138
  async function loadConfiguration(cwd) {
60
139
  const config = await getConfig(cwd);
61
140
  if (!config) {
62
- logger.error('Configuration not found. Please run `ngzard init` first.');
63
- process.exit(1);
141
+ throw new CliError('Configuration not found. Please run `zard-cli init` first.', 'CONFIG_NOT_FOUND');
64
142
  }
65
143
  return config;
66
144
  }
67
145
  async function validateProject(cwd) {
68
146
  const projectInfo = await getProjectInfo(cwd);
69
147
  if (projectInfo.framework !== 'angular') {
70
- logger.error('This project does not appear to be an Angular project.');
71
- process.exit(1);
148
+ throw new CliError('This project does not appear to be an Angular project.', 'NOT_ANGULAR');
72
149
  }
73
150
  return projectInfo;
74
151
  }
75
- async function confirmInstallation(componentsCount, dependenciesCount) {
76
- const { proceed } = await prompts({
77
- type: 'confirm',
78
- name: 'proceed',
79
- message: `Ready to install ${componentsCount} component(s) and ${dependenciesCount} dependencies. Proceed?`,
80
- initial: true,
81
- });
82
- return proceed;
83
- }
84
- async function installDependencies(dependenciesToInstall, cwd, packageManager) {
85
- if (dependenciesToInstall.size === 0)
86
- return;
87
- const depsSpinner = spinner('Installing dependencies...').start();
88
- await installPackages(Array.from(dependenciesToInstall), cwd, packageManager, false);
89
- depsSpinner.succeed('Dependencies installed');
90
- }
91
- async function installComponents(componentsToInstall, cwd, resolvedConfig, options) {
92
- const installSpinner = spinner('Installing components...').start();
93
- const installed = [];
94
- const failed = [];
95
- for (const component of componentsToInstall) {
96
- try {
97
- installSpinner.text = `Installing ${component.name}...`;
98
- const targetDir = getTargetDir(component, resolvedConfig, cwd, options.path);
99
- await installComponent(component.name, targetDir, resolvedConfig);
100
- installed.push(component.name);
101
- }
102
- catch (error) {
103
- failed.push(component.name);
104
- }
105
- }
106
- if (failed.length > 0) {
107
- installSpinner.fail(`Failed to install: ${failed.join(', ')}`);
108
- }
109
- else {
110
- installSpinner.succeed(`Installed ${installed.length} component${installed.length > 1 ? 's' : ''}`);
152
+ function warnOnPrereleaseAngular(angularVersionRaw) {
153
+ if (angularVersionRaw && /-(rc|next|canary)/.test(angularVersionRaw)) {
154
+ logger.warn(`You are using a pre-release version of Angular (${angularVersionRaw}). Some dependencies may have compatibility issues.`);
111
155
  }
112
156
  }
113
- async function setupDarkMode(cwd, resolvedConfig) {
114
- logger.break();
115
- logger.info('Dark mode requires additional configuration.');
116
- const { indexFile } = await prompts({
117
- type: 'text',
118
- name: 'indexFile',
119
- message: `Where is your ${chalk.cyan('index.html')} file?`,
120
- initial: 'src/index.html',
157
+ const ANGULAR_VERSION_PACKAGES = ['embla-carousel-angular'];
158
+ function resolveCompatibleVersions(dependencies, angularVersion) {
159
+ const angularMajor = angularVersion ? parseInt(angularVersion.split('.')[0], 10) : null;
160
+ return Array.from(dependencies).map(dep => {
161
+ if (angularMajor && ANGULAR_VERSION_PACKAGES.includes(dep)) {
162
+ return `${dep}@^${angularMajor}.0.0`;
163
+ }
164
+ return dep;
121
165
  });
122
- if (!indexFile) {
123
- logger.warn('Skipping dark mode script injection.');
166
+ }
167
+ async function installDependencies(packages, cwd, packageManager) {
168
+ if (packages.length === 0)
169
+ return;
170
+ // Um projeto já inicializado costuma ter todas elas: sem o filtro, cada `add`
171
+ // pagaria uma revalidação completa da árvore para não instalar nada.
172
+ const missing = await filterInstalledPackages(packages, cwd);
173
+ if (missing.length === 0) {
174
+ logger.debug(`Dependencies already installed: ${packages.join(', ')}`);
124
175
  return;
125
176
  }
126
- const darkModeSpinner = spinner('Configuring dark mode...').start();
127
- try {
128
- await injectThemeScript(cwd, indexFile);
129
- await updateProvideZardWithDarkMode(cwd, resolvedConfig);
130
- darkModeSpinner.succeed('Dark mode configured');
131
- }
132
- catch (error) {
133
- darkModeSpinner.fail('Failed to configure dark mode');
134
- logger.error(error);
135
- }
177
+ await installPackagesWithRetry(missing, cwd, packageManager, false);
136
178
  }
137
179
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/add/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/add/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { type ComponentMeta } from '../../commands/add/dependency-resolver.js';
2
+ import { type LogRecord } from '../../ui/index.js';
3
+ export interface AddWizardOptions {
4
+ /** Componentes já informados na linha de comando — pulam a seleção. */
5
+ readonly preselected: readonly string[];
6
+ /** Carrega os nomes disponíveis; só é chamado quando há seleção a fazer. */
7
+ loadNames(): Promise<string[]>;
8
+ resolve(names: string[]): Promise<{
9
+ components: ComponentMeta[];
10
+ dependencies: string[];
11
+ }>;
12
+ /** Pula a confirmação (`--yes`). */
13
+ readonly skipConfirmation: boolean;
14
+ installDependencies(packages: string[]): Promise<void>;
15
+ installComponent(component: ComponentMeta): Promise<void>;
16
+ /** Só é chamado quando dark-mode entra na instalação. */
17
+ setupDarkMode(indexHtml: string): Promise<void>;
18
+ /**
19
+ * Onde o index.html deve estar, segundo o tipo de projeto configurado.
20
+ *
21
+ * Um `src/index.html` fixo só existe no app Angular único: num workspace ele
22
+ * está sob `apps/<app>/`, e no Analog é a página de entrada do Vite, na raiz.
23
+ */
24
+ readonly defaultIndexHtml: string;
25
+ }
26
+ export interface AddWizardResult {
27
+ readonly installed: readonly string[];
28
+ readonly logs: readonly LogRecord[];
29
+ }
30
+ export declare function runAddWizard(options: AddWizardOptions): Promise<AddWizardResult>;
31
+ //# sourceMappingURL=wizard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizard.d.ts","sourceRoot":"","sources":["../../../src/commands/add/wizard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,0CAA0C,CAAC;AAC9E,OAAO,EAuBL,KAAK,SAAS,EAKf,MAAM,kBAAkB,CAAC;AA6B1B,MAAM,WAAW,gBAAgB;IAC/B,uEAAuE;IACvE,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,4EAA4E;IAC5E,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/B,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAAE,UAAU,EAAE,aAAa,EAAE,CAAC;QAAC,YAAY,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC3F,oCAAoC;IACpC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,gBAAgB,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,yDAAyD;IACzD,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD;;;;;OAKG;IACH,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,CAAC;CACrC;AAID,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAwKtF"}
@@ -0,0 +1,289 @@
1
+ import { answeredLine, checkList, commandHeader, confirmField, controls, createGate, editInput, hint, page, progress, question, resultPanel, runWizard, screen, spacer, startInput, taskHeader, taskList, text, textField, } from '../../ui/index.js';
2
+ const DARK_MODE = 'dark-mode';
3
+ export async function runAddWizard(options) {
4
+ const state = {
5
+ phase: options.preselected.length ? 'resolving' : 'selecting',
6
+ names: [],
7
+ filter: '',
8
+ visible: [],
9
+ cursor: 0,
10
+ selected: new Set(),
11
+ componentCount: 0,
12
+ dependencyCount: 0,
13
+ confirmValue: true,
14
+ tasks: [],
15
+ tasksDone: 0,
16
+ taskStartedAt: 0,
17
+ indexHtml: startInput(options.defaultIndexHtml),
18
+ transcript: [],
19
+ failure: null,
20
+ installed: [],
21
+ };
22
+ const selection = createGate();
23
+ const confirmation = createGate();
24
+ const darkMode = createGate();
25
+ const finish = createGate();
26
+ const applyFilter = () => {
27
+ const term = state.filter.trim().toLowerCase();
28
+ state.visible = state.names
29
+ .map((_, index) => index)
30
+ .filter(index => !term || state.names[index].toLowerCase().includes(term));
31
+ state.cursor = Math.min(state.cursor, Math.max(0, state.visible.length - 1));
32
+ };
33
+ const onKey = (event, ctx) => {
34
+ if (state.phase === 'selecting') {
35
+ handleSelectionKey(event, state, applyFilter, selection);
36
+ return;
37
+ }
38
+ if (state.phase === 'confirming') {
39
+ if (event.key === 'left' || event.key === 'right')
40
+ state.confirmValue = !state.confirmValue;
41
+ else if (event.key === 'y' || event.key === 'Y')
42
+ confirmation.settle(true);
43
+ else if (event.key === 'n' || event.key === 'N' || event.key === 'escape')
44
+ confirmation.settle(false);
45
+ else if (event.key === 'enter')
46
+ confirmation.settle(state.confirmValue);
47
+ return;
48
+ }
49
+ if (state.phase === 'darkMode') {
50
+ if (event.key === 'enter') {
51
+ darkMode.settle(state.indexHtml.value.trim() || options.defaultIndexHtml);
52
+ return;
53
+ }
54
+ if (event.key === 'escape') {
55
+ darkMode.settle(null);
56
+ return;
57
+ }
58
+ const edited = editInput(state.indexHtml, event);
59
+ if (edited)
60
+ state.indexHtml = edited;
61
+ return;
62
+ }
63
+ if (state.phase === 'done' || state.phase === 'failed') {
64
+ if (event.key === 'enter')
65
+ finish.settle(undefined);
66
+ return;
67
+ }
68
+ void ctx;
69
+ };
70
+ const run = async (ctx) => {
71
+ let names;
72
+ if (options.preselected.length) {
73
+ names = [...options.preselected];
74
+ }
75
+ else {
76
+ state.names = await options.loadNames();
77
+ applyFilter();
78
+ ctx.refresh();
79
+ names = await selection.wait();
80
+ if (!names.length) {
81
+ ctx.cancel('No components selected.');
82
+ return;
83
+ }
84
+ state.transcript.push(['components', names.join(', ')]);
85
+ }
86
+ state.phase = 'resolving';
87
+ ctx.refresh();
88
+ const { components, dependencies } = await options.resolve(names);
89
+ if (components.length === 0) {
90
+ state.phase = 'done';
91
+ state.installed = [];
92
+ ctx.refresh();
93
+ await finish.wait();
94
+ ctx.done([]);
95
+ return;
96
+ }
97
+ state.componentCount = components.length;
98
+ state.dependencyCount = dependencies.length;
99
+ if (!options.skipConfirmation) {
100
+ state.phase = 'confirming';
101
+ ctx.refresh();
102
+ if (!(await confirmation.wait())) {
103
+ ctx.cancel();
104
+ return;
105
+ }
106
+ state.transcript.push(['install', `${components.length} component(s), ${dependencies.length} dependencies`]);
107
+ }
108
+ state.phase = 'installing';
109
+ state.tasks = [
110
+ ...(dependencies.length ? [{ label: 'dependencies', note: dependencies.join(', ') }] : []),
111
+ ...components.map(component => ({ label: component.name, note: 'component source' })),
112
+ ];
113
+ state.tasksDone = 0;
114
+ state.taskStartedAt = Date.now();
115
+ ctx.refresh();
116
+ if (dependencies.length) {
117
+ await options.installDependencies(dependencies);
118
+ state.tasksDone++;
119
+ state.taskStartedAt = Date.now();
120
+ ctx.refresh();
121
+ }
122
+ const failed = [];
123
+ for (const component of components) {
124
+ try {
125
+ await options.installComponent(component);
126
+ state.installed.push(component.name);
127
+ }
128
+ catch (error) {
129
+ failed.push(component.name);
130
+ state.failure = `${component.name}: ${error instanceof Error ? error.message : String(error)}`;
131
+ }
132
+ state.tasksDone++;
133
+ state.taskStartedAt = Date.now();
134
+ ctx.refresh();
135
+ }
136
+ if (components.some(component => component.name === DARK_MODE)) {
137
+ state.phase = 'darkMode';
138
+ ctx.refresh();
139
+ const indexHtml = await darkMode.wait();
140
+ if (indexHtml) {
141
+ state.transcript.push(['index.html', indexHtml]);
142
+ await options.setupDarkMode(indexHtml);
143
+ }
144
+ }
145
+ state.phase = failed.length ? 'failed' : 'done';
146
+ ctx.refresh();
147
+ await finish.wait();
148
+ ctx.done(state.installed);
149
+ };
150
+ const result = await runWizard({
151
+ view: () => buildView(state),
152
+ onKey,
153
+ run,
154
+ });
155
+ return { installed: result.value, logs: result.logs };
156
+ }
157
+ function handleSelectionKey(event, state, applyFilter, selection) {
158
+ const total = state.visible.length;
159
+ if (event.key === 'up') {
160
+ state.cursor = total ? (state.cursor - 1 + total) % total : 0;
161
+ return;
162
+ }
163
+ if (event.key === 'down') {
164
+ state.cursor = total ? (state.cursor + 1) % total : 0;
165
+ return;
166
+ }
167
+ if (event.key === ' ' || event.key === 'space') {
168
+ const index = state.visible[state.cursor];
169
+ if (index !== undefined) {
170
+ if (state.selected.has(index))
171
+ state.selected.delete(index);
172
+ else
173
+ state.selected.add(index);
174
+ }
175
+ return;
176
+ }
177
+ if (event.ctrl && event.key === 'a') {
178
+ // Alterna tudo que está visível, respeitando o filtro corrente.
179
+ const allSelected = state.visible.every(index => state.selected.has(index));
180
+ for (const index of state.visible) {
181
+ if (allSelected)
182
+ state.selected.delete(index);
183
+ else
184
+ state.selected.add(index);
185
+ }
186
+ return;
187
+ }
188
+ if (event.key === 'enter') {
189
+ selection.settle([...state.selected].sort((a, b) => a - b).map(index => state.names[index]));
190
+ return;
191
+ }
192
+ if (event.key === 'backspace') {
193
+ state.filter = [...state.filter].slice(0, -1).join('');
194
+ applyFilter();
195
+ return;
196
+ }
197
+ if (event.key.length === 1 && !event.ctrl && !event.alt) {
198
+ state.filter += event.key;
199
+ applyFilter();
200
+ }
201
+ }
202
+ /** Janela deslizante da lista: mantém o cursor sempre visível. */
203
+ const VISIBLE_ROWS = 10;
204
+ function windowOf(state) {
205
+ if (state.visible.length <= VISIBLE_ROWS)
206
+ return { slice: state.visible, offset: 0 };
207
+ const half = Math.floor(VISIBLE_ROWS / 2);
208
+ const max = state.visible.length - VISIBLE_ROWS;
209
+ const offset = Math.max(0, Math.min(state.cursor - half, max));
210
+ return { slice: state.visible.slice(offset, offset + VISIBLE_ROWS), offset };
211
+ }
212
+ function buildView(state) {
213
+ const body = [commandHeader('add', 'Add components to your project'), text('')];
214
+ for (const [label, value] of state.transcript)
215
+ body.push(answeredLine(label, value));
216
+ if (state.transcript.length)
217
+ body.push(text(''));
218
+ if (state.phase === 'selecting') {
219
+ const { slice, offset } = windowOf(state);
220
+ const choices = slice.map(index => ({ label: state.names[index] }));
221
+ const localCursor = state.cursor - offset;
222
+ const localSelected = new Set(slice.map((index, position) => (state.selected.has(index) ? position : -1)).filter(position => position >= 0));
223
+ body.push(question('Which components would you like to add?'));
224
+ body.push(textField(state.filter));
225
+ if (choices.length) {
226
+ body.push(...checkList(choices, localCursor, localSelected));
227
+ }
228
+ else {
229
+ body.push(hint('No component matches this filter.'));
230
+ }
231
+ body.push(text(''));
232
+ body.push(hint(`${state.selected.size} selected · ${state.visible.length} of ${state.names.length} shown`));
233
+ body.push(spacer());
234
+ body.push(controls([
235
+ ['↑/↓', 'move'],
236
+ ['space', 'select'],
237
+ ['ctrl+a', 'toggle all'],
238
+ ['enter', 'confirm'],
239
+ ]));
240
+ }
241
+ else if (state.phase === 'resolving') {
242
+ body.push(taskHeader('Resolving components and dependencies…', false));
243
+ body.push(spacer());
244
+ }
245
+ else if (state.phase === 'confirming') {
246
+ body.push(question(`Ready to install ${state.componentCount} component(s) and ${state.dependencyCount} dependencies. Proceed?`));
247
+ body.push(confirmField(state.confirmValue));
248
+ body.push(hint('Existing files are kept unless you passed --overwrite.'));
249
+ body.push(spacer());
250
+ body.push(controls([
251
+ ['y/n · ←/→', 'toggle'],
252
+ ['enter', 'confirm'],
253
+ ]));
254
+ }
255
+ else if (state.phase === 'darkMode') {
256
+ body.push(question('Where is your index.html file?'));
257
+ body.push(textField(state.indexHtml.value, state.indexHtml.caret));
258
+ body.push(hint('Dark mode injects a small script there to apply the theme before first paint.'));
259
+ body.push(spacer());
260
+ body.push(controls([
261
+ ['enter', 'confirm'],
262
+ ['esc', 'skip'],
263
+ ]));
264
+ }
265
+ else {
266
+ body.push(...installBlock(state));
267
+ body.push(spacer());
268
+ body.push(controls([['enter', state.phase === 'failed' ? 'exit' : 'finish']]));
269
+ }
270
+ return screen(page(...body));
271
+ }
272
+ function installBlock(state) {
273
+ const allDone = state.tasksDone >= state.tasks.length;
274
+ const nodes = [];
275
+ if (state.tasks.length) {
276
+ nodes.push(taskHeader(state.phase === 'failed' ? 'Finished with errors' : 'Installing…', allDone), text(''), ...taskList(state.tasks, state.tasksDone, state.phase === 'installing' ? Date.now() - state.taskStartedAt : undefined), text(''), progress(state.tasksDone, state.tasks.length), text(''));
277
+ }
278
+ if (state.phase === 'failed') {
279
+ nodes.push(resultPanel('danger', state.failure ?? 'Some components could not be installed.'));
280
+ }
281
+ else if (state.installed.length) {
282
+ nodes.push(resultPanel('success', `Installed ${state.installed.length} component${state.installed.length > 1 ? 's' : ''}.`));
283
+ }
284
+ else {
285
+ nodes.push(resultPanel('success', 'All components are already installed.'));
286
+ }
287
+ return nodes;
288
+ }
289
+ //# sourceMappingURL=wizard.js.map