@blotch/dolan 22.2.2 → 22.2.4
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 +6 -2
- package/dist/commands/add.js +41 -11
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/add.test.js +162 -9
- package/dist/commands/add.test.js.map +1 -1
- package/dist/commands/diff.d.ts +2 -1
- package/dist/commands/diff.js +38 -25
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/diff.test.js +72 -11
- package/dist/commands/diff.test.js.map +1 -1
- package/dist/commands/doctor.js +228 -34
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/doctor.test.js +367 -10
- package/dist/commands/doctor.test.js.map +1 -1
- package/dist/commands/eject.js +7 -0
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/eject.test.js +39 -0
- package/dist/commands/eject.test.js.map +1 -1
- package/dist/commands/info.js +3 -2
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.d.ts +37 -1
- package/dist/commands/init.js +169 -40
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/init.test.js +392 -27
- package/dist/commands/init.test.js.map +1 -1
- package/dist/commands/install-packages.d.ts +6 -0
- package/dist/commands/install-packages.js +20 -0
- package/dist/commands/install-packages.js.map +1 -0
- package/dist/commands/install-packages.test.d.ts +1 -0
- package/dist/commands/install-packages.test.js +55 -0
- package/dist/commands/install-packages.test.js.map +1 -0
- package/dist/commands/list.js +21 -14
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/list.test.js +62 -5
- package/dist/commands/list.test.js.map +1 -1
- package/dist/commands/outdated.js +11 -10
- package/dist/commands/outdated.js.map +1 -1
- package/dist/commands/outdated.test.js +20 -5
- package/dist/commands/outdated.test.js.map +1 -1
- package/dist/commands/remove.d.ts +4 -0
- package/dist/commands/remove.js +17 -4
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/remove.test.js +53 -2
- package/dist/commands/remove.test.js.map +1 -1
- package/dist/commands/theme.js +1 -1
- package/dist/commands/theme.js.map +1 -1
- package/dist/commands/update.d.ts +11 -0
- package/dist/commands/update.js +174 -58
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/update.test.js +587 -33
- package/dist/commands/update.test.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/lockfile.d.ts +7 -0
- package/dist/lockfile.js +36 -0
- package/dist/lockfile.js.map +1 -1
- package/dist/lockfile.test.d.ts +1 -0
- package/dist/lockfile.test.js +25 -0
- package/dist/lockfile.test.js.map +1 -0
- package/dist/registry.d.ts +14 -0
- package/dist/registry.js +78 -24
- package/dist/registry.js.map +1 -1
- package/dist/registry.test.js +119 -38
- package/dist/registry.test.js.map +1 -1
- package/dist/test-utils.d.ts +5 -0
- package/dist/test-utils.js +6 -1
- package/dist/test-utils.js.map +1 -1
- package/dist/testing/fire-lynx-event.d.ts +14 -0
- package/dist/testing/fire-lynx-event.js +19 -0
- package/dist/testing/fire-lynx-event.js.map +1 -0
- package/dist/testing/fire-lynx-event.test.d.ts +1 -0
- package/dist/testing/fire-lynx-event.test.js +44 -0
- package/dist/testing/fire-lynx-event.test.js.map +1 -0
- package/dist/testing/lynx-main-thread.d.ts +22 -0
- package/dist/testing/lynx-main-thread.js +11 -0
- package/dist/testing/lynx-main-thread.js.map +1 -0
- package/dist/testing/lynx-main-thread.test.d.ts +1 -0
- package/dist/testing/lynx-main-thread.test.js +24 -0
- package/dist/testing/lynx-main-thread.test.js.map +1 -0
- package/dist/testing/set-input-signal.d.ts +14 -0
- package/dist/testing/set-input-signal.js +21 -0
- package/dist/testing/set-input-signal.js.map +1 -0
- package/dist/testing/set-input-signal.test.d.ts +1 -0
- package/dist/testing/set-input-signal.test.js +20 -0
- package/dist/testing/set-input-signal.test.js.map +1 -0
- package/dist/ui/components/accordion/accordion.test.ts +158 -144
- package/dist/ui/components/accordion/accordion.ts +19 -14
- package/dist/ui/components/action-sheet/action-sheet.test.ts +283 -151
- package/dist/ui/components/action-sheet/action-sheet.ts +77 -43
- package/dist/ui/components/alert/alert.test.ts +67 -19
- package/dist/ui/components/alert/alert.ts +14 -16
- package/dist/ui/components/alert-dialog/alert-dialog.test.ts +208 -94
- package/dist/ui/components/alert-dialog/alert-dialog.ts +75 -38
- package/dist/ui/components/area-chart/area-chart.test.ts +134 -119
- package/dist/ui/components/area-chart/area-chart.ts +100 -315
- package/dist/ui/components/area-chart/index.ts +2 -3
- package/dist/ui/components/avatar/avatar.test.ts +89 -45
- package/dist/ui/components/badge/badge.test.ts +57 -23
- package/dist/ui/components/badge/badge.ts +12 -14
- package/dist/ui/components/bar-chart/bar-chart.test.ts +172 -45
- package/dist/ui/components/bar-chart/bar-chart.ts +140 -294
- package/dist/ui/components/bar-chart/index.ts +3 -3
- package/dist/ui/components/bottom-sheet/bottom-sheet.test.ts +386 -128
- package/dist/ui/components/bottom-sheet/bottom-sheet.ts +170 -53
- package/dist/ui/components/button/button.test.ts +611 -2
- package/dist/ui/components/button/button.ts +434 -49
- package/dist/ui/components/button/index.ts +2 -0
- package/dist/ui/components/button-group/button-group.test.ts +484 -2
- package/dist/ui/components/button-group/button-group.ts +380 -68
- package/dist/ui/components/button-group/index.ts +3 -0
- package/dist/ui/components/candlestick-chart/candlestick-chart.test.ts +183 -58
- package/dist/ui/components/candlestick-chart/candlestick-chart.ts +150 -323
- package/dist/ui/components/candlestick-chart/index.ts +3 -4
- package/dist/ui/components/card/card.test.ts +82 -62
- package/dist/ui/components/chart/chart-focus.test.ts +132 -0
- package/dist/ui/components/chart/chart-focus.ts +115 -0
- package/dist/ui/components/chart/chart-presets.test.ts +335 -0
- package/dist/ui/components/chart/chart-presets.ts +278 -0
- package/dist/ui/components/chart/chart-scene.test.ts +589 -0
- package/dist/ui/components/chart/chart-scene.ts +483 -0
- package/dist/ui/components/chart/chart-theme.test.ts +85 -0
- package/dist/ui/components/chart/chart-theme.ts +210 -0
- package/dist/ui/components/chart/chart-zoom.test.ts +159 -0
- package/dist/ui/components/chart/chart-zoom.ts +162 -0
- package/dist/ui/components/chart/chart.test.ts +1017 -0
- package/dist/ui/components/chart/chart.ts +934 -0
- package/dist/ui/components/chart/index.ts +24 -0
- package/dist/ui/components/checkbox/checkbox.test.ts +124 -42
- package/dist/ui/components/checkbox/checkbox.ts +23 -23
- package/dist/ui/components/collapsible/collapsible.test.ts +158 -81
- package/dist/ui/components/collapsible/collapsible.ts +19 -14
- package/dist/ui/components/context-menu/context-menu.test.ts +224 -0
- package/dist/ui/components/context-menu/context-menu.ts +110 -0
- package/dist/ui/components/context-menu/index.ts +1 -0
- package/dist/ui/components/dialog/dialog.test.ts +213 -108
- package/dist/ui/components/dialog/dialog.ts +72 -35
- package/dist/ui/components/dock/dock-scroll.test.ts +130 -0
- package/dist/ui/components/dock/dock-scroll.ts +133 -0
- package/dist/ui/components/dock/dock.test.ts +749 -0
- package/dist/ui/components/dock/dock.ts +960 -0
- package/dist/ui/components/dock/index.ts +2 -0
- package/dist/ui/components/empty-state/empty-state.test.ts +28 -39
- package/dist/ui/components/glass/concentric-radius.test.ts +13 -0
- package/dist/ui/components/glass/concentric-radius.ts +17 -0
- package/dist/ui/components/glass/glass-design.test.ts +78 -0
- package/dist/ui/components/glass/glass-design.ts +119 -0
- package/dist/ui/components/glass/glass.test.ts +338 -0
- package/dist/ui/components/glass/glass.ts +360 -0
- package/dist/ui/components/glass/index.ts +18 -0
- package/dist/ui/components/icon/icon-theme.test.ts +169 -0
- package/dist/ui/components/icon/icon-theme.ts +227 -0
- package/dist/ui/components/icon/icon.test.ts +85 -25
- package/dist/ui/components/icon/icon.ts +38 -21
- package/dist/ui/components/input/input.test.ts +178 -101
- package/dist/ui/components/input/input.ts +15 -12
- package/dist/ui/components/label/label.test.ts +11 -24
- package/dist/ui/components/line-chart/index.ts +2 -3
- package/dist/ui/components/line-chart/line-chart.test.ts +149 -56
- package/dist/ui/components/line-chart/line-chart.ts +83 -241
- package/dist/ui/components/list/list.test.ts +119 -21
- package/dist/ui/components/list/list.ts +21 -15
- package/dist/ui/components/menu/index.ts +25 -0
- package/dist/ui/components/menu/menu-placement.test.ts +153 -0
- package/dist/ui/components/menu/menu-placement.ts +159 -0
- package/dist/ui/components/menu/menu-popup.test.ts +632 -0
- package/dist/ui/components/menu/menu-popup.ts +544 -0
- package/dist/ui/components/menu/menu.test.ts +429 -0
- package/dist/ui/components/menu/menu.ts +415 -0
- package/dist/ui/components/nav-drawer/nav-drawer.test.ts +435 -191
- package/dist/ui/components/nav-drawer/nav-drawer.ts +127 -56
- package/dist/ui/components/pagination/pagination.test.ts +177 -65
- package/dist/ui/components/pagination/pagination.ts +55 -8
- package/dist/ui/components/progress/progress.test.ts +102 -46
- package/dist/ui/components/progress/progress.ts +52 -54
- package/dist/ui/components/radio-group/radio-group.test.ts +128 -83
- package/dist/ui/components/radio-group/radio-group.ts +24 -24
- package/dist/ui/components/scatter-chart/index.ts +2 -3
- package/dist/ui/components/scatter-chart/scatter-chart.test.ts +131 -26
- package/dist/ui/components/scatter-chart/scatter-chart.ts +104 -250
- package/dist/ui/components/scroll-area/scroll-area.test.ts +95 -24
- package/dist/ui/components/scroll-area/scroll-area.ts +8 -8
- package/dist/ui/components/select/select.test.ts +138 -78
- package/dist/ui/components/select/select.ts +17 -11
- package/dist/ui/components/separator/separator.test.ts +18 -17
- package/dist/ui/components/sheet/sheet.test.ts +64 -11
- package/dist/ui/components/sheet/sheet.ts +9 -1
- package/dist/ui/components/skeleton/skeleton.test.ts +24 -7
- package/dist/ui/components/skeleton/skeleton.ts +10 -16
- package/dist/ui/components/spinner/spinner.test.ts +67 -22
- package/dist/ui/components/spinner/spinner.ts +48 -41
- package/dist/ui/components/switch/switch.test.ts +116 -46
- package/dist/ui/components/switch/switch.ts +8 -13
- package/dist/ui/components/tab-bar/index.ts +1 -0
- package/dist/ui/components/tab-bar/tab-bar.test.ts +280 -0
- package/dist/ui/components/tab-bar/tab-bar.ts +230 -0
- package/dist/ui/components/tabs/tabs.test.ts +215 -157
- package/dist/ui/components/tabs/tabs.ts +110 -118
- package/dist/ui/components/textarea/textarea.test.ts +206 -100
- package/dist/ui/components/textarea/textarea.ts +14 -12
- package/dist/ui/components/toast/toast.test.ts +436 -315
- package/dist/ui/components/toast/toast.ts +62 -55
- package/dist/ui/components/toggle/toggle.test.ts +247 -140
- package/dist/ui/theme/chart-colors.test.ts +35 -0
- package/dist/ui/theme/dark.css +46 -2
- package/dist/ui/theme/default.css +63 -7
- package/dist/ui/theme/icon-colors.test.ts +35 -0
- package/dist/ui/theme/rgb-channels.test.ts +84 -0
- package/dist/ui/theme/tailwind-build.test.ts +114 -0
- package/dist/ui/theme/tailwind-css.test.ts +83 -0
- package/dist/ui/theme/tailwind-plugin.test.ts +42 -2
- package/dist/ui/theme/tailwind-plugin.ts +98 -25
- package/dist/ui/theme/tailwind.css +113 -0
- package/dist/ui/utils/animate.test.ts +13 -1
- package/dist/utils/analyze.d.ts +14 -0
- package/dist/utils/analyze.js +15 -0
- package/dist/utils/analyze.js.map +1 -1
- package/dist/utils/analyze.test.js +14 -1
- package/dist/utils/analyze.test.js.map +1 -1
- package/dist/utils/installed.d.ts +29 -0
- package/dist/utils/installed.js +43 -0
- package/dist/utils/installed.js.map +1 -0
- package/dist/utils/installed.test.d.ts +1 -0
- package/dist/utils/installed.test.js +57 -0
- package/dist/utils/installed.test.js.map +1 -0
- package/dist/utils/interactive.d.ts +9 -0
- package/dist/utils/interactive.js +10 -0
- package/dist/utils/interactive.js.map +1 -0
- package/dist/utils/interactive.test.d.ts +1 -0
- package/dist/utils/interactive.test.js +24 -0
- package/dist/utils/interactive.test.js.map +1 -0
- package/dist/utils/packages.d.ts +36 -0
- package/dist/utils/packages.js +70 -0
- package/dist/utils/packages.js.map +1 -0
- package/dist/utils/packages.test.d.ts +1 -0
- package/dist/utils/packages.test.js +89 -0
- package/dist/utils/packages.test.js.map +1 -0
- package/dist/utils/resolve-paths.d.ts +17 -1
- package/dist/utils/resolve-paths.js +21 -3
- package/dist/utils/resolve-paths.js.map +1 -1
- package/dist/utils/resolve-paths.test.js +38 -2
- package/dist/utils/resolve-paths.test.js.map +1 -1
- package/dist/utils/tailwind.d.ts +25 -0
- package/dist/utils/tailwind.js +51 -0
- package/dist/utils/tailwind.js.map +1 -0
- package/dist/utils/tailwind.test.d.ts +1 -0
- package/dist/utils/tailwind.test.js +71 -0
- package/dist/utils/tailwind.test.js.map +1 -0
- package/package.json +13 -1
- package/dist/ui/components/area-chart/area-chart-render.test.ts +0 -121
- package/dist/ui/components/bar-chart/bar-chart-render.test.ts +0 -174
- package/dist/ui/components/button/button-render.test.ts +0 -113
- package/dist/ui/components/button-group/button-group-render.test.ts +0 -146
- package/dist/ui/components/candlestick-chart/candlestick-chart-render.test.ts +0 -174
- package/dist/ui/components/cartesian-chart/cartesian-chart-render.test.ts +0 -188
- package/dist/ui/components/cartesian-chart/cartesian-chart.test.ts +0 -525
- package/dist/ui/components/cartesian-chart/cartesian-chart.ts +0 -1140
- package/dist/ui/components/cartesian-chart/index.ts +0 -18
- package/dist/ui/components/line-chart/line-chart-render.test.ts +0 -121
- package/dist/ui/components/scatter-chart/scatter-chart-render.test.ts +0 -157
|
@@ -16,7 +16,7 @@ const SAFE_AREA_SIDES = {
|
|
|
16
16
|
* Registers safe-area-aware padding utilities driven by CSS `env(safe-area-inset-*)`.
|
|
17
17
|
*
|
|
18
18
|
* Why `env()` works on Lynx: the native CSS engine parses `env(safe-area-inset-*)`
|
|
19
|
-
* as a length (see
|
|
19
|
+
* as a length (see lynx-family/lynx's css_style_utils.cc `GetEnvValue`), and its
|
|
20
20
|
* calc parser accepts `env()` *inside* `calc()` too — so `calc(1rem + env(...))`
|
|
21
21
|
* is valid on device. The inset values default to `0` until the native host app
|
|
22
22
|
* populates them, so every utility here degrades gracefully to plain padding
|
|
@@ -69,6 +69,51 @@ export const addSafeAreaUtilities = ({
|
|
|
69
69
|
}
|
|
70
70
|
};
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* What Tailwind passes a color it was given as a function:
|
|
74
|
+
* - an opacity modifier sets only `opacityValue` (`bg-primary/50` → `0.5`);
|
|
75
|
+
* - a plain class whose utility has an opacity variable sets
|
|
76
|
+
* `opacityVariable` too, and `opacityValue` is `var(--tw-bg-opacity, 1)`
|
|
77
|
+
* (`bg-primary`);
|
|
78
|
+
* - other plain classes pass neither (`caret-primary`);
|
|
79
|
+
* - `theme('colors.primary')` in a stylesheet passes an `opacityValue` of 1.
|
|
80
|
+
*/
|
|
81
|
+
type ColorOptions = {
|
|
82
|
+
opacityValue?: string | number;
|
|
83
|
+
opacityVariable?: string;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* A theme color that takes Tailwind's opacity modifiers on Lynx.
|
|
88
|
+
*
|
|
89
|
+
* A plain class reads the complete color, as it always has:
|
|
90
|
+
* `bg-primary` → `background-color: var(--primary)`. A modifier reads the
|
|
91
|
+
* color's channels from its `-rgb` twin:
|
|
92
|
+
* `bg-primary/50` → `background-color: rgba(var(--primary-rgb), 0.5)`.
|
|
93
|
+
*
|
|
94
|
+
* Lynx substitutes `var()` as text before it parses the value, so with
|
|
95
|
+
* `--primary-rgb: 24, 24, 27` its color parser sees `rgba(24, 24, 27, 0.5)`
|
|
96
|
+
* (`CSSValue::Substitution` in lynx-family/lynx). The channels are
|
|
97
|
+
* comma-separated because every Lynx color parser takes `rgba()` in that
|
|
98
|
+
* form. Lynx takes `hsl()` only with commas, which is why the shadcn/ui form,
|
|
99
|
+
* `hsl(var(--x) / 0.5)`, draws nothing.
|
|
100
|
+
*
|
|
101
|
+
* Plain classes stay on `var(--x)` so they don't need the channels: with a
|
|
102
|
+
* theme copied before the `-rgb` variables existed, every plain class still
|
|
103
|
+
* draws, and only modifiers don't. Tailwind's `<alpha-value>` placeholder
|
|
104
|
+
* can't do that, as it puts the channels in plain classes too. An alpha of 1
|
|
105
|
+
* is the plain color, so `bg-primary/100` and `theme('colors.primary')` read
|
|
106
|
+
* `var(--primary)` as well.
|
|
107
|
+
*/
|
|
108
|
+
export const themeColor =
|
|
109
|
+
(name: string) =>
|
|
110
|
+
({ opacityValue, opacityVariable }: ColorOptions = {}): string =>
|
|
111
|
+
opacityValue === undefined ||
|
|
112
|
+
opacityVariable !== undefined ||
|
|
113
|
+
String(opacityValue) === '1'
|
|
114
|
+
? `var(--${name})`
|
|
115
|
+
: `rgba(var(--${name}-rgb), ${opacityValue})`;
|
|
116
|
+
|
|
72
117
|
/**
|
|
73
118
|
* Tailwind plugin that maps @blotch/ui CSS variables to semantic color utilities
|
|
74
119
|
* and registers safe-area-aware padding utilities.
|
|
@@ -86,10 +131,9 @@ export const addSafeAreaUtilities = ({
|
|
|
86
131
|
* referencing them directly avoids color-function parsing entirely. This matches
|
|
87
132
|
* the official React Lynx Tailwind example.
|
|
88
133
|
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
* `--destructive-subtle` → `destructive.subtle`) or use `opacity-*` on the element.
|
|
134
|
+
* Opacity modifiers (`bg-primary/50`, `text-foreground/70`,
|
|
135
|
+
* `border-border/60`) read each color's `--x-rgb` channels instead; see
|
|
136
|
+
* `themeColor`.
|
|
93
137
|
*
|
|
94
138
|
* Safe area: see `addSafeAreaUtilities` for the `*-safe` / `*-safe-<n>` padding
|
|
95
139
|
* utilities that keep content clear of notches and home indicators.
|
|
@@ -106,40 +150,69 @@ export const blotchPlugin = plugin(
|
|
|
106
150
|
{
|
|
107
151
|
theme: {
|
|
108
152
|
extend: {
|
|
153
|
+
// Tailwind's types only allow strings here, but it also takes a
|
|
154
|
+
// function, which it calls with the modifier's alpha: that's how it
|
|
155
|
+
// applies `<alpha-value>` itself. Every color but destructive.subtle
|
|
156
|
+
// and glass.dim, which are translucent already, has an `--x-rgb` twin
|
|
157
|
+
// in the theme, so takes opacity modifiers.
|
|
109
158
|
colors: {
|
|
110
|
-
background: '
|
|
111
|
-
foreground: '
|
|
159
|
+
background: themeColor('background'),
|
|
160
|
+
foreground: themeColor('foreground'),
|
|
112
161
|
primary: {
|
|
113
|
-
DEFAULT: '
|
|
114
|
-
foreground: '
|
|
162
|
+
DEFAULT: themeColor('primary'),
|
|
163
|
+
foreground: themeColor('primary-foreground'),
|
|
115
164
|
},
|
|
116
165
|
secondary: {
|
|
117
|
-
DEFAULT: '
|
|
118
|
-
foreground: '
|
|
166
|
+
DEFAULT: themeColor('secondary'),
|
|
167
|
+
foreground: themeColor('secondary-foreground'),
|
|
119
168
|
},
|
|
120
169
|
muted: {
|
|
121
|
-
DEFAULT: '
|
|
122
|
-
foreground: '
|
|
170
|
+
DEFAULT: themeColor('muted'),
|
|
171
|
+
foreground: themeColor('muted-foreground'),
|
|
123
172
|
},
|
|
124
173
|
accent: {
|
|
125
|
-
DEFAULT: '
|
|
126
|
-
foreground: '
|
|
174
|
+
DEFAULT: themeColor('accent'),
|
|
175
|
+
foreground: themeColor('accent-foreground'),
|
|
127
176
|
},
|
|
128
177
|
destructive: {
|
|
129
|
-
DEFAULT: '
|
|
130
|
-
foreground: '
|
|
131
|
-
//
|
|
132
|
-
//
|
|
178
|
+
DEFAULT: themeColor('destructive'),
|
|
179
|
+
foreground: themeColor('destructive-foreground'),
|
|
180
|
+
// Red at 10%, the destructive alert's background. It's
|
|
181
|
+
// translucent already, so it has no channels and takes no
|
|
182
|
+
// modifier. It predates modifiers and stays for the apps that
|
|
183
|
+
// use it: bg-destructive/10 draws the same color, but only in a
|
|
184
|
+
// theme that has --destructive-rgb.
|
|
133
185
|
subtle: 'var(--destructive-subtle)',
|
|
134
186
|
},
|
|
135
|
-
border: '
|
|
136
|
-
input: '
|
|
137
|
-
ring: '
|
|
187
|
+
border: themeColor('border'),
|
|
188
|
+
input: themeColor('input'),
|
|
189
|
+
ring: themeColor('ring'),
|
|
138
190
|
card: {
|
|
139
|
-
DEFAULT: '
|
|
140
|
-
foreground: '
|
|
191
|
+
DEFAULT: themeColor('card'),
|
|
192
|
+
foreground: themeColor('card-foreground'),
|
|
141
193
|
},
|
|
142
|
-
|
|
194
|
+
// Chart series colors, e.g. bg-chart-1 for a legend swatch that
|
|
195
|
+
// matches the first series.
|
|
196
|
+
chart: {
|
|
197
|
+
1: themeColor('chart-1'),
|
|
198
|
+
2: themeColor('chart-2'),
|
|
199
|
+
3: themeColor('chart-3'),
|
|
200
|
+
4: themeColor('chart-4'),
|
|
201
|
+
5: themeColor('chart-5'),
|
|
202
|
+
},
|
|
203
|
+
// What sits on Liquid Glass, and its tint: text-glass-foreground,
|
|
204
|
+
// bg-glass-tint, bg-glass-dim (see the glass component).
|
|
205
|
+
glass: {
|
|
206
|
+
tint: {
|
|
207
|
+
DEFAULT: themeColor('glass-tint'),
|
|
208
|
+
foreground: themeColor('glass-tint-foreground'),
|
|
209
|
+
},
|
|
210
|
+
foreground: themeColor('glass-foreground'),
|
|
211
|
+
'muted-foreground': themeColor('glass-muted-foreground'),
|
|
212
|
+
'clear-foreground': themeColor('glass-clear-foreground'),
|
|
213
|
+
dim: 'var(--glass-dim)',
|
|
214
|
+
},
|
|
215
|
+
} as unknown as Record<string, string>,
|
|
143
216
|
borderRadius: {
|
|
144
217
|
lg: 'var(--radius)',
|
|
145
218
|
md: 'calc(var(--radius) - 2px)',
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @blotch/ui theme for Tailwind CSS 4: what tailwind-plugin.ts does for
|
|
3
|
+
* Tailwind 3, written the CSS-first way. Import it after Tailwind, with
|
|
4
|
+
* default.css (and dark.css) for the colors themselves:
|
|
5
|
+
*
|
|
6
|
+
* @import './styles/default.css';
|
|
7
|
+
* @import './styles/tailwind.css';
|
|
8
|
+
*
|
|
9
|
+
* The semantic colors (bg-primary, text-muted-foreground, border-border)
|
|
10
|
+
* read the theme's variables directly, `inline` so the utilities write
|
|
11
|
+
* `var(--primary)` rather than a Tailwind variable that points at it. That
|
|
12
|
+
* keeps them switching with dark.css. An opacity modifier (bg-primary/50) is
|
|
13
|
+
* a color-mix() of that variable, which Lynx can't read; the build writes it
|
|
14
|
+
* as rgba(var(--primary-rgb), 0.5), from the channels default.css sets beside
|
|
15
|
+
* each color, as the Tailwind 3 plugin's themeColor() does.
|
|
16
|
+
*/
|
|
17
|
+
@theme inline {
|
|
18
|
+
--color-background: var(--background);
|
|
19
|
+
--color-foreground: var(--foreground);
|
|
20
|
+
--color-card: var(--card);
|
|
21
|
+
--color-card-foreground: var(--card-foreground);
|
|
22
|
+
--color-primary: var(--primary);
|
|
23
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
24
|
+
--color-secondary: var(--secondary);
|
|
25
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
26
|
+
--color-muted: var(--muted);
|
|
27
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
28
|
+
--color-accent: var(--accent);
|
|
29
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
30
|
+
--color-destructive: var(--destructive);
|
|
31
|
+
--color-destructive-foreground: var(--destructive-foreground);
|
|
32
|
+
/* Pre-composed translucent red for subtle destructive backgrounds. */
|
|
33
|
+
--color-destructive-subtle: var(--destructive-subtle);
|
|
34
|
+
--color-border: var(--border);
|
|
35
|
+
--color-input: var(--input);
|
|
36
|
+
--color-ring: var(--ring);
|
|
37
|
+
/* Chart series colors, e.g. bg-chart-1 for a legend swatch that matches
|
|
38
|
+
the first series. */
|
|
39
|
+
--color-chart-1: var(--chart-1);
|
|
40
|
+
--color-chart-2: var(--chart-2);
|
|
41
|
+
--color-chart-3: var(--chart-3);
|
|
42
|
+
--color-chart-4: var(--chart-4);
|
|
43
|
+
--color-chart-5: var(--chart-5);
|
|
44
|
+
/* What sits on Liquid Glass, and its tint (see the glass component).
|
|
45
|
+
glass-dim is translucent already, so it takes no opacity modifier. */
|
|
46
|
+
--color-glass-tint: var(--glass-tint);
|
|
47
|
+
--color-glass-tint-foreground: var(--glass-tint-foreground);
|
|
48
|
+
--color-glass-foreground: var(--glass-foreground);
|
|
49
|
+
--color-glass-muted-foreground: var(--glass-muted-foreground);
|
|
50
|
+
--color-glass-clear-foreground: var(--glass-clear-foreground);
|
|
51
|
+
--color-glass-dim: var(--glass-dim);
|
|
52
|
+
|
|
53
|
+
--radius-lg: var(--radius);
|
|
54
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
55
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@layer base {
|
|
59
|
+
* {
|
|
60
|
+
border-color: var(--border);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/*
|
|
65
|
+
* Safe-area padding, driven by env(safe-area-inset-*), which Lynx parses as
|
|
66
|
+
* a length, inside calc() too. The insets are 0 until the host app sets
|
|
67
|
+
* them, so each utility falls back to plain padding (or none).
|
|
68
|
+
*
|
|
69
|
+
* Bare (pb-safe, px-safe, p-safe): padding equal to the inset.
|
|
70
|
+
* Offset (pb-safe-4, pt-safe-2): a spacing-scale value plus the inset, for an
|
|
71
|
+
* element that wants its own padding and must also clear the notch or the
|
|
72
|
+
* home indicator.
|
|
73
|
+
*/
|
|
74
|
+
@utility pt-safe {
|
|
75
|
+
padding-top: env(safe-area-inset-top);
|
|
76
|
+
}
|
|
77
|
+
@utility pr-safe {
|
|
78
|
+
padding-right: env(safe-area-inset-right);
|
|
79
|
+
}
|
|
80
|
+
@utility pb-safe {
|
|
81
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
82
|
+
}
|
|
83
|
+
@utility pl-safe {
|
|
84
|
+
padding-left: env(safe-area-inset-left);
|
|
85
|
+
}
|
|
86
|
+
@utility px-safe {
|
|
87
|
+
padding-left: env(safe-area-inset-left);
|
|
88
|
+
padding-right: env(safe-area-inset-right);
|
|
89
|
+
}
|
|
90
|
+
@utility py-safe {
|
|
91
|
+
padding-top: env(safe-area-inset-top);
|
|
92
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
93
|
+
}
|
|
94
|
+
@utility p-safe {
|
|
95
|
+
padding-top: env(safe-area-inset-top);
|
|
96
|
+
padding-right: env(safe-area-inset-right);
|
|
97
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
98
|
+
padding-left: env(safe-area-inset-left);
|
|
99
|
+
}
|
|
100
|
+
@utility pt-safe-* {
|
|
101
|
+
padding-top: calc(--spacing(--value(number)) + env(safe-area-inset-top));
|
|
102
|
+
}
|
|
103
|
+
@utility pr-safe-* {
|
|
104
|
+
padding-right: calc(--spacing(--value(number)) + env(safe-area-inset-right));
|
|
105
|
+
}
|
|
106
|
+
@utility pb-safe-* {
|
|
107
|
+
padding-bottom: calc(
|
|
108
|
+
--spacing(--value(number)) + env(safe-area-inset-bottom)
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
@utility pl-safe-* {
|
|
112
|
+
padding-left: calc(--spacing(--value(number)) + env(safe-area-inset-left));
|
|
113
|
+
}
|
|
@@ -28,8 +28,20 @@ import {
|
|
|
28
28
|
springTranslateX,
|
|
29
29
|
} from './animate';
|
|
30
30
|
|
|
31
|
+
// The keyframes and options the helpers hand `animate()`, typed with the
|
|
32
|
+
// fields the assertions read: the mock's calls are typed from its parameters.
|
|
33
|
+
type Keyframe = { transform?: string; opacity?: number };
|
|
34
|
+
type AnimateOptions = {
|
|
35
|
+
duration?: number;
|
|
36
|
+
easing?: string;
|
|
37
|
+
fill?: string;
|
|
38
|
+
iterations?: number;
|
|
39
|
+
};
|
|
40
|
+
|
|
31
41
|
const makeEl = () => ({
|
|
32
|
-
animate: vi.fn(() => ({
|
|
42
|
+
animate: vi.fn((_keyframes: Keyframe[], _options: AnimateOptions) => ({
|
|
43
|
+
cancel: vi.fn(),
|
|
44
|
+
})),
|
|
33
45
|
setStyle: vi.fn(),
|
|
34
46
|
});
|
|
35
47
|
|
package/dist/utils/analyze.d.ts
CHANGED
|
@@ -5,6 +5,11 @@ export type FileAnalysis = {
|
|
|
5
5
|
status: FileStatus;
|
|
6
6
|
currentContent: string;
|
|
7
7
|
newContent: string;
|
|
8
|
+
/**
|
|
9
|
+
* Upstream stopped shipping the file, so taking upstream's version deletes
|
|
10
|
+
* it (see analyzeRemovedFile). Its `newContent` is empty.
|
|
11
|
+
*/
|
|
12
|
+
removed?: boolean;
|
|
8
13
|
};
|
|
9
14
|
export type ComponentAnalysis = {
|
|
10
15
|
name: string;
|
|
@@ -24,6 +29,15 @@ export declare const STATUS_LABELS: Record<FileStatus, string>;
|
|
|
24
29
|
* so any difference is flagged as a conflict to be safe.
|
|
25
30
|
*/
|
|
26
31
|
export declare const analyzeFile: (currentContent: string | null, newContent: string, storedHash: string | null, hashContent: (content: string) => string) => FileStatus;
|
|
32
|
+
/**
|
|
33
|
+
* The status of a file dolan tracks but upstream no longer ships, such as the
|
|
34
|
+
* `*-render.test.ts` files that 22.2.3 stopped copying. Upstream's version of
|
|
35
|
+
* it is "no file", so the same three-way rules apply as for a changed file:
|
|
36
|
+
* - gone from disk too → up-to-date (only its lockfile entry is left)
|
|
37
|
+
* - current == base → auto-update (nobody edited it: delete it)
|
|
38
|
+
* - current != base → conflict (git's modify/delete: ask before deleting)
|
|
39
|
+
*/
|
|
40
|
+
export declare const analyzeRemovedFile: (currentContent: string | null, storedHash: string, hashContent: (content: string) => string) => FileStatus;
|
|
27
41
|
export declare const formatDiff: (currentContent: string, newContent: string) => string;
|
|
28
42
|
export declare const summarizeComponent: (analysis: ComponentAnalysis) => FileStatus;
|
|
29
43
|
export { type Hunk } from 'diff';
|
package/dist/utils/analyze.js
CHANGED
|
@@ -46,6 +46,21 @@ export const analyzeFile = (currentContent, newContent, storedHash, hashContent)
|
|
|
46
46
|
return 'user-modified';
|
|
47
47
|
return 'conflict';
|
|
48
48
|
};
|
|
49
|
+
/**
|
|
50
|
+
* The status of a file dolan tracks but upstream no longer ships, such as the
|
|
51
|
+
* `*-render.test.ts` files that 22.2.3 stopped copying. Upstream's version of
|
|
52
|
+
* it is "no file", so the same three-way rules apply as for a changed file:
|
|
53
|
+
* - gone from disk too → up-to-date (only its lockfile entry is left)
|
|
54
|
+
* - current == base → auto-update (nobody edited it: delete it)
|
|
55
|
+
* - current != base → conflict (git's modify/delete: ask before deleting)
|
|
56
|
+
*/
|
|
57
|
+
export const analyzeRemovedFile = (currentContent, storedHash, hashContent) => {
|
|
58
|
+
if (currentContent === null)
|
|
59
|
+
return 'up-to-date';
|
|
60
|
+
return hashContent(currentContent) === storedHash
|
|
61
|
+
? 'auto-update'
|
|
62
|
+
: 'conflict';
|
|
63
|
+
};
|
|
49
64
|
export const formatDiff = (currentContent, newContent) => {
|
|
50
65
|
const changes = diffLines(currentContent, newContent);
|
|
51
66
|
const lines = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/utils/analyze.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EACL,SAAS,EACT,eAAe,EACf,UAAU,GAGX,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/utils/analyze.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
|
-
import { analyzeFile, formatDiff, summarizeComponent } from './analyze';
|
|
3
|
+
import { analyzeFile, analyzeRemovedFile, formatDiff, summarizeComponent, } from './analyze';
|
|
4
4
|
const hash = (content) => createHash('sha256').update(content).digest('hex').slice(0, 16);
|
|
5
5
|
describe('analyzeFile', () => {
|
|
6
6
|
it('returns new-upstream when current content is null', () => {
|
|
@@ -33,6 +33,19 @@ describe('analyzeFile', () => {
|
|
|
33
33
|
expect(analyzeFile('user-edit', 'upstream-edit', stored, hash)).toBe('conflict');
|
|
34
34
|
});
|
|
35
35
|
});
|
|
36
|
+
// A file dolan tracks that upstream no longer ships: upstream's version is
|
|
37
|
+
// "no file".
|
|
38
|
+
describe('analyzeRemovedFile', () => {
|
|
39
|
+
it('returns up-to-date when the file is gone from disk too', () => {
|
|
40
|
+
expect(analyzeRemovedFile(null, hash('copied'), hash)).toBe('up-to-date');
|
|
41
|
+
});
|
|
42
|
+
it('returns auto-update when nobody edited it, so it can just go', () => {
|
|
43
|
+
expect(analyzeRemovedFile('copied', hash('copied'), hash)).toBe('auto-update');
|
|
44
|
+
});
|
|
45
|
+
it('returns conflict when it was edited, so deleting it needs a yes', () => {
|
|
46
|
+
expect(analyzeRemovedFile('edited', hash('copied'), hash)).toBe('conflict');
|
|
47
|
+
});
|
|
48
|
+
});
|
|
36
49
|
describe('summarizeComponent', () => {
|
|
37
50
|
it('returns up-to-date when all files are up-to-date', () => {
|
|
38
51
|
const result = summarizeComponent({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyze.test.js","sourceRoot":"","sources":["../../src/utils/analyze.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,
|
|
1
|
+
{"version":3,"file":"analyze.test.js","sourceRoot":"","sources":["../../src/utils/analyze.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Lockfile } from '../lockfile.js';
|
|
2
|
+
/**
|
|
3
|
+
* The registry components with a folder in the components directory. Other
|
|
4
|
+
* folders (the app's own code next to the components) aren't dolan's.
|
|
5
|
+
*/
|
|
6
|
+
export declare const componentsOnDisk: (componentsDir: string) => string[];
|
|
7
|
+
/**
|
|
8
|
+
* The installed components dolan tracks: on disk and in the lockfile. `add`
|
|
9
|
+
* records every component it copies, and `eject` removes the record to hand
|
|
10
|
+
* the component over to the app, so a folder without one is the app's own
|
|
11
|
+
* code. `update`, `list`, `diff` and `outdated` leave it alone: before, they
|
|
12
|
+
* scanned the folders, so an ejected component showed as a conflict,
|
|
13
|
+
* `update --force` overwrote it and `update` tracked it again.
|
|
14
|
+
*/
|
|
15
|
+
export declare const trackedComponents: (componentsDir: string, lockfile: Lockfile) => string[];
|
|
16
|
+
/** The components on disk that dolan doesn't track (see trackedComponents). */
|
|
17
|
+
export declare const untrackedComponents: (componentsDir: string, lockfile: Lockfile) => string[];
|
|
18
|
+
/**
|
|
19
|
+
* The files dolan tracks for a component that upstream no longer ships, such
|
|
20
|
+
* as the `*-render.test.ts` files that 22.2.3 stopped copying. `update` and
|
|
21
|
+
* `add` used to keep their lockfile entries and leave them on disk, where a
|
|
22
|
+
* stale spec importing a helper dolan doesn't copy broke the app's `ng test`.
|
|
23
|
+
*
|
|
24
|
+
* Shipped means shipped with tests: a project without the testing library
|
|
25
|
+
* doesn't get the components' `<name>.test.ts`, but upstream still ships it,
|
|
26
|
+
* so a copy from before dolan checked for the library isn't deleted here
|
|
27
|
+
* (`doctor` warns about those instead).
|
|
28
|
+
*/
|
|
29
|
+
export declare const droppedFiles: (name: string, lockfile: Lockfile) => string[];
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { getComponentNames } from '../registry.js';
|
|
3
|
+
import { getComponentFiles } from './resolve-paths.js';
|
|
4
|
+
/**
|
|
5
|
+
* The registry components with a folder in the components directory. Other
|
|
6
|
+
* folders (the app's own code next to the components) aren't dolan's.
|
|
7
|
+
*/
|
|
8
|
+
export const componentsOnDisk = (componentsDir) => {
|
|
9
|
+
if (!existsSync(componentsDir))
|
|
10
|
+
return [];
|
|
11
|
+
const known = new Set(getComponentNames());
|
|
12
|
+
return readdirSync(componentsDir, { withFileTypes: true })
|
|
13
|
+
.filter((entry) => entry.isDirectory() && known.has(entry.name))
|
|
14
|
+
.map((entry) => entry.name)
|
|
15
|
+
.sort();
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* The installed components dolan tracks: on disk and in the lockfile. `add`
|
|
19
|
+
* records every component it copies, and `eject` removes the record to hand
|
|
20
|
+
* the component over to the app, so a folder without one is the app's own
|
|
21
|
+
* code. `update`, `list`, `diff` and `outdated` leave it alone: before, they
|
|
22
|
+
* scanned the folders, so an ejected component showed as a conflict,
|
|
23
|
+
* `update --force` overwrote it and `update` tracked it again.
|
|
24
|
+
*/
|
|
25
|
+
export const trackedComponents = (componentsDir, lockfile) => componentsOnDisk(componentsDir).filter((name) => lockfile.components[name]);
|
|
26
|
+
/** The components on disk that dolan doesn't track (see trackedComponents). */
|
|
27
|
+
export const untrackedComponents = (componentsDir, lockfile) => componentsOnDisk(componentsDir).filter((name) => !lockfile.components[name]);
|
|
28
|
+
/**
|
|
29
|
+
* The files dolan tracks for a component that upstream no longer ships, such
|
|
30
|
+
* as the `*-render.test.ts` files that 22.2.3 stopped copying. `update` and
|
|
31
|
+
* `add` used to keep their lockfile entries and leave them on disk, where a
|
|
32
|
+
* stale spec importing a helper dolan doesn't copy broke the app's `ng test`.
|
|
33
|
+
*
|
|
34
|
+
* Shipped means shipped with tests: a project without the testing library
|
|
35
|
+
* doesn't get the components' `<name>.test.ts`, but upstream still ships it,
|
|
36
|
+
* so a copy from before dolan checked for the library isn't deleted here
|
|
37
|
+
* (`doctor` warns about those instead).
|
|
38
|
+
*/
|
|
39
|
+
export const droppedFiles = (name, lockfile) => {
|
|
40
|
+
const shipped = new Set(getComponentFiles(name, { tests: true }));
|
|
41
|
+
return Object.keys(lockfile.components[name] ?? {}).filter((file) => !shipped.has(file));
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=installed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installed.js","sourceRoot":"","sources":["../../src/utils/installed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,aAAqB,EAAY,EAAE;IAClE,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;QAAE,OAAO,EAAE,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAC3C,OAAO,WAAW,CAAC,aAAa,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;SACvD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;SAC/D,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;SAC1B,IAAI,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,aAAqB,EACrB,QAAkB,EACR,EAAE,CACZ,gBAAgB,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;AAE9E,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,aAAqB,EACrB,QAAkB,EACR,EAAE,CACZ,gBAAgB,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;AAE/E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,QAAkB,EAAY,EAAE;IACzE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAClE,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CACxD,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAC7B,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
5
|
+
import { createEmptyLockfile } from '../lockfile';
|
|
6
|
+
import { componentsOnDisk, droppedFiles, trackedComponents, untrackedComponents, } from './installed';
|
|
7
|
+
let root;
|
|
8
|
+
const componentsDir = (...folders) => {
|
|
9
|
+
root = mkdtempSync(join(tmpdir(), 'dolan-installed-'));
|
|
10
|
+
for (const folder of folders)
|
|
11
|
+
mkdirSync(join(root, folder));
|
|
12
|
+
// A file isn't a component, whatever its name.
|
|
13
|
+
writeFileSync(join(root, 'badge'), '');
|
|
14
|
+
return root;
|
|
15
|
+
};
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
if (root)
|
|
18
|
+
rmSync(root, { recursive: true, force: true });
|
|
19
|
+
});
|
|
20
|
+
describe('componentsOnDisk', () => {
|
|
21
|
+
it('lists the registry components with a folder, sorted', () => {
|
|
22
|
+
const dir = componentsDir('spinner', 'card', 'my-own-thing');
|
|
23
|
+
expect(componentsOnDisk(dir)).toEqual(['card', 'spinner']);
|
|
24
|
+
});
|
|
25
|
+
it('is empty when the directory is missing', () => {
|
|
26
|
+
expect(componentsOnDisk(join(tmpdir(), 'dolan-missing-dir'))).toEqual([]);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
describe('trackedComponents / untrackedComponents', () => {
|
|
30
|
+
it('splits the components on disk by their lockfile entry', () => {
|
|
31
|
+
const dir = componentsDir('card', 'spinner', 'button');
|
|
32
|
+
const lockfile = createEmptyLockfile();
|
|
33
|
+
lockfile.components['card'] = {};
|
|
34
|
+
lockfile.components['button'] = {};
|
|
35
|
+
// In the lockfile but not on disk: removed by hand, so neither.
|
|
36
|
+
lockfile.components['dialog'] = {};
|
|
37
|
+
expect(trackedComponents(dir, lockfile)).toEqual(['button', 'card']);
|
|
38
|
+
expect(untrackedComponents(dir, lockfile)).toEqual(['spinner']);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
// Reads the real registry source that the test config copies into dist/ui.
|
|
42
|
+
describe('droppedFiles', () => {
|
|
43
|
+
it("lists the tracked files that upstream doesn't ship", () => {
|
|
44
|
+
const lockfile = createEmptyLockfile();
|
|
45
|
+
lockfile.components['button'] = {
|
|
46
|
+
'button.ts': { hash: 'a' },
|
|
47
|
+
'button-old.ts': { hash: 'b' },
|
|
48
|
+
// Shipped, though only a project with the testing library gets it.
|
|
49
|
+
'button.test.ts': { hash: 'c' },
|
|
50
|
+
};
|
|
51
|
+
expect(droppedFiles('button', lockfile)).toEqual(['button-old.ts']);
|
|
52
|
+
});
|
|
53
|
+
it('is empty for a component the lockfile has no entry for', () => {
|
|
54
|
+
expect(droppedFiles('button', createEmptyLockfile())).toEqual([]);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=installed.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installed.test.js","sourceRoot":"","sources":["../../src/utils/installed.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether anyone can answer a question: stdin is a terminal. In CI, a script
|
|
3
|
+
* or an AI agent it isn't, and clack's prompts wait for input that never
|
|
4
|
+
* comes. The commands used to hang there until stdin closed, then exit 0
|
|
5
|
+
* having done nothing. Without a terminal, each command asks nothing and takes
|
|
6
|
+
* each question's default instead, or exits 1 and names the option to pass
|
|
7
|
+
* when that default would cancel the run.
|
|
8
|
+
*/
|
|
9
|
+
export declare const isInteractive: () => boolean;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether anyone can answer a question: stdin is a terminal. In CI, a script
|
|
3
|
+
* or an AI agent it isn't, and clack's prompts wait for input that never
|
|
4
|
+
* comes. The commands used to hang there until stdin closed, then exit 0
|
|
5
|
+
* having done nothing. Without a terminal, each command asks nothing and takes
|
|
6
|
+
* each question's default instead, or exits 1 and names the option to pass
|
|
7
|
+
* when that default would cancel the run.
|
|
8
|
+
*/
|
|
9
|
+
export const isInteractive = () => process.stdin.isTTY === true;
|
|
10
|
+
//# sourceMappingURL=interactive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.js","sourceRoot":"","sources":["../../src/utils/interactive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAY,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
|
2
|
+
import { isInteractive } from './interactive';
|
|
3
|
+
const isTTY = Object.getOwnPropertyDescriptor(process.stdin, 'isTTY');
|
|
4
|
+
const setIsTTY = (value) => Object.defineProperty(process.stdin, 'isTTY', { value, configurable: true });
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
if (isTTY)
|
|
7
|
+
Object.defineProperty(process.stdin, 'isTTY', isTTY);
|
|
8
|
+
else
|
|
9
|
+
delete process.stdin.isTTY;
|
|
10
|
+
});
|
|
11
|
+
describe('isInteractive', () => {
|
|
12
|
+
it('is true when stdin is a terminal', () => {
|
|
13
|
+
setIsTTY(true);
|
|
14
|
+
expect(isInteractive()).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
it('is false when stdin is a pipe or a file', () => {
|
|
17
|
+
// Node leaves `isTTY` undefined on anything but a terminal.
|
|
18
|
+
setIsTTY(undefined);
|
|
19
|
+
expect(isInteractive()).toBe(false);
|
|
20
|
+
setIsTTY(false);
|
|
21
|
+
expect(isInteractive()).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
//# sourceMappingURL=interactive.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.test.js","sourceRoot":"","sources":["../../src/utils/interactive.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,KAAK,GAAG,MAAM,CAAC,wBAAwB,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AACtE,MAAM,QAAQ,GAAG,CAAC,KAA0B,EAAE,EAAE,CAC9C,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;AAE/E,SAAS,CAAC,GAAG,EAAE;IACb,IAAI,KAAK;QAAE,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;;QAC3D,OAAQ,OAAO,CAAC,KAA6B,CAAC,KAAK,CAAC;AAC3D,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,4DAA4D;QAC5D,QAAQ,CAAC,SAAS,CAAC,CAAC;QACpB,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChB,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|