zard-cli 1.0.0-beta.12 → 1.0.0-beta.120

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 (265) hide show
  1. package/README.md +39 -167
  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 +5 -2
  15. package/commands/add/dependency-resolver.d.ts.map +1 -1
  16. package/commands/add/dependency-resolver.js +54 -20
  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 +135 -86
  20. package/commands/add/index.js.map +1 -1
  21. package/commands/add/typeset-setup.d.ts +12 -0
  22. package/commands/add/typeset-setup.d.ts.map +1 -0
  23. package/commands/add/typeset-setup.js +68 -0
  24. package/commands/add/typeset-setup.js.map +1 -0
  25. package/commands/add/wizard.d.ts +34 -0
  26. package/commands/add/wizard.d.ts.map +1 -0
  27. package/commands/add/wizard.js +295 -0
  28. package/commands/add/wizard.js.map +1 -0
  29. package/commands/init/config-prompter.d.ts +66 -56
  30. package/commands/init/config-prompter.d.ts.map +1 -1
  31. package/commands/init/config-prompter.js +90 -74
  32. package/commands/init/config-prompter.js.map +1 -1
  33. package/commands/init/dependencies.d.ts +1 -8
  34. package/commands/init/dependencies.d.ts.map +1 -1
  35. package/commands/init/dependencies.js +51 -23
  36. package/commands/init/dependencies.js.map +1 -1
  37. package/commands/init/index.d.ts.map +1 -1
  38. package/commands/init/index.js +150 -86
  39. package/commands/init/index.js.map +1 -1
  40. package/commands/init/project-kind.d.ts +82 -0
  41. package/commands/init/project-kind.d.ts.map +1 -0
  42. package/commands/init/project-kind.js +166 -0
  43. package/commands/init/project-kind.js.map +1 -0
  44. package/commands/init/steps.d.ts +15 -0
  45. package/commands/init/steps.d.ts.map +1 -0
  46. package/commands/init/steps.js +154 -0
  47. package/commands/init/steps.js.map +1 -0
  48. package/commands/init/tailwind-setup.d.ts +9 -2
  49. package/commands/init/tailwind-setup.d.ts.map +1 -1
  50. package/commands/init/tailwind-setup.js +33 -9
  51. package/commands/init/tailwind-setup.js.map +1 -1
  52. package/commands/init/theme-loader.d.ts.map +1 -1
  53. package/commands/init/theme-loader.js +1 -3
  54. package/commands/init/theme-loader.js.map +1 -1
  55. package/commands/init/tsconfig-updater.d.ts +8 -1
  56. package/commands/init/tsconfig-updater.d.ts.map +1 -1
  57. package/commands/init/tsconfig-updater.js +30 -11
  58. package/commands/init/tsconfig-updater.js.map +1 -1
  59. package/commands/init/update-angular-config.d.ts.map +1 -1
  60. package/commands/init/update-angular-config.js +28 -47
  61. package/commands/init/update-angular-config.js.map +1 -1
  62. package/commands/init/vite-setup.d.ts +11 -0
  63. package/commands/init/vite-setup.d.ts.map +1 -0
  64. package/commands/init/vite-setup.js +61 -0
  65. package/commands/init/vite-setup.js.map +1 -0
  66. package/commands/init/wizard.d.ts +30 -0
  67. package/commands/init/wizard.d.ts.map +1 -0
  68. package/commands/init/wizard.js +560 -0
  69. package/commands/init/wizard.js.map +1 -0
  70. package/core/icons/families.d.ts +38 -0
  71. package/core/icons/families.d.ts.map +1 -0
  72. package/core/icons/families.js +26 -0
  73. package/core/icons/families.js.map +1 -0
  74. package/core/icons/icon-map.d.ts +24 -0
  75. package/core/icons/icon-map.d.ts.map +1 -0
  76. package/core/icons/icon-map.js +135 -0
  77. package/core/icons/icon-map.js.map +1 -0
  78. package/core/icons/index.d.ts +107 -0
  79. package/core/icons/index.d.ts.map +1 -0
  80. package/core/icons/index.js +183 -0
  81. package/core/icons/index.js.map +1 -0
  82. package/core/registry/registry-data.d.ts.map +1 -1
  83. package/core/registry/registry-data.js +752 -126
  84. package/core/registry/registry-data.js.map +1 -1
  85. package/core/themes/theme-definitions.d.ts +5 -5
  86. package/core/themes/theme-definitions.d.ts.map +1 -1
  87. package/core/themes/theme-definitions.js +75 -61
  88. package/core/themes/theme-definitions.js.map +1 -1
  89. package/index.js +41 -4
  90. package/index.js.map +1 -1
  91. package/package.json +9 -14
  92. package/ui/blocks.d.ts +71 -0
  93. package/ui/blocks.d.ts.map +1 -0
  94. package/ui/blocks.js +116 -0
  95. package/ui/blocks.js.map +1 -0
  96. package/ui/brand.d.ts +14 -0
  97. package/ui/brand.d.ts.map +1 -0
  98. package/ui/brand.js +35 -0
  99. package/ui/brand.js.map +1 -0
  100. package/ui/engine/animation/index.d.ts +38 -0
  101. package/ui/engine/animation/index.d.ts.map +1 -0
  102. package/ui/engine/animation/index.js +102 -0
  103. package/ui/engine/animation/index.js.map +1 -0
  104. package/ui/engine/ansi/index.d.ts +51 -0
  105. package/ui/engine/ansi/index.d.ts.map +1 -0
  106. package/ui/engine/ansi/index.js +116 -0
  107. package/ui/engine/ansi/index.js.map +1 -0
  108. package/ui/engine/components/index.d.ts +211 -0
  109. package/ui/engine/components/index.d.ts.map +1 -0
  110. package/ui/engine/components/index.js +109 -0
  111. package/ui/engine/components/index.js.map +1 -0
  112. package/ui/engine/cursor/index.d.ts +16 -0
  113. package/ui/engine/cursor/index.d.ts.map +1 -0
  114. package/ui/engine/cursor/index.js +40 -0
  115. package/ui/engine/cursor/index.js.map +1 -0
  116. package/ui/engine/diff/index.d.ts +26 -0
  117. package/ui/engine/diff/index.d.ts.map +1 -0
  118. package/ui/engine/diff/index.js +56 -0
  119. package/ui/engine/diff/index.js.map +1 -0
  120. package/ui/engine/events/index.d.ts +24 -0
  121. package/ui/engine/events/index.d.ts.map +1 -0
  122. package/ui/engine/events/index.js +60 -0
  123. package/ui/engine/events/index.js.map +1 -0
  124. package/ui/engine/focus/index.d.ts +25 -0
  125. package/ui/engine/focus/index.d.ts.map +1 -0
  126. package/ui/engine/focus/index.js +77 -0
  127. package/ui/engine/focus/index.js.map +1 -0
  128. package/ui/engine/frame/index.d.ts +48 -0
  129. package/ui/engine/frame/index.d.ts.map +1 -0
  130. package/ui/engine/frame/index.js +0 -0
  131. package/ui/engine/frame/index.js.map +1 -0
  132. package/ui/engine/index.d.ts +28 -0
  133. package/ui/engine/index.d.ts.map +1 -0
  134. package/ui/engine/index.js +28 -0
  135. package/ui/engine/index.js.map +1 -0
  136. package/ui/engine/input/index.d.ts +36 -0
  137. package/ui/engine/input/index.d.ts.map +1 -0
  138. package/ui/engine/input/index.js +224 -0
  139. package/ui/engine/input/index.js.map +1 -0
  140. package/ui/engine/layout/index.d.ts +42 -0
  141. package/ui/engine/layout/index.d.ts.map +1 -0
  142. package/ui/engine/layout/index.js +241 -0
  143. package/ui/engine/layout/index.js.map +1 -0
  144. package/ui/engine/renderer/index.d.ts +43 -0
  145. package/ui/engine/renderer/index.d.ts.map +1 -0
  146. package/ui/engine/renderer/index.js +619 -0
  147. package/ui/engine/renderer/index.js.map +1 -0
  148. package/ui/engine/scheduler/index.d.ts +22 -0
  149. package/ui/engine/scheduler/index.d.ts.map +1 -0
  150. package/ui/engine/scheduler/index.js +77 -0
  151. package/ui/engine/scheduler/index.js.map +1 -0
  152. package/ui/engine/screen/index.d.ts +39 -0
  153. package/ui/engine/screen/index.d.ts.map +1 -0
  154. package/ui/engine/screen/index.js +255 -0
  155. package/ui/engine/screen/index.js.map +1 -0
  156. package/ui/engine/terminal/index.d.ts +84 -0
  157. package/ui/engine/terminal/index.d.ts.map +1 -0
  158. package/ui/engine/terminal/index.js +235 -0
  159. package/ui/engine/terminal/index.js.map +1 -0
  160. package/ui/engine/testing/index.d.ts +27 -0
  161. package/ui/engine/testing/index.d.ts.map +1 -0
  162. package/ui/engine/testing/index.js +63 -0
  163. package/ui/engine/testing/index.js.map +1 -0
  164. package/ui/engine/theme/index.d.ts +26 -0
  165. package/ui/engine/theme/index.d.ts.map +1 -0
  166. package/ui/engine/theme/index.js +128 -0
  167. package/ui/engine/theme/index.js.map +1 -0
  168. package/ui/engine/utils/index.d.ts +12 -0
  169. package/ui/engine/utils/index.d.ts.map +1 -0
  170. package/ui/engine/utils/index.js +143 -0
  171. package/ui/engine/utils/index.js.map +1 -0
  172. package/ui/gate.d.ts +19 -0
  173. package/ui/gate.d.ts.map +1 -0
  174. package/ui/gate.js +36 -0
  175. package/ui/gate.js.map +1 -0
  176. package/ui/index.d.ts +18 -0
  177. package/ui/index.d.ts.map +1 -0
  178. package/ui/index.js +18 -0
  179. package/ui/index.js.map +1 -0
  180. package/ui/log-sink.d.ts +24 -0
  181. package/ui/log-sink.d.ts.map +1 -0
  182. package/ui/log-sink.js +35 -0
  183. package/ui/log-sink.js.map +1 -0
  184. package/ui/output.d.ts +14 -0
  185. package/ui/output.d.ts.map +1 -0
  186. package/ui/output.js +28 -0
  187. package/ui/output.js.map +1 -0
  188. package/ui/report.d.ts +30 -0
  189. package/ui/report.d.ts.map +1 -0
  190. package/ui/report.js +45 -0
  191. package/ui/report.js.map +1 -0
  192. package/ui/runner.d.ts +66 -0
  193. package/ui/runner.d.ts.map +1 -0
  194. package/ui/runner.js +135 -0
  195. package/ui/runner.js.map +1 -0
  196. package/ui/style.d.ts +24 -0
  197. package/ui/style.d.ts.map +1 -0
  198. package/ui/style.js +44 -0
  199. package/ui/style.js.map +1 -0
  200. package/ui/testing/fake-tty.d.ts +26 -0
  201. package/ui/testing/fake-tty.d.ts.map +1 -0
  202. package/ui/testing/fake-tty.js +61 -0
  203. package/ui/testing/fake-tty.js.map +1 -0
  204. package/ui/text-input.d.ts +31 -0
  205. package/ui/text-input.d.ts.map +1 -0
  206. package/ui/text-input.js +89 -0
  207. package/ui/text-input.js.map +1 -0
  208. package/ui/theme.d.ts +10 -0
  209. package/ui/theme.d.ts.map +1 -0
  210. package/ui/theme.js +20 -0
  211. package/ui/theme.js.map +1 -0
  212. package/utils/angular-compat.d.ts +21 -0
  213. package/utils/angular-compat.d.ts.map +1 -0
  214. package/utils/angular-compat.js +52 -0
  215. package/utils/angular-compat.js.map +1 -0
  216. package/utils/config.d.ts +52 -69
  217. package/utils/config.d.ts.map +1 -1
  218. package/utils/config.js +60 -9
  219. package/utils/config.js.map +1 -1
  220. package/utils/errors.d.ts +27 -0
  221. package/utils/errors.d.ts.map +1 -0
  222. package/utils/errors.js +45 -0
  223. package/utils/errors.js.map +1 -0
  224. package/utils/get-package-info.js +4 -4
  225. package/utils/get-package-info.js.map +1 -1
  226. package/utils/get-project-info.d.ts +30 -0
  227. package/utils/get-project-info.d.ts.map +1 -1
  228. package/utils/get-project-info.js +195 -6
  229. package/utils/get-project-info.js.map +1 -1
  230. package/utils/http-client.d.ts +8 -0
  231. package/utils/http-client.d.ts.map +1 -0
  232. package/utils/http-client.js +83 -0
  233. package/utils/http-client.js.map +1 -0
  234. package/utils/icon-catalog.d.ts +34 -0
  235. package/utils/icon-catalog.d.ts.map +1 -0
  236. package/utils/icon-catalog.js +63 -0
  237. package/utils/icon-catalog.js.map +1 -0
  238. package/utils/logger.d.ts +16 -1
  239. package/utils/logger.d.ts.map +1 -1
  240. package/utils/logger.js +104 -12
  241. package/utils/logger.js.map +1 -1
  242. package/utils/package-manager.d.ts +44 -1
  243. package/utils/package-manager.d.ts.map +1 -1
  244. package/utils/package-manager.js +210 -14
  245. package/utils/package-manager.js.map +1 -1
  246. package/utils/registry.d.ts +44 -2
  247. package/utils/registry.d.ts.map +1 -1
  248. package/utils/registry.js +89 -30
  249. package/utils/registry.js.map +1 -1
  250. package/utils/schema-version.d.ts +21 -0
  251. package/utils/schema-version.d.ts.map +1 -0
  252. package/utils/schema-version.js +28 -0
  253. package/utils/schema-version.js.map +1 -0
  254. package/utils/source-file.d.ts +40 -0
  255. package/utils/source-file.d.ts.map +1 -0
  256. package/utils/source-file.js +104 -0
  257. package/utils/source-file.js.map +1 -0
  258. package/utils/theme-selector.d.ts +1 -1
  259. package/utils/theme-selector.d.ts.map +1 -1
  260. package/utils/theme-selector.js +6 -6
  261. package/utils/theme-selector.js.map +1 -1
  262. package/utils/fetch-component.d.ts +0 -3
  263. package/utils/fetch-component.d.ts.map +0 -1
  264. package/utils/fetch-component.js +0 -75
  265. package/utils/fetch-component.js.map +0 -1
