@blotch/dolan 0.0.0-stage → 22.2.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 (273) hide show
  1. package/dist/commands/add.d.ts +22 -0
  2. package/dist/commands/add.js +132 -0
  3. package/dist/commands/add.js.map +1 -0
  4. package/dist/commands/add.test.d.ts +1 -0
  5. package/dist/commands/add.test.js +209 -0
  6. package/dist/commands/add.test.js.map +1 -0
  7. package/dist/commands/diff.d.ts +13 -0
  8. package/dist/commands/diff.js +155 -0
  9. package/dist/commands/diff.js.map +1 -0
  10. package/dist/commands/diff.test.d.ts +1 -0
  11. package/dist/commands/diff.test.js +327 -0
  12. package/dist/commands/diff.test.js.map +1 -0
  13. package/dist/commands/doctor.d.ts +15 -0
  14. package/dist/commands/doctor.js +248 -0
  15. package/dist/commands/doctor.js.map +1 -0
  16. package/dist/commands/doctor.test.d.ts +1 -0
  17. package/dist/commands/doctor.test.js +301 -0
  18. package/dist/commands/doctor.test.js.map +1 -0
  19. package/dist/commands/eject.d.ts +11 -0
  20. package/dist/commands/eject.js +55 -0
  21. package/dist/commands/eject.js.map +1 -0
  22. package/dist/commands/eject.test.d.ts +1 -0
  23. package/dist/commands/eject.test.js +151 -0
  24. package/dist/commands/eject.test.js.map +1 -0
  25. package/dist/commands/info.d.ts +1 -0
  26. package/dist/commands/info.js +73 -0
  27. package/dist/commands/info.js.map +1 -0
  28. package/dist/commands/info.test.d.ts +1 -0
  29. package/dist/commands/info.test.js +143 -0
  30. package/dist/commands/info.test.js.map +1 -0
  31. package/dist/commands/init.d.ts +1 -0
  32. package/dist/commands/init.js +98 -0
  33. package/dist/commands/init.js.map +1 -0
  34. package/dist/commands/init.test.d.ts +1 -0
  35. package/dist/commands/init.test.js +154 -0
  36. package/dist/commands/init.test.js.map +1 -0
  37. package/dist/commands/list.d.ts +16 -0
  38. package/dist/commands/list.js +124 -0
  39. package/dist/commands/list.js.map +1 -0
  40. package/dist/commands/list.test.d.ts +1 -0
  41. package/dist/commands/list.test.js +285 -0
  42. package/dist/commands/list.test.js.map +1 -0
  43. package/dist/commands/outdated.d.ts +13 -0
  44. package/dist/commands/outdated.js +116 -0
  45. package/dist/commands/outdated.js.map +1 -0
  46. package/dist/commands/outdated.test.d.ts +1 -0
  47. package/dist/commands/outdated.test.js +208 -0
  48. package/dist/commands/outdated.test.js.map +1 -0
  49. package/dist/commands/remove.d.ts +18 -0
  50. package/dist/commands/remove.js +161 -0
  51. package/dist/commands/remove.js.map +1 -0
  52. package/dist/commands/remove.test.d.ts +1 -0
  53. package/dist/commands/remove.test.js +361 -0
  54. package/dist/commands/remove.test.js.map +1 -0
  55. package/dist/commands/theme.d.ts +1 -0
  56. package/dist/commands/theme.js +66 -0
  57. package/dist/commands/theme.js.map +1 -0
  58. package/dist/commands/theme.test.d.ts +1 -0
  59. package/dist/commands/theme.test.js +133 -0
  60. package/dist/commands/theme.test.js.map +1 -0
  61. package/dist/commands/update.d.ts +31 -0
  62. package/dist/commands/update.js +601 -0
  63. package/dist/commands/update.js.map +1 -0
  64. package/dist/commands/update.test.d.ts +1 -0
  65. package/dist/commands/update.test.js +1233 -0
  66. package/dist/commands/update.test.js.map +1 -0
  67. package/dist/config.d.ts +11 -0
  68. package/dist/config.js +19 -0
  69. package/dist/config.js.map +1 -0
  70. package/dist/config.test.d.ts +1 -0
  71. package/dist/config.test.js +48 -0
  72. package/dist/config.test.js.map +1 -0
  73. package/dist/index.d.ts +2 -0
  74. package/dist/index.js +89 -0
  75. package/dist/index.js.map +1 -0
  76. package/dist/lockfile.d.ts +21 -0
  77. package/dist/lockfile.js +39 -0
  78. package/dist/lockfile.js.map +1 -0
  79. package/dist/registry.d.ts +14 -0
  80. package/dist/registry.js +85 -0
  81. package/dist/registry.js.map +1 -0
  82. package/dist/registry.test.d.ts +1 -0
  83. package/dist/registry.test.js +95 -0
  84. package/dist/registry.test.js.map +1 -0
  85. package/dist/test-utils.d.ts +16 -0
  86. package/dist/test-utils.js +65 -0
  87. package/dist/test-utils.js.map +1 -0
  88. package/dist/ui/components/accordion/accordion.test.ts +194 -0
  89. package/dist/ui/components/accordion/accordion.ts +173 -0
  90. package/dist/ui/components/accordion/index.ts +6 -0
  91. package/dist/ui/components/action-sheet/action-sheet.test.ts +211 -0
  92. package/dist/ui/components/action-sheet/action-sheet.ts +353 -0
  93. package/dist/ui/components/action-sheet/index.ts +6 -0
  94. package/dist/ui/components/alert/alert.test.ts +48 -0
  95. package/dist/ui/components/alert/alert.ts +104 -0
  96. package/dist/ui/components/alert/index.ts +1 -0
  97. package/dist/ui/components/alert-dialog/alert-dialog.test.ts +141 -0
  98. package/dist/ui/components/alert-dialog/alert-dialog.ts +243 -0
  99. package/dist/ui/components/alert-dialog/index.ts +7 -0
  100. package/dist/ui/components/area-chart/area-chart-render.test.ts +121 -0
  101. package/dist/ui/components/area-chart/area-chart.test.ts +158 -0
  102. package/dist/ui/components/area-chart/area-chart.ts +349 -0
  103. package/dist/ui/components/area-chart/index.ts +6 -0
  104. package/dist/ui/components/aspect-ratio/aspect-ratio.test.ts +10 -0
  105. package/dist/ui/components/aspect-ratio/aspect-ratio.ts +28 -0
  106. package/dist/ui/components/aspect-ratio/index.ts +1 -0
  107. package/dist/ui/components/avatar/avatar.test.ts +69 -0
  108. package/dist/ui/components/avatar/avatar.ts +131 -0
  109. package/dist/ui/components/avatar/index.ts +1 -0
  110. package/dist/ui/components/badge/badge.test.ts +49 -0
  111. package/dist/ui/components/badge/badge.ts +97 -0
  112. package/dist/ui/components/badge/index.ts +1 -0
  113. package/dist/ui/components/bar-chart/bar-chart-render.test.ts +174 -0
  114. package/dist/ui/components/bar-chart/bar-chart.test.ts +73 -0
  115. package/dist/ui/components/bar-chart/bar-chart.ts +327 -0
  116. package/dist/ui/components/bar-chart/index.ts +6 -0
  117. package/dist/ui/components/bottom-sheet/bottom-sheet.test.ts +163 -0
  118. package/dist/ui/components/bottom-sheet/bottom-sheet.ts +339 -0
  119. package/dist/ui/components/bottom-sheet/index.ts +1 -0
  120. package/dist/ui/components/button/button-render.test.ts +113 -0
  121. package/dist/ui/components/button/button.test.ts +70 -0
  122. package/dist/ui/components/button/button.ts +170 -0
  123. package/dist/ui/components/button/index.ts +6 -0
  124. package/dist/ui/components/button-group/button-group-render.test.ts +146 -0
  125. package/dist/ui/components/button-group/button-group.test.ts +54 -0
  126. package/dist/ui/components/button-group/button-group.ts +209 -0
  127. package/dist/ui/components/button-group/index.ts +8 -0
  128. package/dist/ui/components/candlestick-chart/candlestick-chart-render.test.ts +174 -0
  129. package/dist/ui/components/candlestick-chart/candlestick-chart.test.ts +96 -0
  130. package/dist/ui/components/candlestick-chart/candlestick-chart.ts +355 -0
  131. package/dist/ui/components/candlestick-chart/index.ts +7 -0
  132. package/dist/ui/components/card/card.test.ts +110 -0
  133. package/dist/ui/components/card/card.ts +162 -0
  134. package/dist/ui/components/card/index.ts +8 -0
  135. package/dist/ui/components/cartesian-chart/cartesian-chart-render.test.ts +188 -0
  136. package/dist/ui/components/cartesian-chart/cartesian-chart.test.ts +549 -0
  137. package/dist/ui/components/cartesian-chart/cartesian-chart.ts +1140 -0
  138. package/dist/ui/components/cartesian-chart/index.ts +18 -0
  139. package/dist/ui/components/checkbox/checkbox.test.ts +59 -0
  140. package/dist/ui/components/checkbox/checkbox.ts +96 -0
  141. package/dist/ui/components/checkbox/index.ts +1 -0
  142. package/dist/ui/components/collapsible/collapsible.test.ts +112 -0
  143. package/dist/ui/components/collapsible/collapsible.ts +122 -0
  144. package/dist/ui/components/collapsible/index.ts +5 -0
  145. package/dist/ui/components/dialog/dialog.test.ts +157 -0
  146. package/dist/ui/components/dialog/dialog.ts +248 -0
  147. package/dist/ui/components/dialog/index.ts +7 -0
  148. package/dist/ui/components/empty-state/empty-state.test.ts +60 -0
  149. package/dist/ui/components/empty-state/empty-state.ts +46 -0
  150. package/dist/ui/components/empty-state/index.ts +1 -0
  151. package/dist/ui/components/icon/icon.test.ts +52 -0
  152. package/dist/ui/components/icon/icon.ts +54 -0
  153. package/dist/ui/components/icon/icons.ts +569 -0
  154. package/dist/ui/components/icon/index.ts +2 -0
  155. package/dist/ui/components/input/index.ts +1 -0
  156. package/dist/ui/components/input/input.test.ts +134 -0
  157. package/dist/ui/components/input/input.ts +189 -0
  158. package/dist/ui/components/label/index.ts +1 -0
  159. package/dist/ui/components/label/label.test.ts +38 -0
  160. package/dist/ui/components/label/label.ts +24 -0
  161. package/dist/ui/components/line-chart/index.ts +6 -0
  162. package/dist/ui/components/line-chart/line-chart-render.test.ts +121 -0
  163. package/dist/ui/components/line-chart/line-chart.test.ts +81 -0
  164. package/dist/ui/components/line-chart/line-chart.ts +273 -0
  165. package/dist/ui/components/list/index.ts +1 -0
  166. package/dist/ui/components/list/list.test.ts +35 -0
  167. package/dist/ui/components/list/list.ts +71 -0
  168. package/dist/ui/components/nav-drawer/index.ts +8 -0
  169. package/dist/ui/components/nav-drawer/nav-drawer.test.ts +267 -0
  170. package/dist/ui/components/nav-drawer/nav-drawer.ts +504 -0
  171. package/dist/ui/components/pagination/index.ts +1 -0
  172. package/dist/ui/components/pagination/pagination.test.ts +96 -0
  173. package/dist/ui/components/pagination/pagination.ts +147 -0
  174. package/dist/ui/components/progress/index.ts +1 -0
  175. package/dist/ui/components/progress/progress.test.ts +71 -0
  176. package/dist/ui/components/progress/progress.ts +118 -0
  177. package/dist/ui/components/radio-group/index.ts +1 -0
  178. package/dist/ui/components/radio-group/radio-group.test.ts +115 -0
  179. package/dist/ui/components/radio-group/radio-group.ts +129 -0
  180. package/dist/ui/components/scatter-chart/index.ts +6 -0
  181. package/dist/ui/components/scatter-chart/scatter-chart-render.test.ts +157 -0
  182. package/dist/ui/components/scatter-chart/scatter-chart.test.ts +57 -0
  183. package/dist/ui/components/scatter-chart/scatter-chart.ts +277 -0
  184. package/dist/ui/components/scroll-area/index.ts +1 -0
  185. package/dist/ui/components/scroll-area/scroll-area.test.ts +40 -0
  186. package/dist/ui/components/scroll-area/scroll-area.ts +73 -0
  187. package/dist/ui/components/select/index.ts +1 -0
  188. package/dist/ui/components/select/select.test.ts +107 -0
  189. package/dist/ui/components/select/select.ts +146 -0
  190. package/dist/ui/components/separator/index.ts +1 -0
  191. package/dist/ui/components/separator/separator.test.ts +26 -0
  192. package/dist/ui/components/separator/separator.ts +45 -0
  193. package/dist/ui/components/sheet/index.ts +7 -0
  194. package/dist/ui/components/sheet/sheet.test.ts +44 -0
  195. package/dist/ui/components/sheet/sheet.ts +114 -0
  196. package/dist/ui/components/skeleton/index.ts +1 -0
  197. package/dist/ui/components/skeleton/skeleton.test.ts +13 -0
  198. package/dist/ui/components/skeleton/skeleton.ts +45 -0
  199. package/dist/ui/components/spinner/index.ts +1 -0
  200. package/dist/ui/components/spinner/spinner.test.ts +39 -0
  201. package/dist/ui/components/spinner/spinner.ts +83 -0
  202. package/dist/ui/components/switch/index.ts +1 -0
  203. package/dist/ui/components/switch/switch.test.ts +63 -0
  204. package/dist/ui/components/switch/switch.ts +98 -0
  205. package/dist/ui/components/tabs/index.ts +1 -0
  206. package/dist/ui/components/tabs/tabs.test.ts +199 -0
  207. package/dist/ui/components/tabs/tabs.ts +317 -0
  208. package/dist/ui/components/textarea/index.ts +1 -0
  209. package/dist/ui/components/textarea/textarea.test.ts +138 -0
  210. package/dist/ui/components/textarea/textarea.ts +221 -0
  211. package/dist/ui/components/toast/index.ts +9 -0
  212. package/dist/ui/components/toast/toast-state.test.ts +54 -0
  213. package/dist/ui/components/toast/toast-state.ts +46 -0
  214. package/dist/ui/components/toast/toast.test.ts +342 -0
  215. package/dist/ui/components/toast/toast.ts +527 -0
  216. package/dist/ui/components/toggle/index.ts +7 -0
  217. package/dist/ui/components/toggle/toggle.test.ts +186 -0
  218. package/dist/ui/components/toggle/toggle.ts +218 -0
  219. package/dist/ui/components/typography/index.ts +5 -0
  220. package/dist/ui/components/typography/typography.test.ts +55 -0
  221. package/dist/ui/components/typography/typography.ts +44 -0
  222. package/dist/ui/theme/dark.css +41 -0
  223. package/dist/ui/theme/default.css +56 -0
  224. package/dist/ui/theme/tailwind-plugin.test.ts +124 -0
  225. package/dist/ui/theme/tailwind-plugin.ts +151 -0
  226. package/dist/ui/utils/animate.test.ts +324 -0
  227. package/dist/ui/utils/animate.ts +544 -0
  228. package/dist/ui/utils/cn.test.ts +27 -0
  229. package/dist/ui/utils/cn.ts +6 -0
  230. package/dist/utils/analyze.d.ts +32 -0
  231. package/dist/utils/analyze.js +109 -0
  232. package/dist/utils/analyze.js.map +1 -0
  233. package/dist/utils/analyze.test.d.ts +1 -0
  234. package/dist/utils/analyze.test.js +146 -0
  235. package/dist/utils/analyze.test.js.map +1 -0
  236. package/dist/utils/animate.d.ts +210 -0
  237. package/dist/utils/animate.js +423 -0
  238. package/dist/utils/animate.js.map +1 -0
  239. package/dist/utils/animate.test.d.ts +1 -0
  240. package/dist/utils/animate.test.js +365 -0
  241. package/dist/utils/animate.test.js.map +1 -0
  242. package/dist/utils/banner.d.ts +1 -0
  243. package/dist/utils/banner.js +15 -0
  244. package/dist/utils/banner.js.map +1 -0
  245. package/dist/utils/banner.test.d.ts +1 -0
  246. package/dist/utils/banner.test.js +29 -0
  247. package/dist/utils/banner.test.js.map +1 -0
  248. package/dist/utils/cn.d.ts +2 -0
  249. package/dist/utils/cn.js +6 -0
  250. package/dist/utils/cn.js.map +1 -0
  251. package/dist/utils/cn.test.d.ts +1 -0
  252. package/dist/utils/cn.test.js +21 -0
  253. package/dist/utils/cn.test.js.map +1 -0
  254. package/dist/utils/format.d.ts +31 -0
  255. package/dist/utils/format.js +95 -0
  256. package/dist/utils/format.js.map +1 -0
  257. package/dist/utils/format.test.d.ts +1 -0
  258. package/dist/utils/format.test.js +71 -0
  259. package/dist/utils/format.test.js.map +1 -0
  260. package/dist/utils/logger.d.ts +6 -0
  261. package/dist/utils/logger.js +16 -0
  262. package/dist/utils/logger.js.map +1 -0
  263. package/dist/utils/logger.test.d.ts +1 -0
  264. package/dist/utils/logger.test.js +36 -0
  265. package/dist/utils/logger.test.js.map +1 -0
  266. package/dist/utils/resolve-paths.d.ts +12 -0
  267. package/dist/utils/resolve-paths.js +29 -0
  268. package/dist/utils/resolve-paths.js.map +1 -0
  269. package/dist/utils/resolve-paths.test.d.ts +1 -0
  270. package/dist/utils/resolve-paths.test.js +52 -0
  271. package/dist/utils/resolve-paths.test.js.map +1 -0
  272. package/package.json +56 -4
  273. package/README.md +0 -3
