@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.
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,365 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { fadeIn, fadeOut, scaleIn, scaleOut, slideIn, slideOut, popIn, popOut, pulse, shake, springTranslateX, revealIn, directionalSlideIn, overlayOpen, overlayClose, pressDown, pressRelease, DURATION, EASING, SCALE, } from './animate';
3
+ /**
4
+ * The real Lynx element only needs an `animate()` method for the wrapper
5
+ * helpers below — everything else about the element is irrelevant to them.
6
+ * The mock returns a cancelable handle (mirroring the real API) so callers
7
+ * that store/inspect the return value have something realistic to work with.
8
+ */
9
+ const createAnimateEl = () => ({
10
+ animate: vi.fn().mockReturnValue({ cancel: vi.fn() }),
11
+ });
12
+ const guardedCases = [
13
+ {
14
+ name: 'fadeIn',
15
+ call: fadeIn,
16
+ overrideOptions: { duration: 999, easing: 'linear', fill: 'both' },
17
+ expectedConfig: { duration: 999, easing: 'linear', fill: 'both' },
18
+ defaultConfig: {
19
+ duration: DURATION.normal,
20
+ easing: EASING.decelerate,
21
+ fill: 'forwards',
22
+ },
23
+ },
24
+ {
25
+ name: 'fadeOut',
26
+ call: fadeOut,
27
+ overrideOptions: { duration: 999, easing: 'linear', fill: 'both' },
28
+ expectedConfig: { duration: 999, easing: 'linear', fill: 'both' },
29
+ defaultConfig: {
30
+ duration: DURATION.fast,
31
+ easing: EASING.accelerate,
32
+ fill: 'forwards',
33
+ },
34
+ },
35
+ {
36
+ name: 'scaleIn',
37
+ call: scaleIn,
38
+ overrideOptions: {
39
+ duration: 999,
40
+ easing: 'linear',
41
+ fill: 'both',
42
+ fromScale: 0.5,
43
+ fromY: 40,
44
+ },
45
+ expectedConfig: { duration: 999, easing: 'linear', fill: 'both' },
46
+ defaultConfig: {
47
+ duration: DURATION.slow,
48
+ easing: EASING.springSubtle,
49
+ fill: 'forwards',
50
+ },
51
+ },
52
+ {
53
+ name: 'scaleOut',
54
+ call: scaleOut,
55
+ overrideOptions: {
56
+ duration: 999,
57
+ easing: 'linear',
58
+ fill: 'both',
59
+ toScale: 0.5,
60
+ toY: 40,
61
+ },
62
+ expectedConfig: { duration: 999, easing: 'linear', fill: 'both' },
63
+ defaultConfig: {
64
+ duration: DURATION.fast,
65
+ easing: EASING.accelerate,
66
+ fill: 'forwards',
67
+ },
68
+ },
69
+ {
70
+ name: 'popIn',
71
+ call: popIn,
72
+ overrideOptions: {
73
+ duration: 999,
74
+ easing: 'linear',
75
+ fill: 'both',
76
+ fromScale: 0.2,
77
+ },
78
+ expectedConfig: { duration: 999, easing: 'linear', fill: 'both' },
79
+ defaultConfig: {
80
+ duration: DURATION.fast,
81
+ easing: EASING.spring,
82
+ fill: 'forwards',
83
+ },
84
+ },
85
+ {
86
+ name: 'popOut',
87
+ call: popOut,
88
+ overrideOptions: {
89
+ duration: 999,
90
+ easing: 'linear',
91
+ fill: 'both',
92
+ toScale: 0.2,
93
+ },
94
+ expectedConfig: { duration: 999, easing: 'linear', fill: 'both' },
95
+ defaultConfig: {
96
+ duration: DURATION.instant,
97
+ easing: EASING.accelerate,
98
+ fill: 'forwards',
99
+ },
100
+ },
101
+ {
102
+ name: 'springTranslateX',
103
+ // fromX/toX are required positional args unrelated to `options`; pin
104
+ // them to fixed values so only the options behavior varies per case.
105
+ call: (el, options) => springTranslateX(el, 0, 100, options),
106
+ overrideOptions: { duration: 999, easing: 'linear', fill: 'both' },
107
+ expectedConfig: { duration: 999, easing: 'linear', fill: 'both' },
108
+ defaultConfig: { duration: 200, easing: EASING.spring, fill: 'forwards' },
109
+ },
110
+ {
111
+ name: 'revealIn',
112
+ call: revealIn,
113
+ overrideOptions: {
114
+ duration: 999,
115
+ easing: 'linear',
116
+ fill: 'both',
117
+ fromY: 40,
118
+ },
119
+ expectedConfig: { duration: 999, easing: 'linear', fill: 'both' },
120
+ defaultConfig: {
121
+ duration: DURATION.normal,
122
+ easing: EASING.decelerate,
123
+ fill: 'forwards',
124
+ },
125
+ },
126
+ {
127
+ name: 'directionalSlideIn',
128
+ call: (el, options) => directionalSlideIn(el, 1, options),
129
+ overrideOptions: {
130
+ duration: 999,
131
+ easing: 'linear',
132
+ fill: 'both',
133
+ distance: 50,
134
+ },
135
+ expectedConfig: { duration: 999, easing: 'linear', fill: 'both' },
136
+ defaultConfig: {
137
+ duration: DURATION.slow,
138
+ easing: EASING.springSubtle,
139
+ fill: 'forwards',
140
+ },
141
+ },
142
+ ];
143
+ describe.each(guardedCases)('$name', ({ call, overrideOptions, expectedConfig, defaultConfig }) => {
144
+ it('returns undefined and does not throw when el is falsy', () => {
145
+ expect(call(undefined)).toBeUndefined();
146
+ });
147
+ it('calls el.animate() with default values when no options are given', () => {
148
+ const el = createAnimateEl();
149
+ call(el);
150
+ expect(el.animate).toHaveBeenCalledTimes(1);
151
+ // Second arg to el.animate() is always the { duration, easing, fill }
152
+ // config object — checking it confirms every `?? DEFAULT` fired.
153
+ expect(el.animate.mock.calls[0][1]).toEqual(defaultConfig);
154
+ });
155
+ it('calls el.animate() with the provided options overriding every default', () => {
156
+ const el = createAnimateEl();
157
+ call(el, overrideOptions);
158
+ expect(el.animate).toHaveBeenCalledTimes(1);
159
+ expect(el.animate.mock.calls[0][1]).toEqual(expectedConfig);
160
+ });
161
+ });
162
+ // ---------------------------------------------------------------------------
163
+ // pulse — shares the "guarded" shape but its options type only has
164
+ // `duration` (no easing/fill), and the config includes a fixed `iterations:
165
+ // Infinity` for the indefinite loop, so it doesn't fit the generic table.
166
+ // ---------------------------------------------------------------------------
167
+ describe('pulse', () => {
168
+ it('returns undefined when el is falsy', () => {
169
+ expect(pulse(undefined)).toBeUndefined();
170
+ });
171
+ it('defaults to a 1500ms ease-in-out loop', () => {
172
+ const el = createAnimateEl();
173
+ pulse(el);
174
+ expect(el.animate.mock.calls[0][1]).toEqual({
175
+ duration: 1500,
176
+ easing: 'ease-in-out',
177
+ iterations: Infinity,
178
+ });
179
+ });
180
+ it('honors an explicit duration', () => {
181
+ const el = createAnimateEl();
182
+ pulse(el, { duration: 3000 });
183
+ expect(el.animate.mock.calls[0][1]).toEqual({
184
+ duration: 3000,
185
+ easing: 'ease-in-out',
186
+ iterations: Infinity,
187
+ });
188
+ });
189
+ });
190
+ // ---------------------------------------------------------------------------
191
+ // shake — also "guarded", but `fill` is hardcoded to 'forwards' rather than
192
+ // read from options, so there is no `?? ` branch for it (unlike every other
193
+ // AnimateOptions consumer). Passing `fill: 'both'` below is deliberate: it
194
+ // proves the value is ignored rather than accidentally leaking through.
195
+ // ---------------------------------------------------------------------------
196
+ describe('shake', () => {
197
+ it('returns undefined when el is falsy', () => {
198
+ expect(shake(undefined)).toBeUndefined();
199
+ });
200
+ it('defaults duration and easing', () => {
201
+ const el = createAnimateEl();
202
+ shake(el);
203
+ expect(el.animate.mock.calls[0][1]).toEqual({
204
+ duration: DURATION.slow,
205
+ easing: EASING.standard,
206
+ fill: 'forwards',
207
+ });
208
+ });
209
+ it('honors explicit duration/easing but always fills forwards', () => {
210
+ const el = createAnimateEl();
211
+ shake(el, { duration: 999, easing: 'linear', fill: 'both' });
212
+ expect(el.animate.mock.calls[0][1]).toEqual({
213
+ duration: 999,
214
+ easing: 'linear',
215
+ fill: 'forwards',
216
+ });
217
+ });
218
+ });
219
+ // ---------------------------------------------------------------------------
220
+ // slideIn / slideOut — guarded like the table above, but the direction is
221
+ // resolved via an object-literal lookup (`{ up: ..., down: ... }[direction]`)
222
+ // rather than an if/else, so a single direction is enough for branch
223
+ // coverage. All four are still exercised for behavioral thoroughness since
224
+ // each call is cheap and documents the intended keyframes per direction.
225
+ // ---------------------------------------------------------------------------
226
+ describe('slideIn', () => {
227
+ it('returns undefined when el is falsy', () => {
228
+ expect(slideIn(undefined, 'up')).toBeUndefined();
229
+ });
230
+ it.each(['up', 'down', 'left', 'right'])('animates the %s direction with default options', (direction) => {
231
+ const el = createAnimateEl();
232
+ slideIn(el, direction);
233
+ expect(el.animate).toHaveBeenCalledTimes(1);
234
+ expect(el.animate.mock.calls[0][1]).toEqual({
235
+ duration: DURATION.slow,
236
+ easing: EASING.sheet,
237
+ fill: 'forwards',
238
+ });
239
+ });
240
+ it('honors explicit options', () => {
241
+ const el = createAnimateEl();
242
+ slideIn(el, 'left', { duration: 999, easing: 'linear', fill: 'both' });
243
+ expect(el.animate.mock.calls[0][1]).toEqual({
244
+ duration: 999,
245
+ easing: 'linear',
246
+ fill: 'both',
247
+ });
248
+ });
249
+ });
250
+ describe('slideOut', () => {
251
+ it('returns undefined when el is falsy', () => {
252
+ expect(slideOut(undefined, 'up')).toBeUndefined();
253
+ });
254
+ it.each(['up', 'down', 'left', 'right'])('animates the %s direction with default options', (direction) => {
255
+ const el = createAnimateEl();
256
+ slideOut(el, direction);
257
+ expect(el.animate).toHaveBeenCalledTimes(1);
258
+ expect(el.animate.mock.calls[0][1]).toEqual({
259
+ duration: DURATION.normal,
260
+ easing: EASING.accelerate,
261
+ fill: 'forwards',
262
+ });
263
+ });
264
+ it('honors explicit options', () => {
265
+ const el = createAnimateEl();
266
+ slideOut(el, 'right', { duration: 999, easing: 'linear', fill: 'both' });
267
+ expect(el.animate.mock.calls[0][1]).toEqual({
268
+ duration: 999,
269
+ easing: 'linear',
270
+ fill: 'both',
271
+ });
272
+ });
273
+ });
274
+ // ---------------------------------------------------------------------------
275
+ // overlayOpen / overlayClose — real if/else-if/else branches per `type`
276
+ // (unlike the object-literal lookups above), so all four values must be
277
+ // exercised to hit every branch.
278
+ // ---------------------------------------------------------------------------
279
+ describe('overlayOpen', () => {
280
+ beforeEach(() => {
281
+ vi.useFakeTimers();
282
+ });
283
+ afterEach(() => {
284
+ vi.useRealTimers();
285
+ });
286
+ it.each(['center', 'bottom', 'left', 'right'])('schedules the panel animation for type=%s after the 30ms stagger', (type) => {
287
+ const backdrop = createAnimateEl();
288
+ const panel = createAnimateEl();
289
+ const result = overlayOpen(backdrop, panel, type);
290
+ // Backdrop fades in synchronously, before the stagger.
291
+ expect(backdrop.animate).toHaveBeenCalledTimes(1);
292
+ expect(result.backdrop).toBeDefined();
293
+ // Panel animation is deferred behind setTimeout(..., 30) — it must not
294
+ // have run yet, which is what makes this the branch under test rather
295
+ // than a duplicate of the scaleIn/slideIn unit tests above.
296
+ expect(panel.animate).not.toHaveBeenCalled();
297
+ vi.advanceTimersByTime(30);
298
+ // Firing the timer exercises the matching if/else-if/else arm for
299
+ // `type` inside the callback (scaleIn for 'center', slideIn otherwise).
300
+ expect(panel.animate).toHaveBeenCalledTimes(1);
301
+ });
302
+ });
303
+ describe('overlayClose', () => {
304
+ const cases = [
305
+ ['center', 180],
306
+ ['bottom', DURATION.normal],
307
+ ['left', DURATION.normal],
308
+ ['right', DURATION.normal],
309
+ ];
310
+ it.each(cases)('animates type=%s and returns duration %i', (type, expectedDuration) => {
311
+ const backdrop = createAnimateEl();
312
+ const panel = createAnimateEl();
313
+ const duration = overlayClose(backdrop, panel, type);
314
+ // Panel exit animation and backdrop fade both run synchronously.
315
+ expect(panel.animate).toHaveBeenCalledTimes(1);
316
+ expect(backdrop.animate).toHaveBeenCalledTimes(1);
317
+ expect(duration).toBe(expectedDuration);
318
+ });
319
+ });
320
+ // ---------------------------------------------------------------------------
321
+ // pressDown / pressRelease (transitionTransform)
322
+ //
323
+ // transitionTransform is private, so it's only reachable through these two
324
+ // exports. It guards with `el?.setStyle`, which is a distinct branch from a
325
+ // plain `!el` check: it also returns undefined for a truthy object missing
326
+ // `setStyle`, not just for a nullish `el`.
327
+ // ---------------------------------------------------------------------------
328
+ describe('pressDown / pressRelease', () => {
329
+ it('pressDown returns undefined when el is undefined', () => {
330
+ expect(pressDown(undefined)).toBeUndefined();
331
+ });
332
+ it('pressRelease returns undefined when el is undefined', () => {
333
+ expect(pressRelease(undefined)).toBeUndefined();
334
+ });
335
+ it('pressDown returns undefined when el has no setStyle', () => {
336
+ // A truthy object with no setStyle exercises the `?.` short-circuit
337
+ // itself, as opposed to the `el` being nullish outright above.
338
+ expect(pressDown({})).toBeUndefined();
339
+ });
340
+ it('pressRelease returns undefined when el has no setStyle', () => {
341
+ expect(pressRelease({})).toBeUndefined();
342
+ });
343
+ it('pressDown applies the default press-down scale', () => {
344
+ const el = { setStyle: vi.fn() };
345
+ const handle = pressDown(el);
346
+ expect(el.setStyle).toHaveBeenNthCalledWith(1, 'transition', `transform ${DURATION.instant}ms ${EASING.standard}`);
347
+ expect(el.setStyle).toHaveBeenNthCalledWith(2, 'transform', `scale(${SCALE.pressDown})`);
348
+ // cancel() is a real (if intentionally empty) function body — invoke it
349
+ // so it registers for function coverage, not just declaration coverage.
350
+ expect(() => handle?.cancel()).not.toThrow();
351
+ });
352
+ it('pressDown accepts an explicit scale overriding the default', () => {
353
+ const el = { setStyle: vi.fn() };
354
+ pressDown(el, 0.5);
355
+ expect(el.setStyle).toHaveBeenNthCalledWith(2, 'transform', 'scale(0.5)');
356
+ });
357
+ it('pressRelease transitions back to full scale with spring easing', () => {
358
+ const el = { setStyle: vi.fn() };
359
+ const handle = pressRelease(el);
360
+ expect(el.setStyle).toHaveBeenNthCalledWith(1, 'transition', `transform ${DURATION.fast}ms ${EASING.spring}`);
361
+ expect(el.setStyle).toHaveBeenNthCalledWith(2, 'transform', 'scale(1)');
362
+ handle?.cancel();
363
+ });
364
+ });
365
+ //# sourceMappingURL=animate.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animate.test.js","sourceRoot":"","sources":["../../src/utils/animate.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare const printBanner: () => void;
@@ -0,0 +1,15 @@
1
+ import cfonts from 'cfonts';
2
+ import pc from 'picocolors';
3
+ export const printBanner = () => {
4
+ const rendered = cfonts.render('dolan', {
5
+ font: 'block',
6
+ colors: ['cyan', 'blue'],
7
+ space: false,
8
+ });
9
+ if (rendered) {
10
+ console.log(rendered.string);
11
+ }
12
+ console.log(pc.dim(' UI components for AngularLynx'));
13
+ console.log();
14
+ };
15
+ //# sourceMappingURL=banner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"banner.js","sourceRoot":"","sources":["../../src/utils/banner.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,CAAC,MAAM,WAAW,GAAG,GAAS,EAAE;IACpC,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE;QACtC,IAAI,EAAE,OAAO;QACb,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,KAAK,EAAE,KAAK;KACb,CAAC,CAAC;IAEH,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,29 @@
1
+ import { describe, it, expect, vi, afterEach } from 'vitest';
2
+ import cfonts from 'cfonts';
3
+ import { printBanner } from './banner';
4
+ describe('printBanner', () => {
5
+ afterEach(() => {
6
+ vi.restoreAllMocks();
7
+ });
8
+ it('prints the rendered cfonts banner plus the tagline', () => {
9
+ const spy = vi.spyOn(console, 'log').mockImplementation(() => { });
10
+ printBanner();
11
+ // cfonts.render('dolan', ...) always returns a RenderedFontObject with a
12
+ // `.string` for this font/input, so the "rendered" branch is the normal
13
+ // path — asserting call count pins both the banner line and the tagline.
14
+ expect(spy).toHaveBeenCalled();
15
+ const output = spy.mock.calls.map((c) => String(c[0])).join('\n');
16
+ expect(output).toContain('AngularLynx');
17
+ });
18
+ it('skips the banner line when cfonts.render returns a falsy value', () => {
19
+ // cfonts can return undefined for degenerate input — guard against that
20
+ // rather than crash. Spy directly on the render method to force that
21
+ // branch deterministically.
22
+ vi.spyOn(cfonts, 'render').mockReturnValue(undefined);
23
+ const spy = vi.spyOn(console, 'log').mockImplementation(() => { });
24
+ printBanner();
25
+ // Only the tagline + blank line are logged — no banner string line.
26
+ expect(spy).toHaveBeenCalledTimes(2);
27
+ });
28
+ });
29
+ //# sourceMappingURL=banner.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"banner.test.js","sourceRoot":"","sources":["../../src/utils/banner.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAClE,WAAW,EAAE,CAAC;QAEd,yEAAyE;QACzE,wEAAwE;QACxE,yEAAyE;QACzE,MAAM,CAAC,GAAG,CAAC,CAAC,gBAAgB,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,wEAAwE;QACxE,qEAAqE;QACrE,4BAA4B;QAC5B,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,eAAe,CACxC,SAAwD,CACzD,CAAC;QAEF,MAAM,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAClE,WAAW,EAAE,CAAC;QAEd,oEAAoE;QACpE,MAAM,CAAC,GAAG,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type ClassValue } from 'clsx';
2
+ export declare const cn: (...inputs: ClassValue[]) => string;
@@ -0,0 +1,6 @@
1
+ import { clsx } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+ export const cn = (...inputs) => {
4
+ return twMerge(clsx(inputs));
5
+ };
6
+ //# sourceMappingURL=cn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cn.js","sourceRoot":"","sources":["../../src/utils/cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,MAAM,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEzC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAoB,EAAU,EAAE;IACpD,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/B,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { cn } from './cn';
3
+ describe('cn', () => {
4
+ it('joins plain class name strings', () => {
5
+ expect(cn('a', 'b')).toBe('a b');
6
+ });
7
+ it('drops falsy values (conditional classes)', () => {
8
+ const isActive = false;
9
+ expect(cn('a', isActive && 'b', undefined, null, 'c')).toBe('a c');
10
+ });
11
+ it('merges conflicting Tailwind utilities, keeping the last one', () => {
12
+ // twMerge should resolve conflicting padding utilities to the last-wins value —
13
+ // this is the whole reason cn() wraps clsx() with tailwind-merge instead of
14
+ // just joining strings.
15
+ expect(cn('p-2', 'p-4')).toBe('p-4');
16
+ });
17
+ it('supports object and array syntax from clsx', () => {
18
+ expect(cn(['a', { b: true, c: false }])).toBe('a b');
19
+ });
20
+ });
21
+ //# sourceMappingURL=cn.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cn.test.js","sourceRoot":"","sources":["../../src/utils/cn.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAE1B,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE;IAClB,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,QAAQ,GAAG,KAAK,CAAC;QACvB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,IAAI,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,gFAAgF;QAChF,4EAA4E;QAC5E,wBAAwB;QACxB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Normalizes upstream file content to the consuming project's oxfmt config.
3
+ *
4
+ * WHY THIS EXISTS: dolan copies component source verbatim and rewrites its
5
+ * import paths (`../../utils/cn` → `@blotch/dolan/utils/cn`). That copy is not
6
+ * guaranteed to satisfy the target project's formatter — the import rewrite
7
+ * alone can push a line past `printWidth`, and any drift in the upstream source
8
+ * lands as-is. Without normalization, `dolan add`/`update` writes files that
9
+ * the project's own `oxfmt --check` (and CI) then reject.
10
+ *
11
+ * It MUST run during analysis, not as a post-write pass: the lockfile records
12
+ * `hash(newContent)` as the merge base, and every command (`update`, `diff`,
13
+ * `outdated`, `list`) recomputes that hash to detect drift. If we formatted
14
+ * after writing, the on-disk content would no longer match the recorded hash
15
+ * and every file would read as "user-modified" forever. Normalizing the
16
+ * content itself keeps the hash, the diff, and the written file in agreement.
17
+ *
18
+ * BEST-EFFORT BY DESIGN: we only reformat when the target project genuinely
19
+ * uses oxfmt — i.e. both an `.oxfmtrc` config and an `oxfmt` binary are
20
+ * discoverable by walking up from `filePath`. Projects without oxfmt (and the
21
+ * temp-dir fixtures in our own unit tests, which live outside any workspace)
22
+ * get their content back unchanged, so dolan stays usable everywhere and its
23
+ * tests stay deterministic. Any formatter failure also falls back to the
24
+ * original content — a formatting hiccup must never corrupt the file we install.
25
+ *
26
+ * @param content Raw (already import-rewritten) file content.
27
+ * @param filePath Absolute destination path inside the consumer project. Used
28
+ * to infer the parser (extension) and to resolve the project's
29
+ * oxfmt config/ignore rules exactly as `oxfmt` itself would.
30
+ */
31
+ export declare const formatContent: (content: string, filePath: string) => string;
@@ -0,0 +1,95 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { existsSync } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
4
+ // Extensions oxfmt understands. Everything else (notably the `.css` theme
5
+ // files) is returned untouched — running them through a JS/TS formatter would
6
+ // at best no-op and at worst mangle them.
7
+ const FORMATTABLE_EXTENSIONS = new Set([
8
+ '.ts',
9
+ '.tsx',
10
+ '.mts',
11
+ '.cts',
12
+ '.js',
13
+ '.jsx',
14
+ '.mjs',
15
+ '.cjs',
16
+ ]);
17
+ // oxfmt config filenames we treat as "this project uses oxfmt". We only look
18
+ // for the JSON variants because that's what the schema-validated config in
19
+ // this monorepo (and generated projects) use; a project on a `.ts`/`.js`
20
+ // oxfmt config is niche enough that skipping formatting there is acceptable.
21
+ const OXFMT_CONFIG_NAMES = ['.oxfmtrc.json', '.oxfmtrc.jsonc'];
22
+ const extensionOf = (filePath) => {
23
+ const dot = filePath.lastIndexOf('.');
24
+ return dot === -1 ? '' : filePath.slice(dot);
25
+ };
26
+ /**
27
+ * Walks up the directory tree from `startDir`, returning the first ancestor
28
+ * that contains `relativePath`, or null if the filesystem root is reached
29
+ * without a hit. Used to discover the consumer's oxfmt config and binary.
30
+ */
31
+ const findUp = (startDir, relativePath) => {
32
+ let dir = startDir;
33
+ // eslint-disable-next-line no-constant-condition
34
+ while (true) {
35
+ const candidate = join(dir, relativePath);
36
+ if (existsSync(candidate))
37
+ return candidate;
38
+ const parent = dirname(dir);
39
+ if (parent === dir)
40
+ return null; // reached the filesystem root
41
+ dir = parent;
42
+ }
43
+ };
44
+ /**
45
+ * Normalizes upstream file content to the consuming project's oxfmt config.
46
+ *
47
+ * WHY THIS EXISTS: dolan copies component source verbatim and rewrites its
48
+ * import paths (`../../utils/cn` → `@blotch/dolan/utils/cn`). That copy is not
49
+ * guaranteed to satisfy the target project's formatter — the import rewrite
50
+ * alone can push a line past `printWidth`, and any drift in the upstream source
51
+ * lands as-is. Without normalization, `dolan add`/`update` writes files that
52
+ * the project's own `oxfmt --check` (and CI) then reject.
53
+ *
54
+ * It MUST run during analysis, not as a post-write pass: the lockfile records
55
+ * `hash(newContent)` as the merge base, and every command (`update`, `diff`,
56
+ * `outdated`, `list`) recomputes that hash to detect drift. If we formatted
57
+ * after writing, the on-disk content would no longer match the recorded hash
58
+ * and every file would read as "user-modified" forever. Normalizing the
59
+ * content itself keeps the hash, the diff, and the written file in agreement.
60
+ *
61
+ * BEST-EFFORT BY DESIGN: we only reformat when the target project genuinely
62
+ * uses oxfmt — i.e. both an `.oxfmtrc` config and an `oxfmt` binary are
63
+ * discoverable by walking up from `filePath`. Projects without oxfmt (and the
64
+ * temp-dir fixtures in our own unit tests, which live outside any workspace)
65
+ * get their content back unchanged, so dolan stays usable everywhere and its
66
+ * tests stay deterministic. Any formatter failure also falls back to the
67
+ * original content — a formatting hiccup must never corrupt the file we install.
68
+ *
69
+ * @param content Raw (already import-rewritten) file content.
70
+ * @param filePath Absolute destination path inside the consumer project. Used
71
+ * to infer the parser (extension) and to resolve the project's
72
+ * oxfmt config/ignore rules exactly as `oxfmt` itself would.
73
+ */
74
+ export const formatContent = (content, filePath) => {
75
+ if (!FORMATTABLE_EXTENSIONS.has(extensionOf(filePath)))
76
+ return content;
77
+ const startDir = dirname(filePath);
78
+ // Gate on the project actually using oxfmt. Checking the config first is the
79
+ // cheap, decisive signal; without it we'd risk formatting to oxfmt defaults
80
+ // in a project that never opted in.
81
+ const hasConfig = OXFMT_CONFIG_NAMES.some((name) => findUp(startDir, name));
82
+ if (!hasConfig)
83
+ return content;
84
+ const oxfmtBin = findUp(startDir, join('node_modules', '.bin', 'oxfmt'));
85
+ if (!oxfmtBin)
86
+ return content;
87
+ const result = spawnSync(oxfmtBin, ['--stdin-filepath', filePath], {
88
+ input: content,
89
+ encoding: 'utf-8',
90
+ });
91
+ if (result.status !== 0 || !result.stdout)
92
+ return content;
93
+ return result.stdout;
94
+ };
95
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,0EAA0E;AAC1E,8EAA8E;AAC9E,0CAA0C;AAC1C,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC;IACrC,KAAK;IACL,MAAM;IACN,MAAM;IACN,MAAM;IACN,KAAK;IACL,MAAM;IACN,MAAM;IACN,MAAM;CACP,CAAC,CAAC;AAEH,6EAA6E;AAC7E,2EAA2E;AAC3E,yEAAyE;AACzE,6EAA6E;AAC7E,MAAM,kBAAkB,GAAG,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC;AAE/D,MAAM,WAAW,GAAG,CAAC,QAAgB,EAAU,EAAE;IAC/C,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACtC,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAC/C,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,GAAG,CAAC,QAAgB,EAAE,YAAoB,EAAiB,EAAE;IACvE,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,iDAAiD;IACjD,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QAC1C,IAAI,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;QAC5C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC,CAAC,8BAA8B;QAC/D,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,OAAe,EAAE,QAAgB,EAAU,EAAE;IACzE,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC;IAEvE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEnC,6EAA6E;IAC7E,4EAA4E;IAC5E,oCAAoC;IACpC,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;IAC5E,IAAI,CAAC,SAAS;QAAE,OAAO,OAAO,CAAC;IAE/B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACzE,IAAI,CAAC,QAAQ;QAAE,OAAO,OAAO,CAAC;IAE9B,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,kBAAkB,EAAE,QAAQ,CAAC,EAAE;QACjE,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,OAAO;KAClB,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,OAAO,CAAC;IAC1D,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};