@@ -1,5 +1,48 @@
1
- export declare function detectPackageManager(): Promise<'npm' | 'yarn' | 'pnpm' | 'bun'>;
1
+ type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun';
2
+ /**
3
+ * Which manager the *project* uses.
4
+ *
5
+ * Order matters. `npm_config_user_agent` describes how the CLI was invoked
6
+ * (`npx` always says npm), not what the project uses — trusting it first gave a
7
+ * bun project `packageManager: "npm"` in its components.json and a
8
+ * package-lock.json next to its bun.lock. The project answers for itself: the
9
+ * package.json `packageManager` field first, then the lockfiles.
10
+ */
11
+ export declare function detectPackageManager(cwd?: string): Promise<PackageManager>;
12
+ /**
13
+ * How to suggest running the CLI again.
14
+ *
15
+ * A different question: not which manager the project installs dependencies
16
+ * with, but how the CLI was just invoked. Someone who ran `npx zard-cli init`
17
+ * in a bun project does not expect to finish reading `bunx` — and the `npx`
18
+ * they already used works. Only when that cannot be known does the project's
19
+ * manager answer.
20
+ */
21
+ export declare function suggestedRunner(packageManager: PackageManager): string;
2
22
  export declare function getPackageManager(cwd?: string): Promise<'npm' | 'yarn' | 'pnpm' | 'bun'>;