@@ -0,0 +1,327 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { join } from 'node:path';
3
+ import { readdirSync } from 'node:fs';
4
+ import { createFixture, DEFAULT_CONFIG } from '../test-utils';
5
+ import { hashContent } from '../lockfile';
6
+ vi.mock('@clack/prompts', () => ({
7
+ intro: vi.fn(),
8
+ outro: vi.fn(),
9
+ log: {
10
+ message: vi.fn(),
11
+ error: vi.fn(),
12
+ warn: vi.fn(),
13
+ success: vi.fn(),
14
+ info: vi.fn(),
15
+ },
16
+ select: vi.fn().mockResolvedValue('__none__'),
17
+ isCancel: vi.fn().mockReturnValue(false),
18
+ }));
19
+ let fixture;
20
+ vi.mock('../utils/resolve-paths.js', () => ({
21
+ getUiSourceDir: () => fixture.uiDir,
22
+ getComponentSourceDir: (name) => join(fixture.uiDir, 'components', name),
23
+ getComponentFiles: (name) => readdirSync(join(fixture.uiDir, 'components', name)).filter((f) => f.endsWith('.ts')),
24
+ rewriteImports: (content) => content,
25
+ }));
26
+ beforeEach(() => {
27
+ vi.spyOn(process, 'exit').mockImplementation((code) => {
28
+ throw new Error(`process.exit(${code})`);
29
+ });
30
+ });
31
+ afterEach(() => {
32
+ fixture?.cleanup();
33
+ vi.restoreAllMocks();
34
+ });
35
+ describe('diffCommand', () => {
36
+ it('reports all up to date when content matches upstream', async () => {
37
+ const content = 'export const Card = {};';
38
+ fixture = createFixture({
39
+ config: DEFAULT_CONFIG,
40
+ lockfile: {
41
+ version: 1,
42
+ components: { card: { 'card.ts': { hash: hashContent(content) } } },
43
+ utils: {},
44
+ theme: {},
45
+ },
46
+ components: { card: { 'card.ts': content } },
47
+ uiSource: { card: { 'card.ts': content } },
48
+ });
49
+ vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
50
+ const p = await import('@clack/prompts');
51
+ const { diffCommand } = await import('./diff');
52
+ await diffCommand();
53
+ expect(p.log.success).toHaveBeenCalledWith(expect.stringContaining('up to date'));
54
+ });
55
+ it('shows diff output for a specific changed component', async () => {
56
+ const installed = 'export const Card = { old: true };';
57
+ const upstream = 'export const Card = { new: true };';
58
+ fixture = createFixture({
59
+ config: DEFAULT_CONFIG,
60
+ lockfile: {
61
+ version: 1,
62
+ components: { card: { 'card.ts': { hash: hashContent(installed) } } },
63
+ utils: {},
64
+ theme: {},
65
+ },
66
+ components: { card: { 'card.ts': installed } },
67
+ uiSource: { card: { 'card.ts': upstream } },
68
+ });
69
+ vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
70
+ const p = await import('@clack/prompts');
71
+ const { diffCommand } = await import('./diff');
72
+ await diffCommand('card');
73
+ const messages = p.log.message.mock.calls
74
+ .map((c) => c[0])
75
+ .join('\n');
76
+ expect(messages).toContain('card');
77
+ // Should contain diff markers (colored, but the text is there)
78
+ expect(messages).toContain('old');
79
+ expect(messages).toContain('new');
80
+ });
81
+ it('exits with error for non-installed component', async () => {
82
+ const content = 'export const Card = {};';
83
+ // Need at least one installed component to pass the early-exit check
84
+ fixture = createFixture({
85
+ config: DEFAULT_CONFIG,
86
+ lockfile: {
87
+ version: 1,
88
+ components: {
89
+ spinner: { 'spinner.ts': { hash: hashContent(content) } },
90
+ },
91
+ utils: {},
92
+ theme: {},
93
+ },
94
+ components: { spinner: { 'spinner.ts': content } },
95
+ uiSource: {
96
+ card: { 'card.ts': content },
97
+ spinner: { 'spinner.ts': content },
98
+ },
99
+ });
100
+ vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
101
+ const { diffCommand } = await import('./diff');
102
+ await expect(diffCommand('card')).rejects.toThrow('process.exit(1)');
103
+ });
104
+ it('exits with error for unknown component', async () => {
105
+ const content = 'export const Spinner = {};';
106
+ fixture = createFixture({
107
+ config: DEFAULT_CONFIG,
108
+ components: { spinner: { 'spinner.ts': content } },
109
+ uiSource: { spinner: { 'spinner.ts': content } },
110
+ });
111
+ vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
112
+ const { diffCommand } = await import('./diff');
113
+ await expect(diffCommand('nonexistent')).rejects.toThrow('process.exit(1)');
114
+ });
115
+ it('exits with error when no config exists', async () => {
116
+ fixture = createFixture({});
117
+ vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
118
+ const { diffCommand } = await import('./diff');
119
+ await expect(diffCommand()).rejects.toThrow('process.exit(1)');
120
+ const p = await import('@clack/prompts');
121
+ expect(p.log.error).toHaveBeenCalledWith(expect.stringContaining('dolan.config.json'));
122
+ });
123
+ it('warns when the components directory does not exist', async () => {
124
+ const content = 'export const Card = {};';
125
+ fixture = createFixture({
126
+ config: DEFAULT_CONFIG,
127
+ uiSource: { card: { 'card.ts': content } },
128
+ });
129
+ // createFixture always creates the configured components dir up front —
130
+ // remove it to exercise the "nothing installed yet" branch.
131
+ const { rmSync } = await import('node:fs');
132
+ rmSync(join(fixture.dir, DEFAULT_CONFIG.aliases.components), {
133
+ recursive: true,
134
+ force: true,
135
+ });
136
+ vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
137
+ const p = await import('@clack/prompts');
138
+ const { diffCommand } = await import('./diff');
139
+ await diffCommand();
140
+ expect(p.log.warn).toHaveBeenCalledWith(expect.stringContaining('No components installed'));
141
+ });
142
+ it('warns when the components directory has nothing recognized', async () => {
143
+ const content = 'export const Card = {};';
144
+ fixture = createFixture({
145
+ config: DEFAULT_CONFIG,
146
+ // components dir exists (via createFixture) but is empty — nothing
147
+ // known to the registry is installed.
148
+ uiSource: { card: { 'card.ts': content } },
149
+ });
150
+ vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
151
+ const p = await import('@clack/prompts');
152
+ const { diffCommand } = await import('./diff');
153
+ await diffCommand();
154
+ expect(p.log.warn).toHaveBeenCalledWith(expect.stringContaining('No components installed'));
155
+ });
156
+ it('shows a new-upstream file as full green content', async () => {
157
+ // The file exists upstream but was never installed on disk — analyzeFile
158
+ // reports "new-upstream" and showComponentDiff should render the whole
159
+ // file instead of a diff (there's nothing to diff against).
160
+ const cardContent = 'export const Card = {};';
161
+ const helperContent = 'export const helper = () => 1;';
162
+ fixture = createFixture({
163
+ config: DEFAULT_CONFIG,
164
+ lockfile: {
165
+ version: 1,
166
+ components: { card: { 'card.ts': { hash: hashContent(cardContent) } } },
167
+ utils: {},
168
+ theme: {},
169
+ },
170
+ components: { card: { 'card.ts': cardContent } },
171
+ uiSource: {
172
+ card: { 'card.ts': cardContent, 'helper.ts': helperContent },
173
+ },
174
+ });
175
+ vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
176
+ const p = await import('@clack/prompts');
177
+ const { diffCommand } = await import('./diff');
178
+ await diffCommand('card');
179
+ const messages = p.log.message.mock.calls
180
+ .map((c) => c[0])
181
+ .join('\n');
182
+ expect(messages).toContain('helper.ts');
183
+ expect(messages).toContain(helperContent);
184
+ });
185
+ it('reports all files up to date when diffing a specific up-to-date component', async () => {
186
+ const content = 'export const Card = {};';
187
+ fixture = createFixture({
188
+ config: DEFAULT_CONFIG,
189
+ lockfile: {
190
+ version: 1,
191
+ components: { card: { 'card.ts': { hash: hashContent(content) } } },
192
+ utils: {},
193
+ theme: {},
194
+ },
195
+ components: { card: { 'card.ts': content } },
196
+ uiSource: { card: { 'card.ts': content } },
197
+ });
198
+ vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
199
+ const p = await import('@clack/prompts');
200
+ const { diffCommand } = await import('./diff');
201
+ await diffCommand('card');
202
+ const messages = p.log.message.mock.calls
203
+ .map((c) => c[0])
204
+ .join('\n');
205
+ expect(messages).toContain('All files up to date.');
206
+ });
207
+ it('summary mode: lists changed components and shows the chosen one', async () => {
208
+ const cardInstalled = 'export const Card = { old: true };';
209
+ const cardUpstream = 'export const Card = { new: true };';
210
+ const spinnerContent = 'export const Spinner = {};';
211
+ fixture = createFixture({
212
+ config: DEFAULT_CONFIG,
213
+ lockfile: {
214
+ version: 1,
215
+ components: {
216
+ card: { 'card.ts': { hash: hashContent(cardInstalled) } },
217
+ spinner: { 'spinner.ts': { hash: hashContent(spinnerContent) } },
218
+ },
219
+ utils: {},
220
+ theme: {},
221
+ },
222
+ components: {
223
+ card: { 'card.ts': cardInstalled },
224
+ spinner: { 'spinner.ts': spinnerContent },
225
+ },
226
+ uiSource: {
227
+ card: { 'card.ts': cardUpstream },
228
+ spinner: { 'spinner.ts': spinnerContent },
229
+ },
230
+ });
231
+ vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
232
+ const p = await import('@clack/prompts');
233
+ p.select.mockResolvedValueOnce('card');
234
+ const { diffCommand } = await import('./diff');
235
+ await diffCommand();
236
+ const messages = p.log.message.mock.calls
237
+ .map((c) => c[0])
238
+ .join('\n');
239
+ expect(messages).toContain('1 component(s) with changes');
240
+ expect(messages).toContain('old');
241
+ expect(messages).toContain('new');
242
+ // Spinner never diverged, so its diff should not have been printed.
243
+ expect(p.select).toHaveBeenCalled();
244
+ });
245
+ it('summary mode: "All changed components" shows every diff', async () => {
246
+ const cardInstalled = 'export const Card = { old: true };';
247
+ const cardUpstream = 'export const Card = { new: true };';
248
+ const spinnerInstalled = 'export const Spinner = { old: true };';
249
+ const spinnerUpstream = 'export const Spinner = { new: true };';
250
+ fixture = createFixture({
251
+ config: DEFAULT_CONFIG,
252
+ lockfile: {
253
+ version: 1,
254
+ components: {
255
+ card: { 'card.ts': { hash: hashContent(cardInstalled) } },
256
+ spinner: { 'spinner.ts': { hash: hashContent(spinnerInstalled) } },
257
+ },
258
+ utils: {},
259
+ theme: {},
260
+ },
261
+ components: {
262
+ card: { 'card.ts': cardInstalled },
263
+ spinner: { 'spinner.ts': spinnerInstalled },
264
+ },
265
+ uiSource: {
266
+ card: { 'card.ts': cardUpstream },
267
+ spinner: { 'spinner.ts': spinnerUpstream },
268
+ },
269
+ });
270
+ vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
271
+ const p = await import('@clack/prompts');
272
+ p.select.mockResolvedValueOnce('__all__');
273
+ const { diffCommand } = await import('./diff');
274
+ await diffCommand();
275
+ const messages = p.log.message.mock.calls
276
+ .map((c) => c[0])
277
+ .join('\n');
278
+ expect(messages).toContain('2 component(s) with changes');
279
+ expect(messages).toContain('card');
280
+ expect(messages).toContain('spinner');
281
+ });
282
+ it('handles a component with no lockfile entry at all', async () => {
283
+ // Installed and matches upstream, but was never recorded in the lockfile
284
+ // (e.g. lockfile predates this component) — lockfile.components[name] is
285
+ // undefined and must fall back to {} rather than throwing.
286
+ const content = 'export const Card = {};';
287
+ fixture = createFixture({
288
+ config: DEFAULT_CONFIG,
289
+ lockfile: { version: 1, components: {}, utils: {}, theme: {} },
290
+ components: { card: { 'card.ts': content } },
291
+ uiSource: { card: { 'card.ts': content } },
292
+ });
293
+ vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
294
+ const { diffCommand } = await import('./diff');
295
+ await diffCommand('card');
296
+ const p = await import('@clack/prompts');
297
+ const messages = p.log.message.mock.calls
298
+ .map((c) => c[0])
299
+ .join('\n');
300
+ expect(messages).toContain('All files up to date.');
301
+ });
302
+ it('summary mode: exits cleanly when the user cancels the selection', async () => {
303
+ const cardInstalled = 'export const Card = { old: true };';
304
+ const cardUpstream = 'export const Card = { new: true };';
305
+ fixture = createFixture({
306
+ config: DEFAULT_CONFIG,
307
+ lockfile: {
308
+ version: 1,
309
+ components: {
310
+ card: { 'card.ts': { hash: hashContent(cardInstalled) } },
311
+ },
312
+ utils: {},
313
+ theme: {},
314
+ },
315
+ components: { card: { 'card.ts': cardInstalled } },
316
+ uiSource: { card: { 'card.ts': cardUpstream } },
317
+ });
318
+ vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
319
+ const p = await import('@clack/prompts');
320
+ p.select.mockResolvedValueOnce('cancel-token');
321
+ p.isCancel.mockReturnValueOnce(true);
322
+ const { diffCommand } = await import('./diff');
323
+ await diffCommand();
324
+ expect(p.outro).toHaveBeenCalled();
325
+ });
326
+ });
327
+ //# sourceMappingURL=diff.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.test.js","sourceRoot":"","sources":["../../src/commands/diff.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Runs a battery of project health checks similar to `npm doctor` or
3
+ * `shadcn doctor`. Each check uses a pass/warn/fail tracker so the command
4
+ * exits with the appropriate status code:
5
+ *
6
+ * - **pass** (counted) — green, informational
7
+ * - **warn** (counted) — yellow, fixable issue that doesn't block builds
8
+ * - **fail** (counted) — red, breaks something; exit code 1
9
+ *
10
+ * The check order is intentional: config first (everything depends on it,
11
+ * abort if invalid), then directories (the alias paths must resolve), then
12
+ * progressively more specific integrations (theme files, Tailwind, deps,
13
+ * component consistency).
14
+ */
15
+ export declare const doctorCommand: () => Promise<never>;
@@ -0,0 +1,248 @@
1
+ import * as p from '@clack/prompts';
2
+ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
3
+ import { resolve, join } from 'node:path';
4
+ import pc from 'picocolors';
5
+ import { configExists, readConfig } from '../config.js';
6
+ import { getEntry } from '../registry.js';
7
+ import { getComponentFiles } from '../utils/resolve-paths.js';
8
+ /**
9
+ * Runs a battery of project health checks similar to `npm doctor` or
10
+ * `shadcn doctor`. Each check uses a pass/warn/fail tracker so the command
11
+ * exits with the appropriate status code:
12
+ *
13
+ * - **pass** (counted) — green, informational
14
+ * - **warn** (counted) — yellow, fixable issue that doesn't block builds
15
+ * - **fail** (counted) — red, breaks something; exit code 1
16
+ *
17
+ * The check order is intentional: config first (everything depends on it,
18
+ * abort if invalid), then directories (the alias paths must resolve), then
19
+ * progressively more specific integrations (theme files, Tailwind, deps,
20
+ * component consistency).
21
+ */
22
+ export const doctorCommand = async () => {
23
+ const cwd = process.cwd();
24
+ const counts = { pass: 0, warn: 0, fail: 0 };
25
+ const pass = (msg) => {
26
+ counts.pass++;
27
+ p.log.success(msg);
28
+ };
29
+ const warn = (msg) => {
30
+ counts.warn++;
31
+ p.log.warn(msg);
32
+ };
33
+ const fail = (msg) => {
34
+ counts.fail++;
35
+ p.log.error(msg);
36
+ };
37
+ p.intro(pc.bold('dolan doctor'));
38
+ // --- 1. Config ---
39
+ const config = checkConfig(cwd, pass, fail);
40
+ if (!config) {
41
+ p.outro(pc.red('Fix config issues before continuing.'));
42
+ process.exit(1);
43
+ }
44
+ // --- 2. Directories ---
45
+ checkDirectories(cwd, config, pass, fail);
46
+ // --- 3. Required files ---
47
+ checkRequiredFiles(cwd, config, pass, warn);
48
+ // --- 4. Tailwind integration ---
49
+ checkTailwind(cwd, pass, warn);
50
+ // --- 5. Package dependencies ---
51
+ checkPackageDeps(cwd, pass, warn, fail);
52
+ // --- 6. Component health ---
53
+ checkComponentHealth(cwd, config, pass, warn);
54
+ // --- Summary ---
55
+ const parts = [];
56
+ // The `false` side of this check is unreachable: reaching this line at all
57
+ // requires checkConfig() to have returned a config, and its only successful
58
+ // return path calls pass('Config is valid') first — so counts.pass is
59
+ // always >= 1 by the time the summary runs.
60
+ /* v8 ignore next */
61
+ if (counts.pass > 0)
62
+ parts.push(pc.green(`${counts.pass} passed`));
63
+ if (counts.warn > 0)
64
+ parts.push(pc.yellow(`${counts.warn} warning(s)`));
65
+ if (counts.fail > 0)
66
+ parts.push(pc.red(`${counts.fail} failed`));
67
+ p.outro(parts.join(pc.dim(' · ')));
68
+ process.exit(counts.fail > 0 ? 1 : 0);
69
+ };
70
+ /**
71
+ * --- Check implementations ---
72
+ */
73
+ const checkConfig = (cwd, pass, fail) => {
74
+ if (!configExists(cwd)) {
75
+ fail(`${pc.cyan('dolan.config.json')} not found. Run ${pc.bold('dolan init')} first.`);
76
+ return undefined;
77
+ }
78
+ try {
79
+ const config = readConfig(cwd);
80
+ const aliases = config?.aliases;
81
+ // The three alias keys dolan requires at runtime. We don't validate `utils`
82
+ // anywhere else because it's not actually used (utilities now ship from
83
+ // @blotch/dolan directly) — but it's still listed because old configs may
84
+ // have it and removing it from validation would silently accept broken
85
+ // configs that newer commands might assume.
86
+ const requiredKeys = ['components', 'utils', 'theme'];
87
+ const missing = requiredKeys.filter((key) => typeof aliases?.[key] !== 'string' || aliases[key].length === 0);
88
+ if (missing.length > 0) {
89
+ fail(`Config missing aliases: ${missing.map((k) => pc.cyan(k)).join(', ')}`);
90
+ return undefined;
91
+ }
92
+ pass('Config is valid');
93
+ return config;
94
+ }
95
+ catch {
96
+ fail(`${pc.cyan('dolan.config.json')} is not valid JSON`);
97
+ return undefined;
98
+ }
99
+ };
100
+ const checkDirectories = (cwd, config, pass, fail) => {
101
+ const dirs = [
102
+ { key: 'components', path: config.aliases.components },
103
+ { key: 'theme', path: config.aliases.theme },
104
+ ];
105
+ for (const { key, path } of dirs) {
106
+ const abs = resolve(cwd, path);
107
+ if (existsSync(abs) && statSync(abs).isDirectory()) {
108
+ pass(`${pc.cyan(key)} directory exists (${pc.dim(path)})`);
109
+ }
110
+ else {
111
+ fail(`${pc.cyan(key)} directory missing: ${pc.dim(path)}`);
112
+ }
113
+ }
114
+ };
115
+ const checkRequiredFiles = (cwd, config, pass, warn) => {
116
+ const themeDir = resolve(cwd, config.aliases.theme);
117
+ if (existsSync(join(themeDir, 'tailwind-plugin.ts'))) {
118
+ pass(`${pc.cyan('tailwind-plugin.ts')} found in theme`);
119
+ }
120
+ else {
121
+ warn(`${pc.cyan('tailwind-plugin.ts')} missing from ${pc.dim(config.aliases.theme)}`);
122
+ }
123
+ const hasThemeCss = existsSync(join(themeDir, 'default.css')) ||
124
+ existsSync(join(themeDir, 'dark.css'));
125
+ if (hasThemeCss) {
126
+ pass('Theme CSS found');
127
+ }
128
+ else {
129
+ warn(`No theme CSS files in ${pc.dim(config.aliases.theme)}`);
130
+ }
131
+ };
132
+ const checkTailwind = (cwd, pass, warn) => {
133
+ const candidates = ['tailwind.config.ts', 'tailwind.config.js'];
134
+ const found = candidates.find((f) => existsSync(resolve(cwd, f)));
135
+ if (!found) {
136
+ warn('No Tailwind config found');
137
+ return;
138
+ }
139
+ pass(`Tailwind config found (${pc.dim(found)})`);
140
+ const content = readFileSync(resolve(cwd, found), 'utf-8');
141
+ if (content.includes('blotchPlugin')) {
142
+ pass(`${pc.cyan('blotchPlugin')} referenced in Tailwind config`);
143
+ }
144
+ else {
145
+ warn(`${pc.cyan('blotchPlugin')} not found in ${pc.dim(found)} — add it to your plugins array`);
146
+ }
147
+ };
148
+ const checkPackageDeps = (cwd, pass, warn, fail) => {
149
+ const pkgPath = resolve(cwd, 'package.json');
150
+ if (!existsSync(pkgPath)) {
151
+ fail(`${pc.cyan('package.json')} not found`);
152
+ return;
153
+ }
154
+ let pkg;
155
+ try {
156
+ pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
157
+ }
158
+ catch {
159
+ fail(`${pc.cyan('package.json')} is not valid JSON`);
160
+ return;
161
+ }
162
+ const deps = {
163
+ ...pkg.dependencies,
164
+ ...pkg.devDependencies,
165
+ };
166
+ const required = [
167
+ '@angular/core',
168
+ '@angular/common',
169
+ '@angular/platform-browser',
170
+ '@angular/router',
171
+ ];
172
+ const missingAngular = required.filter((dep) => !deps[dep]);
173
+ if (missingAngular.length === 0) {
174
+ pass('Angular packages found');
175
+ }
176
+ else {
177
+ fail(`Missing Angular packages: ${missingAngular.map((d) => pc.cyan(d)).join(', ')}`);
178
+ }
179
+ if (deps['@blotch/angular-lynx']) {
180
+ pass(`${pc.cyan('@blotch/angular-lynx')} found`);
181
+ }
182
+ else {
183
+ fail(`${pc.cyan('@blotch/angular-lynx')} not found in dependencies`);
184
+ }
185
+ if (deps['tailwindcss']) {
186
+ pass(`${pc.cyan('tailwindcss')} found`);
187
+ }
188
+ else {
189
+ warn(`${pc.cyan('tailwindcss')} not found — required if using dolan UI components`);
190
+ }
191
+ };
192
+ const checkComponentHealth = (cwd, config, pass, warn) => {
193
+ const componentsDir = resolve(cwd, config.aliases.components);
194
+ if (!existsSync(componentsDir))
195
+ return;
196
+ let installed;
197
+ try {
198
+ installed = readdirSync(componentsDir).filter((name) => statSync(join(componentsDir, name)).isDirectory());
199
+ }
200
+ catch {
201
+ return;
202
+ }
203
+ if (installed.length === 0)
204
+ return;
205
+ let allHealthy = true;
206
+ for (const name of installed) {
207
+ const entry = getEntry(name);
208
+ if (!entry) {
209
+ // Directory exists in components/ but no registry entry — either the
210
+ // user manually colocated their own code, or they renamed something
211
+ // away from a known component name. Either way, dolan can't manage it
212
+ // so we surface a warning rather than treating it as a fatal error.
213
+ warn(`${pc.cyan(name)} is not a known dolan component`);
214
+ allHealthy = false;
215
+ continue;
216
+ }
217
+ // Check that all expected source files are present
218
+ try {
219
+ const expectedFiles = getComponentFiles(name);
220
+ const destDir = join(componentsDir, name);
221
+ const missingFiles = expectedFiles.filter((f) => !existsSync(join(destDir, f)));
222
+ if (missingFiles.length > 0) {
223
+ // A registered component is missing files — likely because the user
224
+ // deleted one by hand. Suggest `dolan add` to restore them.
225
+ warn(`${pc.cyan(name)} is missing files: ${missingFiles.map((f) => pc.dim(f)).join(', ')}`);
226
+ allHealthy = false;
227
+ }
228
+ }
229
+ catch {
230
+ warn(`${pc.cyan(name)} — could not verify source files`);
231
+ allHealthy = false;
232
+ }
233
+ // Check dependency consistency — every dependency declared in the
234
+ // registry must also be installed, otherwise the component's imports
235
+ // will fail to resolve at build time. Surface with the exact `dolan add`
236
+ // command so the fix is one copy-paste away.
237
+ for (const dep of entry.dependencies) {
238
+ if (!installed.includes(dep)) {
239
+ warn(`${pc.cyan(name)} requires ${pc.cyan(dep)} — run ${pc.bold(`dolan add ${dep}`)}`);
240
+ allHealthy = false;
241
+ }
242
+ }
243
+ }
244
+ if (allHealthy) {
245
+ pass(`${installed.length} component(s) healthy: ${installed.map((c) => pc.cyan(c)).join(', ')}`);
246
+ }
247
+ };
248
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};