@blotch/dolan 0.0.0-stage → 22.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/add.d.ts +22 -0
- package/dist/commands/add.js +132 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/add.test.d.ts +1 -0
- package/dist/commands/add.test.js +209 -0
- package/dist/commands/add.test.js.map +1 -0
- package/dist/commands/diff.d.ts +13 -0
- package/dist/commands/diff.js +155 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/diff.test.d.ts +1 -0
- package/dist/commands/diff.test.js +327 -0
- package/dist/commands/diff.test.js.map +1 -0
- package/dist/commands/doctor.d.ts +15 -0
- package/dist/commands/doctor.js +248 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/doctor.test.d.ts +1 -0
- package/dist/commands/doctor.test.js +301 -0
- package/dist/commands/doctor.test.js.map +1 -0
- package/dist/commands/eject.d.ts +11 -0
- package/dist/commands/eject.js +55 -0
- package/dist/commands/eject.js.map +1 -0
- package/dist/commands/eject.test.d.ts +1 -0
- package/dist/commands/eject.test.js +151 -0
- package/dist/commands/eject.test.js.map +1 -0
- package/dist/commands/info.d.ts +1 -0
- package/dist/commands/info.js +73 -0
- package/dist/commands/info.js.map +1 -0
- package/dist/commands/info.test.d.ts +1 -0
- package/dist/commands/info.test.js +143 -0
- package/dist/commands/info.test.js.map +1 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +98 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/init.test.d.ts +1 -0
- package/dist/commands/init.test.js +154 -0
- package/dist/commands/init.test.js.map +1 -0
- package/dist/commands/list.d.ts +16 -0
- package/dist/commands/list.js +124 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/list.test.d.ts +1 -0
- package/dist/commands/list.test.js +285 -0
- package/dist/commands/list.test.js.map +1 -0
- package/dist/commands/outdated.d.ts +13 -0
- package/dist/commands/outdated.js +116 -0
- package/dist/commands/outdated.js.map +1 -0
- package/dist/commands/outdated.test.d.ts +1 -0
- package/dist/commands/outdated.test.js +208 -0
- package/dist/commands/outdated.test.js.map +1 -0
- package/dist/commands/remove.d.ts +18 -0
- package/dist/commands/remove.js +161 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/remove.test.d.ts +1 -0
- package/dist/commands/remove.test.js +361 -0
- package/dist/commands/remove.test.js.map +1 -0
- package/dist/commands/theme.d.ts +1 -0
- package/dist/commands/theme.js +66 -0
- package/dist/commands/theme.js.map +1 -0
- package/dist/commands/theme.test.d.ts +1 -0
- package/dist/commands/theme.test.js +133 -0
- package/dist/commands/theme.test.js.map +1 -0
- package/dist/commands/update.d.ts +31 -0
- package/dist/commands/update.js +601 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/update.test.d.ts +1 -0
- package/dist/commands/update.test.js +1233 -0
- package/dist/commands/update.test.js.map +1 -0
- package/dist/config.d.ts +11 -0
- package/dist/config.js +19 -0
- package/dist/config.js.map +1 -0
- package/dist/config.test.d.ts +1 -0
- package/dist/config.test.js +48 -0
- package/dist/config.test.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +89 -0
- package/dist/index.js.map +1 -0
- package/dist/lockfile.d.ts +21 -0
- package/dist/lockfile.js +39 -0
- package/dist/lockfile.js.map +1 -0
- package/dist/registry.d.ts +14 -0
- package/dist/registry.js +85 -0
- package/dist/registry.js.map +1 -0
- package/dist/registry.test.d.ts +1 -0
- package/dist/registry.test.js +95 -0
- package/dist/registry.test.js.map +1 -0
- package/dist/test-utils.d.ts +16 -0
- package/dist/test-utils.js +65 -0
- package/dist/test-utils.js.map +1 -0
- package/dist/ui/components/accordion/accordion.test.ts +194 -0
- package/dist/ui/components/accordion/accordion.ts +173 -0
- package/dist/ui/components/accordion/index.ts +6 -0
- package/dist/ui/components/action-sheet/action-sheet.test.ts +211 -0
- package/dist/ui/components/action-sheet/action-sheet.ts +353 -0
- package/dist/ui/components/action-sheet/index.ts +6 -0
- package/dist/ui/components/alert/alert.test.ts +48 -0
- package/dist/ui/components/alert/alert.ts +104 -0
- package/dist/ui/components/alert/index.ts +1 -0
- package/dist/ui/components/alert-dialog/alert-dialog.test.ts +141 -0
- package/dist/ui/components/alert-dialog/alert-dialog.ts +243 -0
- package/dist/ui/components/alert-dialog/index.ts +7 -0
- package/dist/ui/components/area-chart/area-chart-render.test.ts +121 -0
- package/dist/ui/components/area-chart/area-chart.test.ts +158 -0
- package/dist/ui/components/area-chart/area-chart.ts +349 -0
- package/dist/ui/components/area-chart/index.ts +6 -0
- package/dist/ui/components/aspect-ratio/aspect-ratio.test.ts +10 -0
- package/dist/ui/components/aspect-ratio/aspect-ratio.ts +28 -0
- package/dist/ui/components/aspect-ratio/index.ts +1 -0
- package/dist/ui/components/avatar/avatar.test.ts +69 -0
- package/dist/ui/components/avatar/avatar.ts +131 -0
- package/dist/ui/components/avatar/index.ts +1 -0
- package/dist/ui/components/badge/badge.test.ts +49 -0
- package/dist/ui/components/badge/badge.ts +97 -0
- package/dist/ui/components/badge/index.ts +1 -0
- package/dist/ui/components/bar-chart/bar-chart-render.test.ts +174 -0
- package/dist/ui/components/bar-chart/bar-chart.test.ts +73 -0
- package/dist/ui/components/bar-chart/bar-chart.ts +327 -0
- package/dist/ui/components/bar-chart/index.ts +6 -0
- package/dist/ui/components/bottom-sheet/bottom-sheet.test.ts +163 -0
- package/dist/ui/components/bottom-sheet/bottom-sheet.ts +339 -0
- package/dist/ui/components/bottom-sheet/index.ts +1 -0
- package/dist/ui/components/button/button-render.test.ts +113 -0
- package/dist/ui/components/button/button.test.ts +70 -0
- package/dist/ui/components/button/button.ts +170 -0
- package/dist/ui/components/button/index.ts +6 -0
- package/dist/ui/components/button-group/button-group-render.test.ts +146 -0
- package/dist/ui/components/button-group/button-group.test.ts +54 -0
- package/dist/ui/components/button-group/button-group.ts +209 -0
- package/dist/ui/components/button-group/index.ts +8 -0
- package/dist/ui/components/candlestick-chart/candlestick-chart-render.test.ts +174 -0
- package/dist/ui/components/candlestick-chart/candlestick-chart.test.ts +96 -0
- package/dist/ui/components/candlestick-chart/candlestick-chart.ts +355 -0
- package/dist/ui/components/candlestick-chart/index.ts +7 -0
- package/dist/ui/components/card/card.test.ts +110 -0
- package/dist/ui/components/card/card.ts +162 -0
- package/dist/ui/components/card/index.ts +8 -0
- package/dist/ui/components/cartesian-chart/cartesian-chart-render.test.ts +188 -0
- package/dist/ui/components/cartesian-chart/cartesian-chart.test.ts +549 -0
- package/dist/ui/components/cartesian-chart/cartesian-chart.ts +1140 -0
- package/dist/ui/components/cartesian-chart/index.ts +18 -0
- package/dist/ui/components/checkbox/checkbox.test.ts +59 -0
- package/dist/ui/components/checkbox/checkbox.ts +96 -0
- package/dist/ui/components/checkbox/index.ts +1 -0
- package/dist/ui/components/collapsible/collapsible.test.ts +112 -0
- package/dist/ui/components/collapsible/collapsible.ts +122 -0
- package/dist/ui/components/collapsible/index.ts +5 -0
- package/dist/ui/components/dialog/dialog.test.ts +157 -0
- package/dist/ui/components/dialog/dialog.ts +248 -0
- package/dist/ui/components/dialog/index.ts +7 -0
- package/dist/ui/components/empty-state/empty-state.test.ts +60 -0
- package/dist/ui/components/empty-state/empty-state.ts +46 -0
- package/dist/ui/components/empty-state/index.ts +1 -0
- package/dist/ui/components/icon/icon.test.ts +52 -0
- package/dist/ui/components/icon/icon.ts +54 -0
- package/dist/ui/components/icon/icons.ts +569 -0
- package/dist/ui/components/icon/index.ts +2 -0
- package/dist/ui/components/input/index.ts +1 -0
- package/dist/ui/components/input/input.test.ts +134 -0
- package/dist/ui/components/input/input.ts +189 -0
- package/dist/ui/components/label/index.ts +1 -0
- package/dist/ui/components/label/label.test.ts +38 -0
- package/dist/ui/components/label/label.ts +24 -0
- package/dist/ui/components/line-chart/index.ts +6 -0
- package/dist/ui/components/line-chart/line-chart-render.test.ts +121 -0
- package/dist/ui/components/line-chart/line-chart.test.ts +81 -0
- package/dist/ui/components/line-chart/line-chart.ts +273 -0
- package/dist/ui/components/list/index.ts +1 -0
- package/dist/ui/components/list/list.test.ts +35 -0
- package/dist/ui/components/list/list.ts +71 -0
- package/dist/ui/components/nav-drawer/index.ts +8 -0
- package/dist/ui/components/nav-drawer/nav-drawer.test.ts +267 -0
- package/dist/ui/components/nav-drawer/nav-drawer.ts +504 -0
- package/dist/ui/components/pagination/index.ts +1 -0
- package/dist/ui/components/pagination/pagination.test.ts +96 -0
- package/dist/ui/components/pagination/pagination.ts +147 -0
- package/dist/ui/components/progress/index.ts +1 -0
- package/dist/ui/components/progress/progress.test.ts +71 -0
- package/dist/ui/components/progress/progress.ts +118 -0
- package/dist/ui/components/radio-group/index.ts +1 -0
- package/dist/ui/components/radio-group/radio-group.test.ts +115 -0
- package/dist/ui/components/radio-group/radio-group.ts +129 -0
- package/dist/ui/components/scatter-chart/index.ts +6 -0
- package/dist/ui/components/scatter-chart/scatter-chart-render.test.ts +157 -0
- package/dist/ui/components/scatter-chart/scatter-chart.test.ts +57 -0
- package/dist/ui/components/scatter-chart/scatter-chart.ts +277 -0
- package/dist/ui/components/scroll-area/index.ts +1 -0
- package/dist/ui/components/scroll-area/scroll-area.test.ts +40 -0
- package/dist/ui/components/scroll-area/scroll-area.ts +73 -0
- package/dist/ui/components/select/index.ts +1 -0
- package/dist/ui/components/select/select.test.ts +107 -0
- package/dist/ui/components/select/select.ts +146 -0
- package/dist/ui/components/separator/index.ts +1 -0
- package/dist/ui/components/separator/separator.test.ts +26 -0
- package/dist/ui/components/separator/separator.ts +45 -0
- package/dist/ui/components/sheet/index.ts +7 -0
- package/dist/ui/components/sheet/sheet.test.ts +44 -0
- package/dist/ui/components/sheet/sheet.ts +114 -0
- package/dist/ui/components/skeleton/index.ts +1 -0
- package/dist/ui/components/skeleton/skeleton.test.ts +13 -0
- package/dist/ui/components/skeleton/skeleton.ts +45 -0
- package/dist/ui/components/spinner/index.ts +1 -0
- package/dist/ui/components/spinner/spinner.test.ts +39 -0
- package/dist/ui/components/spinner/spinner.ts +83 -0
- package/dist/ui/components/switch/index.ts +1 -0
- package/dist/ui/components/switch/switch.test.ts +63 -0
- package/dist/ui/components/switch/switch.ts +98 -0
- package/dist/ui/components/tabs/index.ts +1 -0
- package/dist/ui/components/tabs/tabs.test.ts +199 -0
- package/dist/ui/components/tabs/tabs.ts +317 -0
- package/dist/ui/components/textarea/index.ts +1 -0
- package/dist/ui/components/textarea/textarea.test.ts +138 -0
- package/dist/ui/components/textarea/textarea.ts +221 -0
- package/dist/ui/components/toast/index.ts +9 -0
- package/dist/ui/components/toast/toast-state.test.ts +54 -0
- package/dist/ui/components/toast/toast-state.ts +46 -0
- package/dist/ui/components/toast/toast.test.ts +342 -0
- package/dist/ui/components/toast/toast.ts +527 -0
- package/dist/ui/components/toggle/index.ts +7 -0
- package/dist/ui/components/toggle/toggle.test.ts +186 -0
- package/dist/ui/components/toggle/toggle.ts +218 -0
- package/dist/ui/components/typography/index.ts +5 -0
- package/dist/ui/components/typography/typography.test.ts +55 -0
- package/dist/ui/components/typography/typography.ts +44 -0
- package/dist/ui/theme/dark.css +41 -0
- package/dist/ui/theme/default.css +56 -0
- package/dist/ui/theme/tailwind-plugin.test.ts +124 -0
- package/dist/ui/theme/tailwind-plugin.ts +151 -0
- package/dist/ui/utils/animate.test.ts +324 -0
- package/dist/ui/utils/animate.ts +544 -0
- package/dist/ui/utils/cn.test.ts +27 -0
- package/dist/ui/utils/cn.ts +6 -0
- package/dist/utils/analyze.d.ts +32 -0
- package/dist/utils/analyze.js +109 -0
- package/dist/utils/analyze.js.map +1 -0
- package/dist/utils/analyze.test.d.ts +1 -0
- package/dist/utils/analyze.test.js +146 -0
- package/dist/utils/analyze.test.js.map +1 -0
- package/dist/utils/animate.d.ts +210 -0
- package/dist/utils/animate.js +423 -0
- package/dist/utils/animate.js.map +1 -0
- package/dist/utils/animate.test.d.ts +1 -0
- package/dist/utils/animate.test.js +365 -0
- package/dist/utils/animate.test.js.map +1 -0
- package/dist/utils/banner.d.ts +1 -0
- package/dist/utils/banner.js +15 -0
- package/dist/utils/banner.js.map +1 -0
- package/dist/utils/banner.test.d.ts +1 -0
- package/dist/utils/banner.test.js +29 -0
- package/dist/utils/banner.test.js.map +1 -0
- package/dist/utils/cn.d.ts +2 -0
- package/dist/utils/cn.js +6 -0
- package/dist/utils/cn.js.map +1 -0
- package/dist/utils/cn.test.d.ts +1 -0
- package/dist/utils/cn.test.js +21 -0
- package/dist/utils/cn.test.js.map +1 -0
- package/dist/utils/format.d.ts +31 -0
- package/dist/utils/format.js +95 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/format.test.d.ts +1 -0
- package/dist/utils/format.test.js +71 -0
- package/dist/utils/format.test.js.map +1 -0
- package/dist/utils/logger.d.ts +6 -0
- package/dist/utils/logger.js +16 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/logger.test.d.ts +1 -0
- package/dist/utils/logger.test.js +36 -0
- package/dist/utils/logger.test.js.map +1 -0
- package/dist/utils/resolve-paths.d.ts +12 -0
- package/dist/utils/resolve-paths.js +29 -0
- package/dist/utils/resolve-paths.js.map +1 -0
- package/dist/utils/resolve-paths.test.d.ts +1 -0
- package/dist/utils/resolve-paths.test.js +52 -0
- package/dist/utils/resolve-paths.test.js.map +1 -0
- package/package.json +56 -4
- package/README.md +0 -3
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
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
|
+
confirm: vi.fn().mockResolvedValue(true),
|
|
17
|
+
cancel: vi.fn(),
|
|
18
|
+
isCancel: vi.fn().mockReturnValue(false),
|
|
19
|
+
}));
|
|
20
|
+
let fixture;
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
vi.spyOn(process, 'exit').mockImplementation((code) => {
|
|
23
|
+
throw new Error(`process.exit(${code})`);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
afterEach(() => {
|
|
27
|
+
fixture?.cleanup();
|
|
28
|
+
vi.restoreAllMocks();
|
|
29
|
+
});
|
|
30
|
+
describe('removeCommand', () => {
|
|
31
|
+
it('removes component directory and lockfile entry', async () => {
|
|
32
|
+
const content = 'export const Card = {};';
|
|
33
|
+
fixture = createFixture({
|
|
34
|
+
config: DEFAULT_CONFIG,
|
|
35
|
+
lockfile: {
|
|
36
|
+
version: 1,
|
|
37
|
+
components: { card: { 'card.ts': { hash: hashContent(content) } } },
|
|
38
|
+
utils: {},
|
|
39
|
+
theme: {},
|
|
40
|
+
},
|
|
41
|
+
components: { card: { 'card.ts': content } },
|
|
42
|
+
});
|
|
43
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
44
|
+
const { removeCommand } = await import('./remove');
|
|
45
|
+
await removeCommand('card', { force: true });
|
|
46
|
+
const componentDir = join(fixture.dir, DEFAULT_CONFIG.aliases.components, 'card');
|
|
47
|
+
expect(existsSync(componentDir)).toBe(false);
|
|
48
|
+
const lockfile = JSON.parse(readFileSync(join(fixture.dir, 'dolan.lock.json'), 'utf-8'));
|
|
49
|
+
expect(lockfile.components.card).toBeUndefined();
|
|
50
|
+
});
|
|
51
|
+
it('removes orphaned dependencies when confirmed', async () => {
|
|
52
|
+
// button depends on spinner; removing button should orphan spinner
|
|
53
|
+
const buttonContent = 'export const Button = {};';
|
|
54
|
+
const spinnerContent = 'export const Spinner = {};';
|
|
55
|
+
fixture = createFixture({
|
|
56
|
+
config: DEFAULT_CONFIG,
|
|
57
|
+
lockfile: {
|
|
58
|
+
version: 1,
|
|
59
|
+
components: {
|
|
60
|
+
button: { 'button.ts': { hash: hashContent(buttonContent) } },
|
|
61
|
+
spinner: { 'spinner.ts': { hash: hashContent(spinnerContent) } },
|
|
62
|
+
},
|
|
63
|
+
utils: {},
|
|
64
|
+
theme: {},
|
|
65
|
+
},
|
|
66
|
+
components: {
|
|
67
|
+
button: { 'button.ts': buttonContent },
|
|
68
|
+
spinner: { 'spinner.ts': spinnerContent },
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
72
|
+
const { removeCommand } = await import('./remove');
|
|
73
|
+
await removeCommand('button', { force: true });
|
|
74
|
+
const componentsDir = join(fixture.dir, DEFAULT_CONFIG.aliases.components);
|
|
75
|
+
expect(existsSync(join(componentsDir, 'button'))).toBe(false);
|
|
76
|
+
expect(existsSync(join(componentsDir, 'spinner'))).toBe(false);
|
|
77
|
+
const lockfile = JSON.parse(readFileSync(join(fixture.dir, 'dolan.lock.json'), 'utf-8'));
|
|
78
|
+
expect(lockfile.components.button).toBeUndefined();
|
|
79
|
+
expect(lockfile.components.spinner).toBeUndefined();
|
|
80
|
+
});
|
|
81
|
+
it('exits with error for non-installed component', async () => {
|
|
82
|
+
fixture = createFixture({
|
|
83
|
+
config: DEFAULT_CONFIG,
|
|
84
|
+
lockfile: { version: 1, components: {}, utils: {}, theme: {} },
|
|
85
|
+
});
|
|
86
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
87
|
+
const { removeCommand } = await import('./remove');
|
|
88
|
+
await expect(removeCommand('card', { force: true })).rejects.toThrow('process.exit(1)');
|
|
89
|
+
});
|
|
90
|
+
it('exits with error for unknown component', async () => {
|
|
91
|
+
fixture = createFixture({ config: DEFAULT_CONFIG });
|
|
92
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
93
|
+
const { removeCommand } = await import('./remove');
|
|
94
|
+
await expect(removeCommand('nonexistent', { force: true })).rejects.toThrow('process.exit(1)');
|
|
95
|
+
});
|
|
96
|
+
it('exits with error when no config exists', async () => {
|
|
97
|
+
fixture = createFixture({});
|
|
98
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
99
|
+
const p = await import('@clack/prompts');
|
|
100
|
+
const { removeCommand } = await import('./remove');
|
|
101
|
+
await expect(removeCommand('card', { force: true })).rejects.toThrow('process.exit(1)');
|
|
102
|
+
expect(p.log.error).toHaveBeenCalledWith(expect.stringContaining('dolan.config.json'));
|
|
103
|
+
});
|
|
104
|
+
it('warns about dependents and proceeds when the user confirms', async () => {
|
|
105
|
+
// spinner has no dependencies of its own, so removing it can't also
|
|
106
|
+
// trigger the orphan-detection prompt — isolates the dependents branch.
|
|
107
|
+
const buttonContent = 'export const Button = {};';
|
|
108
|
+
const spinnerContent = 'export const Spinner = {};';
|
|
109
|
+
fixture = createFixture({
|
|
110
|
+
config: DEFAULT_CONFIG,
|
|
111
|
+
lockfile: {
|
|
112
|
+
version: 1,
|
|
113
|
+
components: {
|
|
114
|
+
button: { 'button.ts': { hash: hashContent(buttonContent) } },
|
|
115
|
+
spinner: { 'spinner.ts': { hash: hashContent(spinnerContent) } },
|
|
116
|
+
},
|
|
117
|
+
utils: {},
|
|
118
|
+
theme: {},
|
|
119
|
+
},
|
|
120
|
+
components: {
|
|
121
|
+
button: { 'button.ts': buttonContent },
|
|
122
|
+
spinner: { 'spinner.ts': spinnerContent },
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
126
|
+
const p = await import('@clack/prompts');
|
|
127
|
+
p.confirm.mockResolvedValueOnce(true);
|
|
128
|
+
const { removeCommand } = await import('./remove');
|
|
129
|
+
await removeCommand('spinner', {});
|
|
130
|
+
expect(p.log.warn).toHaveBeenCalledWith(expect.stringContaining('depend on'));
|
|
131
|
+
const componentsDir = join(fixture.dir, DEFAULT_CONFIG.aliases.components);
|
|
132
|
+
// Removed despite the warning because the user confirmed.
|
|
133
|
+
expect(existsSync(join(componentsDir, 'spinner'))).toBe(false);
|
|
134
|
+
// button itself is untouched — only the target is removed.
|
|
135
|
+
expect(existsSync(join(componentsDir, 'button'))).toBe(true);
|
|
136
|
+
});
|
|
137
|
+
it('cancels removal when dependents exist and the user declines', async () => {
|
|
138
|
+
const buttonContent = 'export const Button = {};';
|
|
139
|
+
const spinnerContent = 'export const Spinner = {};';
|
|
140
|
+
fixture = createFixture({
|
|
141
|
+
config: DEFAULT_CONFIG,
|
|
142
|
+
lockfile: {
|
|
143
|
+
version: 1,
|
|
144
|
+
components: {
|
|
145
|
+
button: { 'button.ts': { hash: hashContent(buttonContent) } },
|
|
146
|
+
spinner: { 'spinner.ts': { hash: hashContent(spinnerContent) } },
|
|
147
|
+
},
|
|
148
|
+
utils: {},
|
|
149
|
+
theme: {},
|
|
150
|
+
},
|
|
151
|
+
components: {
|
|
152
|
+
button: { 'button.ts': buttonContent },
|
|
153
|
+
spinner: { 'spinner.ts': spinnerContent },
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
157
|
+
const p = await import('@clack/prompts');
|
|
158
|
+
p.confirm.mockResolvedValueOnce(false);
|
|
159
|
+
const { removeCommand } = await import('./remove');
|
|
160
|
+
await expect(removeCommand('spinner', {})).rejects.toThrow('process.exit(0)');
|
|
161
|
+
expect(p.cancel).toHaveBeenCalledWith(expect.stringContaining('Removal canceled'));
|
|
162
|
+
const componentsDir = join(fixture.dir, DEFAULT_CONFIG.aliases.components);
|
|
163
|
+
// Nothing was removed — the user declined.
|
|
164
|
+
expect(existsSync(join(componentsDir, 'spinner'))).toBe(true);
|
|
165
|
+
});
|
|
166
|
+
it('cancels removal when dependents exist and the user cancels the prompt', async () => {
|
|
167
|
+
const buttonContent = 'export const Button = {};';
|
|
168
|
+
const spinnerContent = 'export const Spinner = {};';
|
|
169
|
+
fixture = createFixture({
|
|
170
|
+
config: DEFAULT_CONFIG,
|
|
171
|
+
lockfile: {
|
|
172
|
+
version: 1,
|
|
173
|
+
components: {
|
|
174
|
+
button: { 'button.ts': { hash: hashContent(buttonContent) } },
|
|
175
|
+
spinner: { 'spinner.ts': { hash: hashContent(spinnerContent) } },
|
|
176
|
+
},
|
|
177
|
+
utils: {},
|
|
178
|
+
theme: {},
|
|
179
|
+
},
|
|
180
|
+
components: {
|
|
181
|
+
button: { 'button.ts': buttonContent },
|
|
182
|
+
spinner: { 'spinner.ts': spinnerContent },
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
186
|
+
const p = await import('@clack/prompts');
|
|
187
|
+
p.isCancel.mockReturnValueOnce(true);
|
|
188
|
+
const { removeCommand } = await import('./remove');
|
|
189
|
+
await expect(removeCommand('spinner', {})).rejects.toThrow('process.exit(0)');
|
|
190
|
+
});
|
|
191
|
+
it('prompts to remove orphaned dependencies without --force, and removes them when confirmed', async () => {
|
|
192
|
+
const buttonContent = 'export const Button = {};';
|
|
193
|
+
const spinnerContent = 'export const Spinner = {};';
|
|
194
|
+
fixture = createFixture({
|
|
195
|
+
config: DEFAULT_CONFIG,
|
|
196
|
+
lockfile: {
|
|
197
|
+
version: 1,
|
|
198
|
+
components: {
|
|
199
|
+
button: { 'button.ts': { hash: hashContent(buttonContent) } },
|
|
200
|
+
spinner: { 'spinner.ts': { hash: hashContent(spinnerContent) } },
|
|
201
|
+
},
|
|
202
|
+
utils: {},
|
|
203
|
+
theme: {},
|
|
204
|
+
},
|
|
205
|
+
components: {
|
|
206
|
+
button: { 'button.ts': buttonContent },
|
|
207
|
+
spinner: { 'spinner.ts': spinnerContent },
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
211
|
+
const p = await import('@clack/prompts');
|
|
212
|
+
p.confirm.mockResolvedValueOnce(true);
|
|
213
|
+
const { removeCommand } = await import('./remove');
|
|
214
|
+
await removeCommand('button', {});
|
|
215
|
+
expect(p.confirm).toHaveBeenCalledWith(expect.objectContaining({
|
|
216
|
+
message: expect.stringContaining('orphaned dependencies'),
|
|
217
|
+
}));
|
|
218
|
+
const componentsDir = join(fixture.dir, DEFAULT_CONFIG.aliases.components);
|
|
219
|
+
expect(existsSync(join(componentsDir, 'button'))).toBe(false);
|
|
220
|
+
// Confirmed → orphaned spinner removed too.
|
|
221
|
+
expect(existsSync(join(componentsDir, 'spinner'))).toBe(false);
|
|
222
|
+
});
|
|
223
|
+
it('keeps an orphaned dependency when the user declines removing it', async () => {
|
|
224
|
+
const buttonContent = 'export const Button = {};';
|
|
225
|
+
const spinnerContent = 'export const Spinner = {};';
|
|
226
|
+
fixture = createFixture({
|
|
227
|
+
config: DEFAULT_CONFIG,
|
|
228
|
+
lockfile: {
|
|
229
|
+
version: 1,
|
|
230
|
+
components: {
|
|
231
|
+
button: { 'button.ts': { hash: hashContent(buttonContent) } },
|
|
232
|
+
spinner: { 'spinner.ts': { hash: hashContent(spinnerContent) } },
|
|
233
|
+
},
|
|
234
|
+
utils: {},
|
|
235
|
+
theme: {},
|
|
236
|
+
},
|
|
237
|
+
components: {
|
|
238
|
+
button: { 'button.ts': buttonContent },
|
|
239
|
+
spinner: { 'spinner.ts': spinnerContent },
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
243
|
+
const p = await import('@clack/prompts');
|
|
244
|
+
p.confirm.mockResolvedValueOnce(false);
|
|
245
|
+
const { removeCommand } = await import('./remove');
|
|
246
|
+
await removeCommand('button', {});
|
|
247
|
+
const componentsDir = join(fixture.dir, DEFAULT_CONFIG.aliases.components);
|
|
248
|
+
expect(existsSync(join(componentsDir, 'button'))).toBe(false);
|
|
249
|
+
// Declined → orphaned spinner is kept.
|
|
250
|
+
expect(existsSync(join(componentsDir, 'spinner'))).toBe(true);
|
|
251
|
+
});
|
|
252
|
+
it('does not flag a dependency as orphaned when another installed component still needs it', async () => {
|
|
253
|
+
// empty-state and nav-drawer both depend on icon — removing empty-state
|
|
254
|
+
// must not touch icon (nav-drawer still needs it), and since there's
|
|
255
|
+
// nothing left to orphan, the orphan-removal prompt should never appear.
|
|
256
|
+
const emptyStateContent = 'export const EmptyState = {};';
|
|
257
|
+
const navDrawerContent = 'export const NavDrawer = {};';
|
|
258
|
+
const iconContent = 'export const Icon = {};';
|
|
259
|
+
fixture = createFixture({
|
|
260
|
+
config: DEFAULT_CONFIG,
|
|
261
|
+
lockfile: {
|
|
262
|
+
version: 1,
|
|
263
|
+
components: {
|
|
264
|
+
'empty-state': {
|
|
265
|
+
'empty-state.ts': { hash: hashContent(emptyStateContent) },
|
|
266
|
+
},
|
|
267
|
+
'nav-drawer': {
|
|
268
|
+
'nav-drawer.ts': { hash: hashContent(navDrawerContent) },
|
|
269
|
+
},
|
|
270
|
+
icon: { 'icon.ts': { hash: hashContent(iconContent) } },
|
|
271
|
+
},
|
|
272
|
+
utils: {},
|
|
273
|
+
theme: {},
|
|
274
|
+
},
|
|
275
|
+
components: {
|
|
276
|
+
'empty-state': { 'empty-state.ts': emptyStateContent },
|
|
277
|
+
'nav-drawer': { 'nav-drawer.ts': navDrawerContent },
|
|
278
|
+
icon: { 'icon.ts': iconContent },
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
282
|
+
const p = await import('@clack/prompts');
|
|
283
|
+
p.confirm.mockClear();
|
|
284
|
+
const { removeCommand } = await import('./remove');
|
|
285
|
+
await removeCommand('empty-state', {});
|
|
286
|
+
// No orphans to decide on, so the confirm prompt is never shown.
|
|
287
|
+
expect(p.confirm).not.toHaveBeenCalled();
|
|
288
|
+
const componentsDir = join(fixture.dir, DEFAULT_CONFIG.aliases.components);
|
|
289
|
+
expect(existsSync(join(componentsDir, 'empty-state'))).toBe(false);
|
|
290
|
+
expect(existsSync(join(componentsDir, 'nav-drawer'))).toBe(true);
|
|
291
|
+
expect(existsSync(join(componentsDir, 'icon'))).toBe(true);
|
|
292
|
+
});
|
|
293
|
+
it('does not orphan a dependency that was never installed in the first place', async () => {
|
|
294
|
+
// avatar depends on skeleton, but skeleton was never installed here — the
|
|
295
|
+
// "not installed" skip must short-circuit findOrphans before it ever
|
|
296
|
+
// checks whether anything still needs it.
|
|
297
|
+
const avatarContent = 'export const Avatar = {};';
|
|
298
|
+
fixture = createFixture({
|
|
299
|
+
config: DEFAULT_CONFIG,
|
|
300
|
+
lockfile: {
|
|
301
|
+
version: 1,
|
|
302
|
+
components: {
|
|
303
|
+
avatar: { 'avatar.ts': { hash: hashContent(avatarContent) } },
|
|
304
|
+
},
|
|
305
|
+
utils: {},
|
|
306
|
+
theme: {},
|
|
307
|
+
},
|
|
308
|
+
components: { avatar: { 'avatar.ts': avatarContent } },
|
|
309
|
+
});
|
|
310
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
311
|
+
const p = await import('@clack/prompts');
|
|
312
|
+
p.confirm.mockClear();
|
|
313
|
+
const { removeCommand } = await import('./remove');
|
|
314
|
+
await removeCommand('avatar', {});
|
|
315
|
+
expect(p.confirm).not.toHaveBeenCalled();
|
|
316
|
+
const componentsDir = join(fixture.dir, DEFAULT_CONFIG.aliases.components);
|
|
317
|
+
expect(existsSync(join(componentsDir, 'avatar'))).toBe(false);
|
|
318
|
+
});
|
|
319
|
+
it('drops the lockfile entry for an orphan whose directory already vanished', async () => {
|
|
320
|
+
// Simulates the orphan's directory disappearing between the "what's
|
|
321
|
+
// installed" scan and the actual removal pass (e.g. removed out-of-band
|
|
322
|
+
// while the confirm prompt was on screen) — the removal loop must still
|
|
323
|
+
// clean up its lockfile entry instead of throwing on the missing dir.
|
|
324
|
+
const buttonContent = 'export const Button = {};';
|
|
325
|
+
const spinnerContent = 'export const Spinner = {};';
|
|
326
|
+
fixture = createFixture({
|
|
327
|
+
config: DEFAULT_CONFIG,
|
|
328
|
+
lockfile: {
|
|
329
|
+
version: 1,
|
|
330
|
+
components: {
|
|
331
|
+
button: { 'button.ts': { hash: hashContent(buttonContent) } },
|
|
332
|
+
spinner: { 'spinner.ts': { hash: hashContent(spinnerContent) } },
|
|
333
|
+
},
|
|
334
|
+
utils: {},
|
|
335
|
+
theme: {},
|
|
336
|
+
},
|
|
337
|
+
components: {
|
|
338
|
+
button: { 'button.ts': buttonContent },
|
|
339
|
+
spinner: { 'spinner.ts': spinnerContent },
|
|
340
|
+
},
|
|
341
|
+
});
|
|
342
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
343
|
+
const componentsDir = join(fixture.dir, DEFAULT_CONFIG.aliases.components);
|
|
344
|
+
const { rmSync } = await import('node:fs');
|
|
345
|
+
const p = await import('@clack/prompts');
|
|
346
|
+
p.confirm.mockImplementationOnce(async () => {
|
|
347
|
+
// Delete spinner's directory out from under the command right as the
|
|
348
|
+
// user confirms removing it.
|
|
349
|
+
rmSync(join(componentsDir, 'spinner'), { recursive: true, force: true });
|
|
350
|
+
return true;
|
|
351
|
+
});
|
|
352
|
+
const { removeCommand } = await import('./remove');
|
|
353
|
+
await removeCommand('button', {});
|
|
354
|
+
// No throw, and the lockfile entry is still cleaned up despite the dir
|
|
355
|
+
// already being gone.
|
|
356
|
+
const lockfile = JSON.parse(readFileSync(join(fixture.dir, 'dolan.lock.json'), 'utf-8'));
|
|
357
|
+
expect(lockfile.components.spinner).toBeUndefined();
|
|
358
|
+
expect(lockfile.components.button).toBeUndefined();
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
//# sourceMappingURL=remove.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove.test.js","sourceRoot":"","sources":["../../src/commands/remove.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const themeCommand: (name?: string) => Promise<void>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as p from '@clack/prompts';
|
|
2
|
+
import { existsSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { resolve, join } from 'node:path';
|
|
4
|
+
import pc from 'picocolors';
|
|
5
|
+
import { configExists, readConfig } from '../config.js';
|
|
6
|
+
import { getUiSourceDir } from '../utils/resolve-paths.js';
|
|
7
|
+
export const themeCommand = async (name) => {
|
|
8
|
+
const cwd = process.cwd();
|
|
9
|
+
p.intro(pc.bold('dolan theme'));
|
|
10
|
+
if (!configExists(cwd)) {
|
|
11
|
+
p.log.error(`No ${pc.cyan('dolan.config.json')} found. Run ${pc.bold('dolan init')} first.`);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
const config = readConfig(cwd);
|
|
15
|
+
const themeDir = resolve(cwd, config.aliases.theme);
|
|
16
|
+
if (name) {
|
|
17
|
+
createTheme(name, themeDir);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
listThemes(themeDir);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
const listThemes = (themeDir) => {
|
|
24
|
+
if (!existsSync(themeDir)) {
|
|
25
|
+
p.log.warn('No theme directory found.');
|
|
26
|
+
p.outro('');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const files = readdirSync(themeDir).filter((f) => f.endsWith('.css'));
|
|
30
|
+
if (files.length === 0) {
|
|
31
|
+
p.log.warn('No theme files found.');
|
|
32
|
+
p.outro('');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
p.log.message(pc.bold('Installed themes:\n'));
|
|
36
|
+
for (const file of files) {
|
|
37
|
+
const name = file.replace('.css', '');
|
|
38
|
+
p.log.message(` ${pc.green('●')} ${name}`);
|
|
39
|
+
}
|
|
40
|
+
p.outro(`Create a custom theme: ${pc.bold('dolan theme <name>')}`);
|
|
41
|
+
};
|
|
42
|
+
const createTheme = (name, themeDir) => {
|
|
43
|
+
const fileName = `${name}.css`;
|
|
44
|
+
const destPath = resolve(themeDir, fileName);
|
|
45
|
+
if (existsSync(destPath)) {
|
|
46
|
+
p.log.error(`Theme ${pc.bold(name)} already exists at ${pc.dim(destPath)}`);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
// Read the default theme as a template
|
|
50
|
+
const uiSrc = getUiSourceDir();
|
|
51
|
+
const defaultThemePath = join(uiSrc, 'theme', 'default.css');
|
|
52
|
+
if (!existsSync(defaultThemePath)) {
|
|
53
|
+
p.log.error('Could not find default theme template in @blotch/ui.');
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
const template = readFileSync(defaultThemePath, 'utf-8');
|
|
57
|
+
// Replace only the first block comment (the header). The lazy `*?` is
|
|
58
|
+
// critical — without it, the greedy version would consume everything from
|
|
59
|
+
// the first `/*` to the LAST `*/` in the file, wiping all comments.
|
|
60
|
+
const content = template.replace(/\/\*[\s\S]*?\*\//, `/* Custom theme: ${name}\n *\n * Edit the CSS variables below to customize your theme.\n * Values are complete rgba() colors (e.g., "rgba(24, 24, 27, 1)") referenced\n * directly via var(--x); Lynx drops Tailwind's space-separated hsl(var() / a).\n */`);
|
|
61
|
+
writeFileSync(destPath, content);
|
|
62
|
+
p.log.success(`Created ${pc.bold(fileName)} in ${pc.dim(themeDir)}`);
|
|
63
|
+
p.log.info(`Import it in your global styles:\n ${pc.cyan(`@import './${fileName}';`)}`);
|
|
64
|
+
p.outro('Edit the CSS variables to customize your theme.');
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/commands/theme.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { createFixture, DEFAULT_CONFIG } from '../test-utils';
|
|
5
|
+
vi.mock('@clack/prompts', () => ({
|
|
6
|
+
intro: vi.fn(),
|
|
7
|
+
outro: vi.fn(),
|
|
8
|
+
log: {
|
|
9
|
+
message: vi.fn(),
|
|
10
|
+
error: vi.fn(),
|
|
11
|
+
warn: vi.fn(),
|
|
12
|
+
success: vi.fn(),
|
|
13
|
+
info: vi.fn(),
|
|
14
|
+
},
|
|
15
|
+
}));
|
|
16
|
+
let fixture;
|
|
17
|
+
vi.mock('../utils/resolve-paths.js', () => ({
|
|
18
|
+
getUiSourceDir: () => fixture.uiDir,
|
|
19
|
+
}));
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
vi.spyOn(process, 'exit').mockImplementation((code) => {
|
|
22
|
+
throw new Error(`process.exit(${code})`);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
afterEach(() => {
|
|
26
|
+
fixture?.cleanup();
|
|
27
|
+
vi.restoreAllMocks();
|
|
28
|
+
});
|
|
29
|
+
const THEME_TEMPLATE = `/*
|
|
30
|
+
* @blotch/ui default theme
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
page {
|
|
34
|
+
--background: 0 0% 100%;
|
|
35
|
+
--foreground: 240 10% 3.9%;
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
describe('themeCommand', () => {
|
|
39
|
+
it('lists installed theme CSS files', async () => {
|
|
40
|
+
fixture = createFixture({
|
|
41
|
+
config: DEFAULT_CONFIG,
|
|
42
|
+
themeFiles: { 'default.css': THEME_TEMPLATE },
|
|
43
|
+
});
|
|
44
|
+
// Put a theme file in the project theme dir too
|
|
45
|
+
const { writeFileSync } = await import('node:fs');
|
|
46
|
+
writeFileSync(join(fixture.dir, DEFAULT_CONFIG.aliases.theme, 'default.css'), THEME_TEMPLATE);
|
|
47
|
+
writeFileSync(join(fixture.dir, DEFAULT_CONFIG.aliases.theme, 'dark.css'), 'page.dark {}');
|
|
48
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
49
|
+
const p = await import('@clack/prompts');
|
|
50
|
+
const { themeCommand } = await import('./theme');
|
|
51
|
+
await themeCommand();
|
|
52
|
+
const messages = p.log.message.mock.calls
|
|
53
|
+
.map((c) => c[0])
|
|
54
|
+
.join('\n');
|
|
55
|
+
expect(messages).toContain('default');
|
|
56
|
+
expect(messages).toContain('dark');
|
|
57
|
+
});
|
|
58
|
+
it('creates a new theme from the default template', async () => {
|
|
59
|
+
fixture = createFixture({
|
|
60
|
+
config: DEFAULT_CONFIG,
|
|
61
|
+
themeFiles: { 'default.css': THEME_TEMPLATE },
|
|
62
|
+
});
|
|
63
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
64
|
+
const p = await import('@clack/prompts');
|
|
65
|
+
const { themeCommand } = await import('./theme');
|
|
66
|
+
await themeCommand('ocean');
|
|
67
|
+
const themePath = join(fixture.dir, DEFAULT_CONFIG.aliases.theme, 'ocean.css');
|
|
68
|
+
expect(existsSync(themePath)).toBe(true);
|
|
69
|
+
const content = readFileSync(themePath, 'utf-8');
|
|
70
|
+
expect(content).toContain('Custom theme: ocean');
|
|
71
|
+
expect(content).toContain('--background');
|
|
72
|
+
expect(p.log.success).toHaveBeenCalled();
|
|
73
|
+
});
|
|
74
|
+
it('errors if theme already exists', async () => {
|
|
75
|
+
fixture = createFixture({
|
|
76
|
+
config: DEFAULT_CONFIG,
|
|
77
|
+
themeFiles: { 'default.css': THEME_TEMPLATE },
|
|
78
|
+
});
|
|
79
|
+
// Create the theme file in the project
|
|
80
|
+
const { writeFileSync } = await import('node:fs');
|
|
81
|
+
writeFileSync(join(fixture.dir, DEFAULT_CONFIG.aliases.theme, 'ocean.css'), 'existing');
|
|
82
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
83
|
+
const { themeCommand } = await import('./theme');
|
|
84
|
+
await expect(themeCommand('ocean')).rejects.toThrow('process.exit(1)');
|
|
85
|
+
});
|
|
86
|
+
it('errors if no config exists', async () => {
|
|
87
|
+
fixture = createFixture({});
|
|
88
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
89
|
+
const { themeCommand } = await import('./theme');
|
|
90
|
+
await expect(themeCommand()).rejects.toThrow('process.exit(1)');
|
|
91
|
+
});
|
|
92
|
+
it('warns when the project theme directory does not exist', async () => {
|
|
93
|
+
fixture = createFixture({
|
|
94
|
+
config: DEFAULT_CONFIG,
|
|
95
|
+
themeFiles: { 'default.css': THEME_TEMPLATE },
|
|
96
|
+
});
|
|
97
|
+
// createFixture always creates the configured theme dir up front — remove
|
|
98
|
+
// it to exercise the "nothing installed yet" branch of listThemes.
|
|
99
|
+
const { rmSync } = await import('node:fs');
|
|
100
|
+
rmSync(join(fixture.dir, DEFAULT_CONFIG.aliases.theme), {
|
|
101
|
+
recursive: true,
|
|
102
|
+
force: true,
|
|
103
|
+
});
|
|
104
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
105
|
+
const p = await import('@clack/prompts');
|
|
106
|
+
const { themeCommand } = await import('./theme');
|
|
107
|
+
await themeCommand();
|
|
108
|
+
expect(p.log.warn).toHaveBeenCalledWith(expect.stringContaining('No theme directory found'));
|
|
109
|
+
});
|
|
110
|
+
it('warns when the theme directory has no CSS files', async () => {
|
|
111
|
+
fixture = createFixture({
|
|
112
|
+
config: DEFAULT_CONFIG,
|
|
113
|
+
themeFiles: { 'default.css': THEME_TEMPLATE },
|
|
114
|
+
});
|
|
115
|
+
// Project theme dir exists (created by the fixture) but is empty.
|
|
116
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
117
|
+
const p = await import('@clack/prompts');
|
|
118
|
+
const { themeCommand } = await import('./theme');
|
|
119
|
+
await themeCommand();
|
|
120
|
+
expect(p.log.warn).toHaveBeenCalledWith(expect.stringContaining('No theme files found'));
|
|
121
|
+
});
|
|
122
|
+
it('errors if the default theme template is missing from @blotch/ui', async () => {
|
|
123
|
+
// No themeFiles passed — createFixture never creates uiDir/theme, so
|
|
124
|
+
// getUiSourceDir()/theme/default.css can't be found.
|
|
125
|
+
fixture = createFixture({ config: DEFAULT_CONFIG });
|
|
126
|
+
vi.spyOn(process, 'cwd').mockReturnValue(fixture.dir);
|
|
127
|
+
const { themeCommand } = await import('./theme');
|
|
128
|
+
await expect(themeCommand('ocean')).rejects.toThrow('process.exit(1)');
|
|
129
|
+
const p = await import('@clack/prompts');
|
|
130
|
+
expect(p.log.error).toHaveBeenCalledWith(expect.stringContaining('Could not find default theme template'));
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
//# sourceMappingURL=theme.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.test.js","sourceRoot":"","sources":["../../src/commands/theme.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Three-way merge update for installed components, modeled on the same flow
|
|
3
|
+
* git/Mercurial use when applying upstream changes to a fork:
|
|
4
|
+
*
|
|
5
|
+
* - **base** (lockfile hash) — what the file was at last add/update.
|
|
6
|
+
* - **current** (disk content) — what the user has now.
|
|
7
|
+
* - **upstream** (registry source, re-rewritten) — what we'd install fresh.
|
|
8
|
+
*
|
|
9
|
+
* For each file, `analyzeFile` produces a status:
|
|
10
|
+
* - **up-to-date** — base == current == upstream (no work needed).
|
|
11
|
+
* - **auto-update** — current matches base, upstream differs (safe to
|
|
12
|
+
* overwrite — user hasn't touched the file).
|
|
13
|
+
* - **new-upstream** — file didn't exist locally (new dependency file).
|
|
14
|
+
* - **user-modified** — current differs from base, upstream matches base
|
|
15
|
+
* (user has edits, no upstream change → keep theirs).
|
|
16
|
+
* - **conflict** — current differs from base AND upstream differs
|
|
17
|
+
* from base (both sides moved → prompt the user).
|
|
18
|
+
*
|
|
19
|
+
* `--force` bypasses all prompts and overwrites every file with upstream,
|
|
20
|
+
* which is destructive but useful for resetting to a clean baseline.
|
|
21
|
+
*
|
|
22
|
+
* After the apply phase, the lockfile is updated to record the new upstream
|
|
23
|
+
* hash for every file — even ones the user chose to keep. This intentionally
|
|
24
|
+
* "advances the base" so the user only sees the same conflict once: next
|
|
25
|
+
* update compares against the (now-advanced) base and surfaces only changes
|
|
26
|
+
* introduced since this update.
|
|
27
|
+
*/
|
|
28
|
+
export declare const updateCommand: (options: {
|
|
29
|
+
force?: boolean;
|
|
30
|
+
selective?: boolean;
|
|
31
|
+
}) => Promise<void>;
|