3
23
  export declare function getInstallCommand(packageManager: string, isDev?: boolean): Promise<string[]>;
4
24
  export declare function installPackages(packages: string[], cwd: string, packageManager: 'npm' | 'yarn' | 'pnpm' | 'bun', isDev?: boolean, legacyPeerDeps?: boolean): Promise<void>;
25
+ /**
26
+ * Installs the batch and, if the manager rejects the tree over a peer conflict,
27
+ * retries with the check relaxed.
28
+ *
29
+ * The fallback is remembered for the rest of the run: once the first batch
30
+ * needed it, the following ones will need it for the same reason, and an
31
+ * attempt already known to be doomed costs a full tree resolution.
32
+ */
33
+ export declare function installPackagesWithRetry(packages: string[], cwd: string, packageManager: PackageManager, isDev?: boolean): Promise<void>;
34
+ /**
35
+ * Drops from the batch the packages the project already declares and resolves.
36
+ *
37
+ * The manager charges a lot per invocation — it revalidates the whole tree even
38
+ * when there is nothing to do — so the win is not in making the install faster
39
+ * but in not calling it. An `add` in an already-initialized project asks for
40
+ * exactly the dependencies `init` put there.
41
+ *
42
+ * The filter is deliberately conservative: when in doubt the package stays in
43
+ * the batch and the manager decides. Comparing only the major is enough because
44
+ * the versions the CLI asks for are always of the form `^N`.
45
+ */
46
+ export declare function filterInstalledPackages(packages: string[], cwd: string): Promise<string[]>;
47
+ export {};
5
48
  //# sourceMappingURL=package-manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"package-manager.d.ts","sourceRoot":"","sources":["../../src/utils/package-manager.ts"],"names":[],"mappings":"AAIA,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,CAgBrF;AAED,wBAAsB,iBAAiB,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,CAG7G;AAED,wBAAsB,iBAAiB,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,UAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAYhG;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,EAAE,KAAK,UAAQ,EAAE,cAAc,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAW5K"}
1
+ {"version":3,"file":"package-manager.d.ts","sourceRoot":"","sources":["../../src/utils/package-manager.ts"],"names":[],"mappings":"AAQA,KAAK,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAYtD;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,cAAc,CAAC,CAgB/F;AASD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,cAAc,GAAG,MAAM,CAStE;AAYD,wBAAsB,iBAAiB,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,CAG7G;AAED,wBAAsB,iBAAiB,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,UAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAYhG;AAaD,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAAE,EAClB,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,EAC/C,KAAK,UAAQ,EACb,cAAc,UAAQ,GACrB,OAAO,CAAC,IAAI,CAAC,CA8Cf;AAcD;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,MAAM,EAAE,EAClB,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,cAAc,EAC9B,KAAK,UAAQ,GACZ,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAchG"}
@@ -1,22 +1,80 @@
1
1
  import { detect } from '@antfu/ni';
2
+ import { isCapturing } from '../ui/log-sink.js';
2
3
  import { getConfig } from '../utils/config.js';
3
- export async function detectPackageManager() {
4
+ import { logger } from '../utils/logger.js';
5
+ import { existsSync } from 'node:fs';
6
+ import { readFile } from 'node:fs/promises';
7
+ import * as path from 'node:path';
8
+ let cachedPackageManager = null;
9
+ const SUPPORTED = ['npm', 'yarn', 'pnpm', 'bun'];
10
+ function asPackageManager(value) {
11
+ // `yarn@berry`, `pnpm@6`, `bun@1.3.14` — only the family matters.
12
+ const name = value?.split('@')[0];
13
+ return SUPPORTED.includes(name) ? name : null;
14
+ }
15
+ /**
16
+ * Which manager the *project* uses.
17
+ *
18
+ * Order matters. `npm_config_user_agent` describes how the CLI was invoked
19
+ * (`npx` always says npm), not what the project uses — trusting it first gave a
20
+ * bun project `packageManager: "npm"` in its components.json and a
21
+ * package-lock.json next to its bun.lock. The project answers for itself: the
22
+ * package.json `packageManager` field first, then the lockfiles.
23
+ */
24
+ export async function detectPackageManager(cwd = process.cwd()) {
25
+ if (cachedPackageManager)
26
+ return cachedPackageManager;
27
+ const declared = asPackageManager(await readPackageManagerField(cwd));
28
+ if (declared)
29
+ return (cachedPackageManager = declared);
30
+ const fromLockfile = asPackageManager(await detect({ programmatic: true, cwd }));
31
+ if (fromLockfile)
32
+ return (cachedPackageManager = fromLockfile);
4
33
  const userAgent = process.env.npm_config_user_agent || '';
5
34
  if (userAgent.includes('bun'))
6
- return 'bun';
35
+ return (cachedPackageManager = 'bun');
7
36
  if (userAgent.includes('pnpm'))
8
- return 'pnpm';
37
+ return (cachedPackageManager = 'pnpm');
9
38
  if (userAgent.includes('yarn'))
10
- return 'yarn';
11
- if (userAgent.includes('npm'))
12
- return 'npm';
13
- const agent = await detect({ programmatic: true });
14
- if (agent === 'yarn@berry')
15
- return 'yarn';
16
- if (agent && ['npm', 'yarn', 'pnpm', 'bun'].includes(agent)) {
17
- return agent;
39
+ return (cachedPackageManager = 'yarn');
40
+ return (cachedPackageManager = 'npm');
41
+ }
42
+ const RUNNER = {
43
+ npm: 'npx',
44
+ yarn: 'yarn dlx',
45
+ pnpm: 'pnpm dlx',
46
+ bun: 'bunx',
47
+ };
48
+ /**
49
+ * How to suggest running the CLI again.
50
+ *
51
+ * A different question: not which manager the project installs dependencies
52
+ * with, but how the CLI was just invoked. Someone who ran `npx zard-cli init`
53
+ * in a bun project does not expect to finish reading `bunx` — and the `npx`
54
+ * they already used works. Only when that cannot be known does the project's
55
+ * manager answer.
56
+ */
57
+ export function suggestedRunner(packageManager) {
58
+ const userAgent = process.env.npm_config_user_agent || '';
59
+ if (userAgent.startsWith('bun'))
60
+ return RUNNER.bun;
61
+ if (userAgent.startsWith('pnpm'))
62
+ return RUNNER.pnpm;
63
+ if (userAgent.startsWith('yarn'))
64
+ return RUNNER.yarn;
65
+ if (userAgent.startsWith('npm'))
66
+ return RUNNER.npm;
67
+ return RUNNER[packageManager];
68
+ }
69
+ /** The package.json `packageManager` field — the Corepack standard, an explicit declaration. */
70
+ async function readPackageManagerField(cwd) {
71
+ try {
72
+ const manifest = JSON.parse(await readFile(path.join(cwd, 'package.json'), 'utf8'));
73
+ return typeof manifest.packageManager === 'string' ? manifest.packageManager : null;
74
+ }
75
+ catch {
76
+ return null;
18
77
  }
19
- return 'npm';
20
78
  }
21
79
  export async function getPackageManager(cwd = process.cwd()) {
22
80
  const config = await getConfig(cwd);
@@ -35,13 +93,151 @@ export async function getInstallCommand(packageManager, isDev = false) {
35
93
  return isDev ? ['install', '-D'] : ['install'];
36
94
  }
37
95
  }
96
+ /**
97
+ * Work the manager does out of habit that the install itself does not need.
98
+ *
99
+ * The vulnerability audit sends the whole tree to the registry and waits for an
100
+ * answer; in an Angular project, with over a thousand packages, that alone
101
+ * accounts for several seconds of a call that installs half a dozen.
102
+ */
103
+ function speedFlags(packageManager) {
104
+ return packageManager === 'npm' ? ['--no-audit', '--no-fund'] : [];
105
+ }
38
106
  export async function installPackages(packages, cwd, packageManager, isDev = false, legacyPeerDeps = false) {
39
107
  const { execa } = await import('execa');
40
108
  const installCmd = await getInstallCommand(packageManager, isDev);
41
- const args = [...installCmd, ...packages];
109
+ const args = [...installCmd, ...packages, ...speedFlags(packageManager)];
42
110
  if (legacyPeerDeps && packageManager === 'npm') {
43
111
  args.push('--legacy-peer-deps');
44
112
  }
45
- await execa(packageManager, args, { cwd, stdio: 'inherit' });
113
+ if (legacyPeerDeps && packageManager === 'pnpm') {
114
+ args.push('--no-strict-peer-dependencies');
115
+ }
116
+ // With the interactive screen mounted, inheriting stdio would let the package
117
+ // manager write over the frame. In that case the output is captured and only
118
+ // shows up in debug mode; outside it, the behaviour stays "pass the output
119
+ // through live".
120
+ if (isCapturing()) {
121
+ const command = `${packageManager} ${args.join(' ')}`;
122
+ try {
123
+ // stdin ignored, not piped: an open input pipe never sees EOF and the
124
+ // package manager waits on it forever. Closing stdin also guarantees it
125
+ // never opens a prompt, which would be invisible behind the full screen.
126
+ const result = await execa(packageManager, args, {
127
+ cwd,
128
+ stdin: 'ignore',
129
+ stdout: 'pipe',
130
+ stderr: 'pipe',
131
+ });
132
+ logger.debug(`${command}\n${result.stdout}`);
133
+ }
134
+ catch (error) {
135
+ // Without this the failure reaches the user as one generic line: the
136
+ // package manager's real output stays in the sink and is printed with the
137
+ // summary.
138
+ logger.error(`${command} failed:\n${outputOf(error)}`);
139
+ throw error;
140
+ }
141
+ return;
142
+ }
143
+ // stdin ignored here too. The install takes its packages as arguments and has
144
+ // nothing to ask; inheriting a stdin that never closes (a pipe, CI, a
145
+ // background job) leaves the manager waiting for an EOF that never comes —
146
+ // output stays live because stdout and stderr are still inherited.
147
+ await execa(packageManager, args, { cwd, stdin: 'ignore', stdout: 'inherit', stderr: 'inherit' });
148
+ }
149
+ function outputOf(error) {
150
+ const { stderr, stdout, message } = (error ?? {});
151
+ return (stderr?.trim() || stdout?.trim() || message || String(error)).trim();
152
+ }
153
+ /** Only npm and pnpm can relax peer checking; elsewhere, retrying repeats the same failure. */
154
+ function canRelaxPeers(packageManager) {
155
+ return packageManager === 'npm' || packageManager === 'pnpm';
156
+ }
157
+ let peerRelaxationEngaged = false;
158
+ /**
159
+ * Installs the batch and, if the manager rejects the tree over a peer conflict,
160
+ * retries with the check relaxed.
161
+ *
162
+ * The fallback is remembered for the rest of the run: once the first batch
163
+ * needed it, the following ones will need it for the same reason, and an
164
+ * attempt already known to be doomed costs a full tree resolution.
165
+ */
166
+ export async function installPackagesWithRetry(packages, cwd, packageManager, isDev = false) {
167
+ if (packages.length === 0)
168
+ return;
169
+ if (peerRelaxationEngaged) {
170
+ await installPackages(packages, cwd, packageManager, isDev, true);
171
+ return;
172
+ }
173
+ try {
174
+ await installPackages(packages, cwd, packageManager, isDev);
175
+ }
176
+ catch (error) {
177
+ if (!canRelaxPeers(packageManager))
178
+ throw error;
179
+ logger.warn('Installation failed, retrying with relaxed peer dependency resolution...');
180
+ await installPackages(packages, cwd, packageManager, isDev, true);
181
+ peerRelaxationEngaged = true;
182
+ }
183
+ }
184
+ /**
185
+ * Drops from the batch the packages the project already declares and resolves.
186
+ *
187
+ * The manager charges a lot per invocation — it revalidates the whole tree even
188
+ * when there is nothing to do — so the win is not in making the install faster
189
+ * but in not calling it. An `add` in an already-initialized project asks for
190
+ * exactly the dependencies `init` put there.
191
+ *
192
+ * The filter is deliberately conservative: when in doubt the package stays in
193
+ * the batch and the manager decides. Comparing only the major is enough because
194
+ * the versions the CLI asks for are always of the form `^N`.
195
+ */
196
+ export async function filterInstalledPackages(packages, cwd) {
197
+ const declared = await readDeclaredDependencies(cwd);
198
+ if (!declared)
199
+ return packages;
200
+ return packages.filter(spec => {
201
+ const { name, range } = parseSpec(spec);
202
+ const declaredRange = declared[name];
203
+ if (!declaredRange)
204
+ return true;
205
+ if (!isResolvable(name, cwd))
206
+ return true;
207
+ if (range && majorOf(range) !== majorOf(declaredRange))
208
+ return true;
209
+ return false;
210
+ });
211
+ }
212
+ function parseSpec(spec) {
213
+ // The `@` in `@ng-icons/core` opens the scope, not the version — hence the last one.
214
+ const separator = spec.lastIndexOf('@');
215
+ if (separator <= 0)
216
+ return { name: spec, range: null };
217
+ return { name: spec.slice(0, separator), range: spec.slice(separator + 1) };
218
+ }
219
+ function majorOf(range) {
220
+ return /(\d+)/.exec(range)?.[1] ?? null;
221
+ }
222
+ async function readDeclaredDependencies(cwd) {
223
+ try {
224
+ const manifest = JSON.parse(await readFile(path.join(cwd, 'package.json'), 'utf8'));
225
+ return { ...manifest.dependencies, ...manifest.devDependencies };
226
+ }
227
+ catch {
228
+ return null;
229
+ }
230
+ }
231
+ /** node_modules can sit above the project — workspaces hoist everything to the root. */
232
+ function isResolvable(name, cwd) {
233
+ let dir = path.resolve(cwd);
234
+ for (;;) {
235
+ if (existsSync(path.join(dir, 'node_modules', name)))
236
+ return true;
237
+ const parent = path.dirname(dir);
238
+ if (parent === dir)
239
+ return false;
240
+ dir = parent;
241
+ }
46
242
  }
47
243
  //# sourceMappingURL=package-manager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"package-manager.js","sourceRoot":"","sources":["../../src/utils/package-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE,CAAC;IAE1D,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAC9C,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAC9C,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAE5C,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;IAEnD,IAAI,KAAK,KAAK,YAAY;QAAE,OAAO,MAAM,CAAC;IAC1C,IAAI,KAAK,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5D,OAAO,KAAwC,CAAC;IAClD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACjE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;IACpC,OAAO,MAAM,EAAE,cAAc,IAAI,KAAK,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,cAAsB,EAAE,KAAK,GAAG,KAAK;IAC3E,QAAQ,cAAc,EAAE,CAAC;QACvB,KAAK,MAAM;YACT,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACzC,KAAK,MAAM;YACT,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACzC,KAAK,KAAK;YACR,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACzC,KAAK,KAAK,CAAC;QACX;YACE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,QAAkB,EAAE,GAAW,EAAE,cAA+C,EAAE,KAAK,GAAG,KAAK,EAAE,cAAc,GAAG,KAAK;IAC3J,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IAElE,MAAM,IAAI,GAAG,CAAC,GAAG,UAAU,EAAE,GAAG,QAAQ,CAAC,CAAC;IAE1C,IAAI,cAAc,IAAI,cAAc,KAAK,KAAK,EAAE,CAAC;QAC/C,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAClC,CAAC;IAED,MAAM,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AAC/D,CAAC"}
1
+ {"version":3,"file":"package-manager.js","sourceRoot":"","sources":["../../src/utils/package-manager.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,23 @@
1
+ import { type IconFamily } from '../core/icons/index.js';
1
2
  import type { Config } from '../utils/config.js';
2
3
  export declare const DEFAULT_REGISTRY_URL: string;
4
+ /**
5
+ * The icons a component draws, as the registry publishes them.
6
+ *
7
+ * `family` is the family the files are written in — anyone installing with a
8
+ * different family in `components.json` learns from this field that they need
9
+ * rewriting. Absent from items published before this property existed.
10
+ */
11
+ export interface RegistryIcons {
12
+ family: string;
13
+ symbols: string[];
14
+ tokens: string[];
15
+ /** The icons that only appear in the demos. Absent from the index, which does not carry them. */
16
+ demos?: {
17
+ symbols: string[];
18
+ tokens: string[];
19
+ };
20
+ }
3
21
  export interface RegistryItem {
4
22
  name: string;
5
23
  type: 'registry:component';
@@ -11,9 +29,12 @@ export interface RegistryItem {
11
29
  dependencies?: string[];
12
30
  devDependencies?: string[];
13
31
  registryDependencies?: string[];
32
+ icons?: RegistryIcons;
14
33
  }
15
34
  export interface RegistryIndex {
16
35
  $schema: string;
36
+ /** The file's shape. Absent from registries older than the field. */
37
+ schemaVersion?: number;
17
38
  name: string;
18
39
  homepage: string;
19
40
  version: string;
@@ -24,13 +45,34 @@ export interface RegistryIndex {
24
45
  dependencies?: string[];
25
46
  devDependencies?: string[];
26
47
  registryDependencies?: string[];
48
+ icons?: RegistryIcons;
27
49
  files: string[];
28
50
  }>;
29
51
  }
52
+ /**
53
+ * The family the item's files are written in.
54
+ *
55
+ * An item with no `icons` — published before the property existed — is in
56
+ * lucide, which was the only possibility. So is an unknown value: better the
57
+ * right guess than refusing to install over an unfamiliar field.
58
+ */
59
+ export declare function sourceFamilyOf(item: Pick<RegistryItem, 'icons'>): IconFamily;
30
60
  export declare function getRegistryUrl(config?: Config): string;
61
+ export declare function validateRegistryUrl(url: string): void;
31
62
  export declare function fetchRegistryIndex(registryUrl?: string): Promise<RegistryIndex>;
63
+ export declare function invalidateRegistryCache(): void;
32
64
  export declare function fetchComponentFromRegistry(componentName: string, registryUrl?: string): Promise<RegistryItem>;
33
65
  export declare function getAvailableComponents(registryUrl?: string): Promise<string[]>;
34
- export declare function transformContent(content: string, config: Config): string;
35
- export declare function fetchComponent(componentName: string, config: Config, registryUrl?: string): Promise<RegistryItem>;
66
+ export interface TransformOptions {
67
+ /**
68
+ * The destination came from `--path`, outside the configured alias.
69
+ *
70
+ * In that case the batch's components become neighbours on disk, and the
71
+ * relative path is what resolves — the alias would point at the folder they are
72
+ * not in. `utils` and `core` stay on the alias, because `init` installed them.
73
+ */
74
+ readonly siblingComponents?: boolean;
75
+ }
76
+ export declare function transformContent(content: string, config: Config, options?: TransformOptions): string;
77
+ export declare function fetchComponent(componentName: string, config: Config, registryUrl?: string, options?: TransformOptions): Promise<RegistryItem>;
36
78
  //# sourceMappingURL=registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/utils/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAGnD,eAAO,MAAM,oBAAoB,QAE0D,CAAC;AAE5F,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,oBAAoB,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;QAC3B,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;QAChC,KAAK,EAAE,MAAM,EAAE,CAAC;KACjB,CAAC,CAAC;CACJ;AAED,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAEtD;AA4BD,wBAAsB,kBAAkB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAIrF;AAED,wBAAsB,0BAA0B,CAAC,aAAa,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAInH;AAED,wBAAsB,sBAAsB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAGpF;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CA+BxE;AAED,wBAAsB,cAAc,CAClC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,YAAY,CAAC,CAYvB"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/utils/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAmD,KAAK,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC5G,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAOnD,eAAO,MAAM,oBAAoB,QAE0D,CAAC;AAE5F;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,iGAAiG;IACjG,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CACjD;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,oBAAoB,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;QAC3B,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;QAChC,KAAK,CAAC,EAAE,aAAa,CAAC;QACtB,KAAK,EAAE,MAAM,EAAE,CAAC;KACjB,CAAC,CAAC;CACJ;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,GAAG,UAAU,CAG5E;AAED,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAarD;AAYD,wBAAsB,kBAAkB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAerF;AAED,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAED,wBAAsB,0BAA0B,CAAC,aAAa,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAInH;AAED,wBAAsB,sBAAsB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAGpF;AAOD,MAAM,WAAW,gBAAgB;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CACtC;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAyCxG;AAED,wBAAsB,cAAc,CAClC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,YAAY,CAAC,CAoCvB"}
package/utils/registry.js CHANGED
@@ -1,38 +1,63 @@
1
1
  import { DEFAULT_REGISTRY_URL as BUILD_REGISTRY_URL } from '../config/registry-config.js';
2
- import { execa } from 'execa';
2
+ import { isIconFamily, retargetIcons, SOURCE_ICON_FAMILY } from '../core/icons/index.js';
3
+ import { ConfigError } from '../utils/errors.js';
4
+ import { fetchJson } from '../utils/http-client.js';
5
+ import { iconCatalog } from '../utils/icon-catalog.js';
6
+ import { logger } from '../utils/logger.js';
7
+ import { assertSupportedSchema } from '../utils/schema-version.js';
3
8
  export const DEFAULT_REGISTRY_URL = process.env['ZARD_REGISTRY_URL'] ||
4
9
  (BUILD_REGISTRY_URL !== '__REGISTRY_URL__' ? BUILD_REGISTRY_URL : 'https://zardui.com/r');
10
+ /**
11
+ * The family the item's files are written in.
12
+ *
13
+ * An item with no `icons` — published before the property existed — is in
14
+ * lucide, which was the only possibility. So is an unknown value: better the
15
+ * right guess than refusing to install over an unfamiliar field.
16
+ */
17
+ export function sourceFamilyOf(item) {
18
+ const family = item.icons?.family;
19
+ return family !== undefined && isIconFamily(family, iconCatalog()) ? family : SOURCE_ICON_FAMILY;
20
+ }
5
21
  export function getRegistryUrl(config) {
6
22
  return config?.registryUrl || DEFAULT_REGISTRY_URL;
7
23
  }
8
- async function fetchJson(url) {
24
+ export function validateRegistryUrl(url) {
9
25
  try {
10
- const { stdout } = await execa('curl', [
11
- '-s',
12
- '-H',
13
- 'Accept: application/json',
14
- '-H',
15
- 'User-Agent: ngzard-cli',
16
- '--max-time',
17
- '30',
18
- url,
19
- ]);
20
- if (!stdout || stdout.includes('<!DOCTYPE') || stdout.includes('<html')) {
21
- throw new Error(`Invalid response from registry: ${url}`);
26
+ const parsed = new URL(url);
27
+ const isHttps = parsed.protocol === 'https:';
28
+ const isLocalhost = parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1';
29
+ if (!isHttps && !isLocalhost) {
30
+ throw new ConfigError('Registry URL must use HTTPS (or localhost for development)');
22
31
  }
23
- return JSON.parse(stdout);
24
32
  }
25
33
  catch (error) {
26
- if (error instanceof SyntaxError) {
27
- throw new Error(`Invalid JSON response from registry: ${url}`);
28
- }
29
- throw new Error(`Failed to fetch from registry: ${url} - ${error}`);
34
+ if (error instanceof ConfigError)
35
+ throw error;
36
+ throw new ConfigError(`Invalid registry URL: ${url}`);
30
37
  }
31
38
  }
39
+ const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
40
+ /**
41
+ * Keyed by registry URL, not global.
42
+ *
43
+ * `registryUrl` is a `components.json` field, so two registries can be read in one
44
+ * run — and a single cache entry handed the second call the first registry's index.
45
+ */
46
+ const registryIndexCache = new Map();
32
47
  export async function fetchRegistryIndex(registryUrl) {
33
48
  const baseUrl = registryUrl || DEFAULT_REGISTRY_URL;
49
+ const cached = registryIndexCache.get(baseUrl);
50
+ if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
51
+ return cached.data;
52
+ }
34
53
  const url = `${baseUrl}/registry.json`;
35
- return fetchJson(url);
54
+ const data = await fetchJson(url);
55
+ assertSupportedSchema(data.schemaVersion, 'registry.json');
56
+ registryIndexCache.set(baseUrl, { data, timestamp: Date.now() });
57
+ return data;
58
+ }
59
+ export function invalidateRegistryCache() {
60
+ registryIndexCache.clear();
36
61
  }
37
62
  export async function fetchComponentFromRegistry(componentName, registryUrl) {
38
63
  const baseUrl = registryUrl || DEFAULT_REGISTRY_URL;
@@ -43,26 +68,60 @@ export async function getAvailableComponents(registryUrl) {
43
68
  const index = await fetchRegistryIndex(registryUrl);
44
69
  return index.items.map(item => item.name);
45
70
  }
46
- export function transformContent(content, config) {
71
+ /** Sem isto, um alias digitado como `@/ui/components/` produz `@/ui/components//button`. */
72
+ function trimSlashes(alias) {
73
+ return alias.replace(/\/+$/, '');
74
+ }
75
+ export function transformContent(content, config, options = {}) {
47
76
  let transformed = content;
48
- const { aliases } = config;
49
- // Replace utils imports
50
- transformed = transformed.replace(/from ['"]\.\.\/\.\.\/shared\/utils\/utils['"]/g, `from '${aliases.utils}/merge-classes'`);
51
- transformed = transformed.replace(/from ['"]\.\.\/\.\.\/shared\/utils\/number['"]/g, `from '${aliases.utils}/number'`);
77
+ const aliases = {
78
+ components: options.siblingComponents ? '..' : trimSlashes(config.aliases.components),
79
+ utils: trimSlashes(config.aliases.utils),
80
+ core: trimSlashes(config.aliases.core),
81
+ services: trimSlashes(config.aliases.services),
82
+ };
52
83
  // Replace relative component imports with aliased imports
53
84
  const componentImportRegex = /from ['"]\.\.\/([\w-/.]+)['"]/g;
54
85
  transformed = transformed.replace(componentImportRegex, `from '${aliases.components}/$1'`);
55
86
  // Replace ClassValue imports
56
87
  transformed = transformed.replace(/import \{ ClassValue \} from ['"]class-variance-authority\/dist\/types['"]/g, `import { ClassValue } from 'clsx'`);
57
88
  transformed = transformed.replace(/import \{ ClassValue \} from ['"]class-variance-authority['"]/g, `import { ClassValue } from 'clsx'`);
89
+ // Transform default @/shared/* to match aliases
90
+ for (const [key, value] of Object.entries(aliases)) {
91
+ if (!value) {
92
+ continue;
93
+ }
94
+ // The subpath is optional: `card.component.ts` imports the barrel directly
95
+ // (`from '@/shared/core'`). Requiring `/something` after the key let that
96
+ // import escape the substitution, and the installed component kept pointing
97
+ // at `@/shared/core` — a folder that does not exist under a custom alias.
98
+ const regex = new RegExp(`(['"])@\\/shared\\/${key}(\\/[\\w\\-\\/.]+)?\\1`, 'g');
99
+ transformed = transformed.replace(regex, (_match, quote, subpath) => {
100
+ return `${quote}${value}${subpath ?? ''}${quote}`;
101
+ });
102
+ }
58
103
  return transformed;
59
104
  }
60
- export async function fetchComponent(componentName, config, registryUrl) {
105
+ export async function fetchComponent(componentName, config, registryUrl, options = {}) {
61
106
  const item = await fetchComponentFromRegistry(componentName, registryUrl);
62
- const transformedFiles = item.files.map(file => ({
63
- name: file.name,
64
- content: transformContent(file.content, config),
65
- }));
107
+ if (!item.files || !Array.isArray(item.files)) {
108
+ throw new ConfigError(`Component "${componentName}" has no files in the registry`);
109
+ }
110
+ const sourceFamily = sourceFamilyOf(item);
111
+ const missing = new Set();
112
+ const transformedFiles = item.files.map(file => {
113
+ const retargeted = retargetIcons(transformContent(file.content, config, options), sourceFamily, config.icons, iconCatalog());
114
+ for (const symbol of retargeted.missing)
115
+ missing.add(symbol);
116
+ return { name: file.name, content: retargeted.content };
117
+ });
118
+ // An icon with no equivalent in the chosen family keeps its original symbol,
119
+ // and its import no longer resolves. Failing the whole install over that would
120
+ // be worse: the rest of the component is correct and the fix is one line.
121
+ if (missing.size > 0) {
122
+ logger.warn(`"${componentName}" uses icons that ${config.icons} does not provide: ${[...missing].sort().join(', ')}. ` +
123
+ 'They were left untouched — replace them by hand.');
124
+ }
66
125
  return {
67
126
  ...item,
68
127
  files: transformedFiles,
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/utils/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/utils/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The registry FORMAT version this CLI understands.
3
+ *
4
+ * Not to be confused with the package version, which the index also publishes:
5
+ * that one says which release the content came from, this one says what shape it
6
+ * has. Without separating them there was no way for the registry to change shape
7
+ * without silently breaking whoever was already installed — the CLI would read
8
+ * `files` from an item with a different shape and get it wrong without a word.
9
+ *
10
+ * It goes up when the change breaks a reader: a field removed, a meaning
11
+ * altered, an item reorganized. A new optional field raises nothing.
12
+ */
13
+ export declare const SUPPORTED_SCHEMA_VERSION = 1;
14
+ /**
15
+ * Rejects a document newer than this CLI knows how to read.
16
+ *
17
+ * A missing field means a registry older than the field itself, which is version
18
+ * 1 by definition.
19
+ */
20
+ export declare function assertSupportedSchema(schemaVersion: number | undefined, source: string): void;
21
+ //# sourceMappingURL=schema-version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-version.d.ts","sourceRoot":"","sources":["../../src/utils/schema-version.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAS7F"}