livemark 0.24.1 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (397) hide show
  1. package/README.md +3 -2
  2. package/build/actions/config/define.d.ts +6 -0
  3. package/build/actions/config/define.unit.js +8 -1
  4. package/build/actions/escape/copy.d.ts +11 -0
  5. package/build/actions/escape/copy.js +29 -0
  6. package/build/actions/escape/copy.unit.d.ts +1 -0
  7. package/build/actions/escape/copy.unit.js +37 -0
  8. package/build/actions/escape/list.d.ts +12 -0
  9. package/build/actions/escape/list.js +27 -0
  10. package/build/actions/escape/list.unit.d.ts +1 -0
  11. package/build/actions/escape/list.unit.js +36 -0
  12. package/build/actions/target/build.d.ts +9 -26
  13. package/build/actions/target/build.js +50 -71
  14. package/build/actions/target/build.unit.d.ts +1 -0
  15. package/build/actions/target/build.unit.js +76 -0
  16. package/build/actions/target/clear.d.ts +4 -0
  17. package/build/actions/target/clear.js +14 -0
  18. package/build/actions/target/clear.unit.d.ts +1 -0
  19. package/build/actions/target/clear.unit.js +23 -0
  20. package/build/commands/build.js +1 -2
  21. package/build/commands/clear.d.ts +5 -0
  22. package/build/commands/clear.js +15 -0
  23. package/build/commands/escape.d.ts +4 -3
  24. package/build/commands/escape.js +45 -48
  25. package/build/commands/preview.js +1 -2
  26. package/build/commands/start.js +1 -2
  27. package/build/components/Abbr.d.ts +1 -1
  28. package/build/components/Abbr.js +2 -4
  29. package/build/components/AnsiCode.d.ts +1 -1
  30. package/build/components/AnsiCode.js +2 -2
  31. package/build/components/Article.d.ts +2 -1
  32. package/build/components/Article.js +7 -14
  33. package/build/components/BackToTop.d.ts +1 -1
  34. package/build/components/Banner.d.ts +2 -2
  35. package/build/components/Banner.js +7 -3
  36. package/build/components/BlogIndex.d.ts +1 -1
  37. package/build/components/BlogIndex.js +2 -11
  38. package/build/components/Breadcrumbs.d.ts +1 -1
  39. package/build/components/Breadcrumbs.js +2 -3
  40. package/build/components/Callout.d.ts +1 -1
  41. package/build/components/Callout.js +5 -9
  42. package/build/components/Card.d.ts +1 -1
  43. package/build/components/Card.js +2 -3
  44. package/build/components/Cards.d.ts +1 -1
  45. package/build/components/ChangelogIndex.d.ts +1 -1
  46. package/build/components/ChangelogIndex.js +2 -11
  47. package/build/components/ChoiceList.d.ts +15 -0
  48. package/build/components/ChoiceList.js +13 -0
  49. package/build/components/CodeBlock.d.ts +1 -1
  50. package/build/components/CodeBlock.js +3 -16
  51. package/build/components/CodeTabs.d.ts +1 -1
  52. package/build/components/CodeTabs.js +2 -3
  53. package/build/components/Column.d.ts +1 -1
  54. package/build/components/Columns.d.ts +1 -1
  55. package/build/components/Content.d.ts +1 -1
  56. package/build/components/ContentTab.d.ts +1 -1
  57. package/build/components/ContentTabs.d.ts +1 -1
  58. package/build/components/ContentTabs.js +2 -3
  59. package/build/components/DefaultCatchBoundary.d.ts +1 -1
  60. package/build/components/DefaultCatchBoundary.js +5 -7
  61. package/build/components/DefinitionList.d.ts +3 -3
  62. package/build/components/Details.d.ts +1 -1
  63. package/build/components/Details.js +2 -5
  64. package/build/components/FileTree.d.ts +1 -1
  65. package/build/components/FileTree.js +3 -5
  66. package/build/components/Footer.d.ts +1 -1
  67. package/build/components/Footer.js +2 -5
  68. package/build/components/FootnoteRef.d.ts +1 -1
  69. package/build/components/FootnoteRef.js +2 -4
  70. package/build/components/Header.d.ts +6 -0
  71. package/build/components/Header.js +26 -0
  72. package/build/components/HeaderMenu.d.ts +2 -0
  73. package/build/components/HeaderMenu.js +27 -0
  74. package/build/components/HeaderNav.d.ts +6 -0
  75. package/build/components/HeaderNav.js +74 -0
  76. package/build/components/HeaderSearch.d.ts +4 -0
  77. package/build/components/HeaderSearch.js +33 -0
  78. package/build/components/Heading.d.ts +6 -6
  79. package/build/components/InlineBadge.d.ts +2 -2
  80. package/build/components/InlineBadge.js +1 -1
  81. package/build/components/InlineIcon.d.ts +1 -1
  82. package/build/components/InlineToc.d.ts +1 -1
  83. package/build/components/InlineToc.js +2 -4
  84. package/build/components/Layout.d.ts +2 -1
  85. package/build/components/Layout.js +5 -58
  86. package/build/components/LinkButton.d.ts +2 -2
  87. package/build/components/LinkButton.js +1 -1
  88. package/build/components/MenuSheet.d.ts +22 -0
  89. package/build/components/MenuSheet.js +27 -0
  90. package/build/components/Mermaid.d.ts +1 -1
  91. package/build/components/MermaidRenderer.d.ts +1 -1
  92. package/build/components/MermaidRenderer.js +20 -8
  93. package/build/components/NotFound.d.ts +1 -1
  94. package/build/components/NotFound.js +3 -6
  95. package/build/components/PackageTabs.d.ts +1 -1
  96. package/build/components/PackageTabs.js +3 -7
  97. package/build/components/PageToolbar.d.ts +1 -1
  98. package/build/components/PageToolbar.js +2 -10
  99. package/build/components/PrevNext.d.ts +1 -1
  100. package/build/components/PrevNext.js +2 -10
  101. package/build/components/Root.d.ts +4 -0
  102. package/build/components/Root.js +8 -0
  103. package/build/components/Search.d.ts +5 -2
  104. package/build/components/Search.js +11 -9
  105. package/build/components/SearchDialog.d.ts +1 -1
  106. package/build/components/SearchDialog.js +10 -133
  107. package/build/components/Section.d.ts +1 -1
  108. package/build/components/SectionHeader.d.ts +1 -1
  109. package/build/components/SheetPanel.d.ts +12 -0
  110. package/build/components/SheetPanel.js +19 -0
  111. package/build/components/Sidebar.d.ts +1 -1
  112. package/build/components/Sidebar.js +12 -14
  113. package/build/components/SidebarArticles.d.ts +4 -1
  114. package/build/components/SidebarArticles.js +5 -9
  115. package/build/components/SidebarLinks.d.ts +4 -1
  116. package/build/components/SidebarLinks.js +6 -9
  117. package/build/components/SidebarPosts.d.ts +4 -1
  118. package/build/components/SidebarPosts.js +7 -23
  119. package/build/components/SidebarReleases.d.ts +4 -1
  120. package/build/components/SidebarReleases.js +5 -15
  121. package/build/components/SidebarSectionPicker.d.ts +8 -0
  122. package/build/components/SidebarSectionPicker.js +31 -0
  123. package/build/components/SidebarSections.d.ts +1 -1
  124. package/build/components/SidebarSections.js +5 -9
  125. package/build/components/SiteLink.d.ts +1 -1
  126. package/build/components/SiteTitle.d.ts +1 -1
  127. package/build/components/SiteTitle.js +2 -6
  128. package/build/components/SortableTable.d.ts +1 -1
  129. package/build/components/SoundCloud.d.ts +1 -1
  130. package/build/components/SoundCloud.js +2 -2
  131. package/build/components/TagIndex.d.ts +1 -1
  132. package/build/components/TagIndex.js +2 -11
  133. package/build/components/Theme.d.ts +2 -1
  134. package/build/components/Theme.js +35 -15
  135. package/build/components/Toc.d.ts +5 -4
  136. package/build/components/Toc.js +35 -35
  137. package/build/components/YouTube.d.ts +1 -1
  138. package/build/components/YouTube.js +2 -2
  139. package/build/components/ZoomImage.d.ts +1 -1
  140. package/build/content-collections.js +5 -1
  141. package/build/elements/accordion.d.ts +4 -4
  142. package/build/elements/accordion.js +2 -3
  143. package/build/elements/alert-dialog.d.ts +12 -12
  144. package/build/elements/alert-dialog.js +2 -4
  145. package/build/elements/alert.d.ts +4 -4
  146. package/build/elements/alert.js +2 -2
  147. package/build/elements/aspect-ratio.d.ts +1 -1
  148. package/build/elements/avatar.d.ts +6 -6
  149. package/build/elements/badge.d.ts +1 -1
  150. package/build/elements/badge.js +3 -1
  151. package/build/elements/breadcrumb.d.ts +6 -6
  152. package/build/elements/breadcrumb.js +2 -4
  153. package/build/elements/button-group.d.ts +2 -2
  154. package/build/elements/button-group.js +5 -5
  155. package/build/elements/button.d.ts +2 -2
  156. package/build/elements/button.js +9 -7
  157. package/build/elements/calendar.d.ts +2 -2
  158. package/build/elements/calendar.js +2 -2
  159. package/build/elements/card.d.ts +7 -7
  160. package/build/elements/card.js +4 -4
  161. package/build/elements/carousel.d.ts +5 -5
  162. package/build/elements/carousel.js +3 -7
  163. package/build/elements/chart.d.ts +6 -6
  164. package/build/elements/chart.js +5 -11
  165. package/build/elements/checkbox.d.ts +1 -1
  166. package/build/elements/collapsible.d.ts +3 -3
  167. package/build/elements/command.d.ts +9 -9
  168. package/build/elements/command.js +5 -11
  169. package/build/elements/context-menu.d.ts +15 -15
  170. package/build/elements/context-menu.js +6 -9
  171. package/build/elements/dialog.d.ts +10 -10
  172. package/build/elements/dialog.js +2 -6
  173. package/build/elements/drawer.d.ts +14 -12
  174. package/build/elements/drawer.js +14 -15
  175. package/build/elements/dropdown-menu.d.ts +15 -15
  176. package/build/elements/dropdown-menu.js +7 -10
  177. package/build/elements/empty.d.ts +6 -6
  178. package/build/elements/empty.js +2 -2
  179. package/build/elements/field.d.ts +10 -10
  180. package/build/elements/field.js +3 -4
  181. package/build/elements/hover-card.d.ts +3 -3
  182. package/build/elements/hover-card.js +2 -2
  183. package/build/elements/input-group.d.ts +7 -7
  184. package/build/elements/input-group.js +5 -5
  185. package/build/elements/input-otp.d.ts +4 -4
  186. package/build/elements/input.d.ts +1 -1
  187. package/build/elements/input.js +2 -2
  188. package/build/elements/item.d.ts +9 -9
  189. package/build/elements/item.js +2 -2
  190. package/build/elements/kbd.d.ts +2 -2
  191. package/build/elements/label.d.ts +1 -1
  192. package/build/elements/menubar.d.ts +16 -16
  193. package/build/elements/menubar.js +9 -11
  194. package/build/elements/native-select.d.ts +3 -3
  195. package/build/elements/native-select.js +2 -4
  196. package/build/elements/navigation-menu.d.ts +8 -8
  197. package/build/elements/navigation-menu.js +3 -5
  198. package/build/elements/pagination.d.ts +7 -7
  199. package/build/elements/pagination.js +4 -10
  200. package/build/elements/popover.d.ts +6 -6
  201. package/build/elements/popover.js +2 -2
  202. package/build/elements/progress.d.ts +5 -5
  203. package/build/elements/progress.js +2 -3
  204. package/build/elements/radio-group.d.ts +2 -2
  205. package/build/elements/resizable.d.ts +3 -3
  206. package/build/elements/scroll-area.d.ts +2 -2
  207. package/build/elements/scroll-area.js +2 -4
  208. package/build/elements/select.d.ts +9 -9
  209. package/build/elements/select.js +4 -9
  210. package/build/elements/separator.d.ts +1 -1
  211. package/build/elements/sheet.d.ts +8 -8
  212. package/build/elements/sheet.js +2 -6
  213. package/build/elements/sidebar.d.ts +19 -19
  214. package/build/elements/sidebar.js +15 -37
  215. package/build/elements/skeleton.d.ts +1 -1
  216. package/build/elements/slider.d.ts +2 -1
  217. package/build/elements/slider.js +2 -3
  218. package/build/elements/sonner.d.ts +1 -1
  219. package/build/elements/spinner.d.ts +1 -1
  220. package/build/elements/switch.d.ts +1 -1
  221. package/build/elements/table.d.ts +8 -8
  222. package/build/elements/tabs.d.ts +4 -4
  223. package/build/elements/tabs.js +3 -3
  224. package/build/elements/textarea.d.ts +1 -1
  225. package/build/elements/textarea.js +2 -2
  226. package/build/elements/toggle-group.d.ts +3 -2
  227. package/build/elements/toggle-group.js +3 -3
  228. package/build/elements/toggle.d.ts +1 -1
  229. package/build/elements/toggle.js +2 -2
  230. package/build/elements/tooltip.d.ts +4 -4
  231. package/build/elements/tooltip.js +2 -3
  232. package/build/head.d.ts +4 -0
  233. package/build/head.js +6 -0
  234. package/build/helpers/article-search.d.ts +19 -0
  235. package/build/helpers/article-search.js +134 -0
  236. package/build/helpers/dependency-dir.d.ts +5 -0
  237. package/build/helpers/dependency-dir.js +20 -0
  238. package/build/helpers/dependency-dir.unit.d.ts +1 -0
  239. package/build/helpers/dependency-dir.unit.js +25 -0
  240. package/build/helpers/dynamic-icon-resolver.d.ts +1 -1
  241. package/build/helpers/dynamic-icon.d.ts +1 -1
  242. package/build/helpers/head.d.ts +53 -0
  243. package/build/helpers/head.js +69 -0
  244. package/build/helpers/head.unit.d.ts +1 -0
  245. package/build/helpers/head.unit.js +108 -0
  246. package/build/helpers/nav-items.d.ts +11 -0
  247. package/build/helpers/nav-items.js +65 -0
  248. package/build/helpers/render-inline-markdown.d.ts +1 -0
  249. package/build/helpers/render-inline-markdown.js +34 -0
  250. package/build/helpers/render-inline-markdown.unit.d.ts +1 -0
  251. package/build/helpers/render-inline-markdown.unit.js +20 -0
  252. package/build/helpers/search-highlight.d.ts +8 -0
  253. package/build/helpers/search-highlight.js +59 -0
  254. package/build/helpers/search-highlight.unit.d.ts +1 -0
  255. package/build/helpers/search-highlight.unit.js +36 -0
  256. package/build/helpers/target-export.d.ts +9 -0
  257. package/build/helpers/target-export.js +24 -0
  258. package/build/helpers/target-export.unit.d.ts +1 -0
  259. package/build/helpers/target-export.unit.js +25 -0
  260. package/build/helpers/theme.d.ts +6 -2
  261. package/build/helpers/theme.js +40 -7
  262. package/build/helpers/theme.unit.d.ts +1 -0
  263. package/build/helpers/theme.unit.js +30 -0
  264. package/build/hooks/hydrated.d.ts +2 -0
  265. package/build/hooks/hydrated.js +15 -0
  266. package/build/index.d.ts +1 -0
  267. package/build/index.js +1 -1
  268. package/build/models/config.d.ts +32 -6
  269. package/build/models/config.js +10 -1
  270. package/build/models/section.d.ts +4 -2
  271. package/build/models/section.js +1 -1
  272. package/build/plugins/vite-livemark.d.ts +4 -5
  273. package/build/plugins/vite-livemark.js +56 -90
  274. package/build/program.js +4 -2
  275. package/build/routes/$.d.ts +4 -1
  276. package/build/routes/$.js +20 -9
  277. package/build/routes/__root.js +29 -63
  278. package/build/settings.js +2 -1
  279. package/package.json +68 -66
  280. package/{.agents/skills → skills}/livemark-authoring/SKILL.md +2 -2
  281. package/{.agents/skills → skills}/livemark-configuration/SKILL.md +12 -5
  282. package/skills/livemark-customization/SKILL.md +145 -0
  283. package/source/actions/config/define.unit.ts +9 -0
  284. package/source/actions/escape/copy.ts +35 -0
  285. package/source/actions/escape/copy.unit.ts +51 -0
  286. package/source/actions/escape/list.ts +30 -0
  287. package/source/actions/escape/list.unit.ts +42 -0
  288. package/source/actions/target/build.ts +49 -69
  289. package/source/actions/target/build.unit.ts +95 -0
  290. package/source/actions/target/clear.ts +14 -0
  291. package/source/actions/target/clear.unit.ts +25 -0
  292. package/source/commands/build.ts +0 -1
  293. package/source/commands/clear.ts +15 -0
  294. package/source/commands/escape.ts +42 -59
  295. package/source/commands/preview.ts +0 -1
  296. package/source/commands/start.ts +0 -1
  297. package/source/components/AnsiCode.tsx +1 -1
  298. package/source/components/Article.tsx +8 -4
  299. package/source/components/Banner.tsx +12 -2
  300. package/source/components/BlogIndex.tsx +1 -1
  301. package/source/components/Callout.tsx +4 -6
  302. package/source/components/ChangelogIndex.tsx +1 -1
  303. package/source/components/ChoiceList.tsx +69 -0
  304. package/source/components/CodeBlock.tsx +6 -6
  305. package/source/components/CodeTabs.tsx +1 -1
  306. package/source/components/ContentTabs.tsx +1 -1
  307. package/source/components/DefaultCatchBoundary.tsx +4 -6
  308. package/source/components/Details.tsx +1 -1
  309. package/source/components/FileTree.tsx +1 -1
  310. package/source/components/Header.tsx +52 -0
  311. package/source/components/HeaderMenu.tsx +41 -0
  312. package/source/components/HeaderNav.tsx +145 -0
  313. package/source/components/HeaderSearch.tsx +77 -0
  314. package/source/components/InlineBadge.tsx +1 -1
  315. package/source/components/InlineToc.tsx +1 -1
  316. package/source/components/Layout.tsx +16 -160
  317. package/source/components/LinkButton.tsx +9 -1
  318. package/source/components/MenuSheet.tsx +92 -0
  319. package/source/components/MermaidRenderer.tsx +19 -8
  320. package/source/components/NotFound.tsx +3 -5
  321. package/source/components/PackageTabs.tsx +2 -2
  322. package/source/components/PageToolbar.tsx +11 -3
  323. package/source/components/PrevNext.tsx +2 -2
  324. package/source/components/Root.tsx +13 -0
  325. package/source/components/Search.tsx +28 -8
  326. package/source/components/SearchDialog.tsx +15 -189
  327. package/source/components/SheetPanel.tsx +69 -0
  328. package/source/components/Sidebar.tsx +27 -14
  329. package/source/components/SidebarArticles.tsx +4 -3
  330. package/source/components/SidebarLinks.tsx +3 -2
  331. package/source/components/SidebarPosts.tsx +3 -2
  332. package/source/components/SidebarReleases.tsx +3 -2
  333. package/source/components/SidebarSectionPicker.tsx +70 -0
  334. package/source/components/SiteTitle.tsx +5 -5
  335. package/source/components/SoundCloud.tsx +1 -1
  336. package/source/components/TagIndex.tsx +1 -1
  337. package/source/components/Theme.tsx +55 -29
  338. package/source/components/Toc.tsx +76 -55
  339. package/source/components/YouTube.tsx +1 -1
  340. package/source/content-collections.ts +4 -0
  341. package/source/elements/alert-dialog.tsx +1 -1
  342. package/source/elements/alert.tsx +1 -1
  343. package/source/elements/badge.tsx +4 -0
  344. package/source/elements/button-group.tsx +4 -4
  345. package/source/elements/button.tsx +10 -6
  346. package/source/elements/calendar.tsx +1 -1
  347. package/source/elements/card.tsx +3 -3
  348. package/source/elements/command.tsx +7 -4
  349. package/source/elements/context-menu.tsx +5 -5
  350. package/source/elements/dialog.tsx +1 -1
  351. package/source/elements/drawer.tsx +59 -43
  352. package/source/elements/dropdown-menu.tsx +6 -6
  353. package/source/elements/empty.tsx +1 -1
  354. package/source/elements/field.tsx +1 -1
  355. package/source/elements/hover-card.tsx +1 -1
  356. package/source/elements/input-group.tsx +4 -4
  357. package/source/elements/input.tsx +1 -1
  358. package/source/elements/item.tsx +1 -1
  359. package/source/elements/menubar.tsx +8 -8
  360. package/source/elements/native-select.tsx +1 -1
  361. package/source/elements/popover.tsx +1 -1
  362. package/source/elements/select.tsx +3 -3
  363. package/source/elements/sidebar.tsx +8 -21
  364. package/source/elements/tabs.tsx +2 -2
  365. package/source/elements/textarea.tsx +1 -1
  366. package/source/elements/toggle-group.tsx +2 -2
  367. package/source/elements/toggle.tsx +1 -1
  368. package/source/env.d.ts +1 -0
  369. package/source/head.ts +7 -0
  370. package/source/helpers/article-search.tsx +192 -0
  371. package/source/helpers/dependency-dir.ts +20 -0
  372. package/source/helpers/dependency-dir.unit.ts +39 -0
  373. package/source/helpers/head.ts +94 -0
  374. package/source/helpers/head.unit.ts +116 -0
  375. package/source/helpers/nav-items.tsx +102 -0
  376. package/source/helpers/render-inline-markdown.ts +44 -0
  377. package/source/helpers/render-inline-markdown.unit.ts +30 -0
  378. package/source/helpers/search-highlight.ts +73 -0
  379. package/source/helpers/search-highlight.unit.ts +42 -0
  380. package/source/helpers/target-export.ts +28 -0
  381. package/source/helpers/target-export.unit.ts +37 -0
  382. package/source/helpers/theme.ts +40 -6
  383. package/source/helpers/theme.unit.ts +32 -0
  384. package/source/hooks/hydrated.ts +18 -0
  385. package/source/index.ts +1 -0
  386. package/source/models/config.ts +13 -0
  387. package/source/models/section.ts +3 -0
  388. package/source/plugins/vite-livemark.ts +54 -95
  389. package/source/program.ts +2 -0
  390. package/source/routes/$.tsx +27 -9
  391. package/source/routes/__root.tsx +51 -71
  392. package/source/settings.ts +1 -0
  393. package/source/styles/general.css +59 -11
  394. package/source/styles/markdown.css +13 -7
  395. package/source/styles/shape.css +14 -0
  396. package/.agents/skills/change-review/SKILL.md +0 -47
  397. package/.agents/skills/livemark-customization/SKILL.md +0 -118
package/README.md CHANGED
@@ -9,7 +9,7 @@ Livemark turns plain Markdown into a fast, modern documentation site. Point it a
9
9
  - **Diagrams and math.** [Mermaid](https://mermaid.js.org/) flowcharts and KaTeX equations, theme-aware, zero config.
10
10
  - **Rich elements.** Callouts, tabs, file trees, cards, columns, badges, package tabs (npm/pnpm/yarn/bun), embeds (YouTube, SoundCloud), and more — all as Markdown directives or MDX components.
11
11
  - **Sections.** First-class support for docs, blog (with tags + RSS), and changelog (local `CHANGELOG.md` or GitHub releases).
12
- - **Search.** Full-text search powered by [Orama](https://oramasearch.com/), keyboard shortcuts, smart table-of-contents.
12
+ - **Search.** Full-text search powered by [Orama](https://oramasearch.com/), with matches highlighted on the page you land on, keyboard shortcuts, smart table-of-contents.
13
13
  - **Themable.** Tailwind v4, shadcn-style primitives, dark mode, and per-file overrides via a `.livemark/` folder.
14
14
  - **Built on TanStack Start.** SSR, prerendering, sitemap, and routing for free.
15
15
 
@@ -66,9 +66,10 @@ Welcome!
66
66
  npx livemark start # dev server with HMR at http://localhost:8000
67
67
  npx livemark build # production build to .livemark/build/
68
68
  npx livemark preview # serve the production build locally
69
+ npx livemark clear # wipe the generated .livemark/.target/ (stop the dev server first)
69
70
  ```
70
71
 
71
- That's the whole loop.
72
+ That's the whole loop. Add `.livemark/build/` and `.livemark/.target/` to your `.gitignore`.
72
73
 
73
74
  ## Project structure
74
75
 
@@ -9,6 +9,7 @@ export declare function defineConfig(input: UserConfig): {
9
9
  logo?: string | undefined;
10
10
  title: string;
11
11
  description: string;
12
+ banner?: string | undefined;
12
13
  include: string | string[];
13
14
  exclude?: string | string[] | undefined;
14
15
  codeThemeLight: "ayu-light" | "catppuccin-latte" | "everforest-light" | "github-light" | "github-light-default" | "github-light-high-contrast" | "gruvbox-light-hard" | "gruvbox-light-medium" | "gruvbox-light-soft" | "horizon-bright" | "kanagawa-lotus" | "light-plus" | "material-theme-lighter" | "min-light" | "night-owl-light" | "one-light" | "rose-pine-dawn" | "slack-ochin" | "snazzy-light" | "solarized-light" | "vitesse-light";
@@ -78,5 +79,10 @@ export declare function defineConfig(input: UserConfig): {
78
79
  sourceAction?: "edit" | "view" | undefined;
79
80
  };
80
81
  }[] | undefined;
82
+ head?: {
83
+ meta?: Record<string, string>[] | undefined;
84
+ links?: Record<string, string>[] | undefined;
85
+ scripts?: Record<string, string>[] | undefined;
86
+ } | undefined;
81
87
  vite?: unknown;
82
88
  };
@@ -26,5 +26,12 @@ describe("defineConfig", () => {
26
26
  const config = defineConfig({});
27
27
  expect(config.include).toBe("**/*.md");
28
28
  });
29
+ it("should accept an inline Markdown banner", () => {
30
+ const config = defineConfig({ banner: "Hi · [x](/y/)" });
31
+ expect(config.banner).toBe("Hi · [x](/y/)");
32
+ });
33
+ it("should leave banner unset by default", () => {
34
+ expect(defineConfig({}).banner).toBeUndefined();
35
+ });
29
36
  });
30
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmaW5lLnVuaXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zb3VyY2UvYWN0aW9ucy9jb25maWcvZGVmaW5lLnVuaXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0JBQWdCLENBQUE7QUFDckQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUUxQyxRQUFRLENBQUMsY0FBYyxFQUFFLEdBQUcsRUFBRTtJQUM1QixFQUFFLENBQUMsbUNBQW1DLEVBQUUsR0FBRyxFQUFFO1FBQzNDLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxFQUFFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxDQUFDLENBQUE7UUFDN0QsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQTtJQUNsRCxDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQyxtQ0FBbUMsRUFBRSxHQUFHLEVBQUU7UUFDM0MsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDO1lBQzFCLE9BQU8sRUFBRSxDQUFDLG1CQUFtQixFQUFFLGlCQUFpQixDQUFDO1NBQ2xELENBQUMsQ0FBQTtRQUNGLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsbUJBQW1CLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxDQUFBO0lBQzFFLENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLGdDQUFnQyxFQUFFLEdBQUcsRUFBRTtRQUN4QyxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUM7WUFDMUIsT0FBTyxFQUFFLFVBQVU7WUFDbkIsT0FBTyxFQUFFLFdBQVc7U0FDckIsQ0FBQyxDQUFBO1FBQ0YsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUE7SUFDMUMsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsK0JBQStCLEVBQUUsR0FBRyxFQUFFO1FBQ3ZDLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFBO1FBQ3BELE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsYUFBYSxFQUFFLENBQUE7SUFDeEMsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsbUNBQW1DLEVBQUUsR0FBRyxFQUFFO1FBQzNDLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQTtRQUMvQixNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUN4QyxDQUFDLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZGVzY3JpYmUsIGV4cGVjdCwgaXQgfSBmcm9tIFwidml0ZS1wbHVzL3Rlc3RcIlxuaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSBcIi4vZGVmaW5lLnRzXCJcblxuZGVzY3JpYmUoXCJkZWZpbmVDb25maWdcIiwgKCkgPT4ge1xuICBpdChcInNob3VsZCBhY2NlcHQgaW5jbHVkZSBhcyBhIHN0cmluZ1wiLCAoKSA9PiB7XG4gICAgY29uc3QgY29uZmlnID0gZGVmaW5lQ29uZmlnKHsgaW5jbHVkZTogXCJhcnRpY2xlcy8qKi8qLm1keFwiIH0pXG4gICAgZXhwZWN0KGNvbmZpZy5pbmNsdWRlKS50b0JlKFwiYXJ0aWNsZXMvKiovKi5tZHhcIilcbiAgfSlcblxuICBpdChcInNob3VsZCBhY2NlcHQgaW5jbHVkZSBhcyBhbiBhcnJheVwiLCAoKSA9PiB7XG4gICAgY29uc3QgY29uZmlnID0gZGVmaW5lQ29uZmlnKHtcbiAgICAgIGluY2x1ZGU6IFtcImFydGljbGVzLyoqLyoubWR4XCIsIFwiZ3VpZGVzLyoqLyoubWR4XCJdLFxuICAgIH0pXG4gICAgZXhwZWN0KGNvbmZpZy5pbmNsdWRlKS50b0VxdWFsKFtcImFydGljbGVzLyoqLyoubWR4XCIsIFwiZ3VpZGVzLyoqLyoubWR4XCJdKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIGFjY2VwdCBvcHRpb25hbCBleGNsdWRlXCIsICgpID0+IHtcbiAgICBjb25zdCBjb25maWcgPSBkZWZpbmVDb25maWcoe1xuICAgICAgaW5jbHVkZTogXCIqKi8qLm1keFwiLFxuICAgICAgZXhjbHVkZTogXCJkcmFmdHMvKipcIixcbiAgICB9KVxuICAgIGV4cGVjdChjb25maWcuZXhjbHVkZSkudG9CZShcImRyYWZ0cy8qKlwiKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIGFsbG93IG9taXR0aW5nIGV4Y2x1ZGVcIiwgKCkgPT4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IGRlZmluZUNvbmZpZyh7IGluY2x1ZGU6IFwiKiovKi5tZHhcIiB9KVxuICAgIGV4cGVjdChjb25maWcuZXhjbHVkZSkudG9CZVVuZGVmaW5lZCgpXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgZGVmYXVsdCBpbmNsdWRlIHRvICoqLyoubWRcIiwgKCkgPT4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IGRlZmluZUNvbmZpZyh7fSlcbiAgICBleHBlY3QoY29uZmlnLmluY2x1ZGUpLnRvQmUoXCIqKi8qLm1kXCIpXG4gIH0pXG59KVxuIl19
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmaW5lLnVuaXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zb3VyY2UvYWN0aW9ucy9jb25maWcvZGVmaW5lLnVuaXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0JBQWdCLENBQUE7QUFDckQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUUxQyxRQUFRLENBQUMsY0FBYyxFQUFFLEdBQUcsRUFBRTtJQUM1QixFQUFFLENBQUMsbUNBQW1DLEVBQUUsR0FBRyxFQUFFO1FBQzNDLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxFQUFFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxDQUFDLENBQUE7UUFDN0QsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQTtJQUNsRCxDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQyxtQ0FBbUMsRUFBRSxHQUFHLEVBQUU7UUFDM0MsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDO1lBQzFCLE9BQU8sRUFBRSxDQUFDLG1CQUFtQixFQUFFLGlCQUFpQixDQUFDO1NBQ2xELENBQUMsQ0FBQTtRQUNGLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsbUJBQW1CLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxDQUFBO0lBQzFFLENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLGdDQUFnQyxFQUFFLEdBQUcsRUFBRTtRQUN4QyxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUM7WUFDMUIsT0FBTyxFQUFFLFVBQVU7WUFDbkIsT0FBTyxFQUFFLFdBQVc7U0FDckIsQ0FBQyxDQUFBO1FBQ0YsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUE7SUFDMUMsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsK0JBQStCLEVBQUUsR0FBRyxFQUFFO1FBQ3ZDLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFBO1FBQ3BELE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsYUFBYSxFQUFFLENBQUE7SUFDeEMsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsbUNBQW1DLEVBQUUsR0FBRyxFQUFFO1FBQzNDLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQTtRQUMvQixNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUN4QyxDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQyx5Q0FBeUMsRUFBRSxHQUFHLEVBQUU7UUFDakQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLEVBQUUsTUFBTSxFQUFFLGVBQWUsRUFBRSxDQUFDLENBQUE7UUFDeEQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUE7SUFDN0MsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsc0NBQXNDLEVBQUUsR0FBRyxFQUFFO1FBQzlDLE1BQU0sQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsYUFBYSxFQUFFLENBQUE7SUFDakQsQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGRlc2NyaWJlLCBleHBlY3QsIGl0IH0gZnJvbSBcInZpdGUtcGx1cy90ZXN0XCJcbmltcG9ydCB7IGRlZmluZUNvbmZpZyB9IGZyb20gXCIuL2RlZmluZS50c1wiXG5cbmRlc2NyaWJlKFwiZGVmaW5lQ29uZmlnXCIsICgpID0+IHtcbiAgaXQoXCJzaG91bGQgYWNjZXB0IGluY2x1ZGUgYXMgYSBzdHJpbmdcIiwgKCkgPT4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IGRlZmluZUNvbmZpZyh7IGluY2x1ZGU6IFwiYXJ0aWNsZXMvKiovKi5tZHhcIiB9KVxuICAgIGV4cGVjdChjb25maWcuaW5jbHVkZSkudG9CZShcImFydGljbGVzLyoqLyoubWR4XCIpXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgYWNjZXB0IGluY2x1ZGUgYXMgYW4gYXJyYXlcIiwgKCkgPT4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IGRlZmluZUNvbmZpZyh7XG4gICAgICBpbmNsdWRlOiBbXCJhcnRpY2xlcy8qKi8qLm1keFwiLCBcImd1aWRlcy8qKi8qLm1keFwiXSxcbiAgICB9KVxuICAgIGV4cGVjdChjb25maWcuaW5jbHVkZSkudG9FcXVhbChbXCJhcnRpY2xlcy8qKi8qLm1keFwiLCBcImd1aWRlcy8qKi8qLm1keFwiXSlcbiAgfSlcblxuICBpdChcInNob3VsZCBhY2NlcHQgb3B0aW9uYWwgZXhjbHVkZVwiLCAoKSA9PiB7XG4gICAgY29uc3QgY29uZmlnID0gZGVmaW5lQ29uZmlnKHtcbiAgICAgIGluY2x1ZGU6IFwiKiovKi5tZHhcIixcbiAgICAgIGV4Y2x1ZGU6IFwiZHJhZnRzLyoqXCIsXG4gICAgfSlcbiAgICBleHBlY3QoY29uZmlnLmV4Y2x1ZGUpLnRvQmUoXCJkcmFmdHMvKipcIilcbiAgfSlcblxuICBpdChcInNob3VsZCBhbGxvdyBvbWl0dGluZyBleGNsdWRlXCIsICgpID0+IHtcbiAgICBjb25zdCBjb25maWcgPSBkZWZpbmVDb25maWcoeyBpbmNsdWRlOiBcIioqLyoubWR4XCIgfSlcbiAgICBleHBlY3QoY29uZmlnLmV4Y2x1ZGUpLnRvQmVVbmRlZmluZWQoKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIGRlZmF1bHQgaW5jbHVkZSB0byAqKi8qLm1kXCIsICgpID0+IHtcbiAgICBjb25zdCBjb25maWcgPSBkZWZpbmVDb25maWcoe30pXG4gICAgZXhwZWN0KGNvbmZpZy5pbmNsdWRlKS50b0JlKFwiKiovKi5tZFwiKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIGFjY2VwdCBhbiBpbmxpbmUgTWFya2Rvd24gYmFubmVyXCIsICgpID0+IHtcbiAgICBjb25zdCBjb25maWcgPSBkZWZpbmVDb25maWcoeyBiYW5uZXI6IFwiSGkgwrcgW3hdKC95LylcIiB9KVxuICAgIGV4cGVjdChjb25maWcuYmFubmVyKS50b0JlKFwiSGkgwrcgW3hdKC95LylcIilcbiAgfSlcblxuICBpdChcInNob3VsZCBsZWF2ZSBiYW5uZXIgdW5zZXQgYnkgZGVmYXVsdFwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KGRlZmluZUNvbmZpZyh7fSkuYmFubmVyKS50b0JlVW5kZWZpbmVkKClcbiAgfSlcbn0pXG4iXX0=
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Copy a livemark default into `<root>/.livemark/<path>`.
3
+ *
4
+ * Throws when the path is not escapable, is not a livemark file, or the
5
+ * destination already exists. Returns the destination path.
6
+ */
7
+ export declare function copyEscape(props: {
8
+ root: string;
9
+ sourceRoot: string;
10
+ path: string;
11
+ }): string;
@@ -0,0 +1,29 @@
1
+ import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { ESCAPABLE_FILES, ESCAPABLE_FOLDERS } from "../../settings.js";
4
+ /**
5
+ * Copy a livemark default into `<root>/.livemark/<path>`.
6
+ *
7
+ * Throws when the path is not escapable, is not a livemark file, or the
8
+ * destination already exists. Returns the destination path.
9
+ */
10
+ export function copyEscape(props) {
11
+ const isTopLevelFile = !props.path.includes("/") && ESCAPABLE_FILES.includes(props.path);
12
+ const [first] = props.path.split("/");
13
+ const isFolderPath = !!first && ESCAPABLE_FOLDERS.includes(first) && !props.path.includes("..");
14
+ if (!isTopLevelFile && !isFolderPath) {
15
+ throw new Error(`'${props.path}' is not escapable (folders: ${ESCAPABLE_FOLDERS.join(", ")}; files: ${ESCAPABLE_FILES.join(", ")})`);
16
+ }
17
+ const src = join(props.sourceRoot, props.path);
18
+ if (!existsSync(src) || !statSync(src).isFile()) {
19
+ throw new Error(`'${props.path}' is not a livemark file`);
20
+ }
21
+ const dest = join(props.root, ".livemark", props.path);
22
+ if (existsSync(dest)) {
23
+ throw new Error(`.livemark/${props.path} already exists`);
24
+ }
25
+ mkdirSync(dirname(dest), { recursive: true });
26
+ writeFileSync(dest, readFileSync(src));
27
+ return dest;
28
+ }
29
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29weS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NvdXJjZS9hY3Rpb25zL2VzY2FwZS9jb3B5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFLE1BQU0sU0FBUyxDQUFBO0FBQ3RGLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQ3pDLE9BQU8sRUFBRSxlQUFlLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUV0RTs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxVQUFVLENBQUMsS0FBeUQ7SUFDbEYsTUFBTSxjQUFjLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxlQUFlLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUN4RixNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDckMsTUFBTSxZQUFZLEdBQ2hCLENBQUMsQ0FBQyxLQUFLLElBQUksaUJBQWlCLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDNUUsSUFBSSxDQUFDLGNBQWMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3JDLE1BQU0sSUFBSSxLQUFLLENBQ2IsSUFBSSxLQUFLLENBQUMsSUFBSSxnQ0FBZ0MsaUJBQWlCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FDcEgsQ0FBQTtJQUNILENBQUM7SUFFRCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDOUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO1FBQ2hELE1BQU0sSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLENBQUMsSUFBSSwwQkFBMEIsQ0FBQyxDQUFBO0lBQzNELENBQUM7SUFFRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxXQUFXLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ3RELElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDckIsTUFBTSxJQUFJLEtBQUssQ0FBQyxhQUFhLEtBQUssQ0FBQyxJQUFJLGlCQUFpQixDQUFDLENBQUE7SUFDM0QsQ0FBQztJQUVELFNBQVMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUM3QyxhQUFhLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0lBQ3RDLE9BQU8sSUFBSSxDQUFBO0FBQ2IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGV4aXN0c1N5bmMsIG1rZGlyU3luYywgcmVhZEZpbGVTeW5jLCBzdGF0U3luYywgd3JpdGVGaWxlU3luYyB9IGZyb20gXCJub2RlOmZzXCJcbmltcG9ydCB7IGRpcm5hbWUsIGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCJcbmltcG9ydCB7IEVTQ0FQQUJMRV9GSUxFUywgRVNDQVBBQkxFX0ZPTERFUlMgfSBmcm9tIFwiLi4vLi4vc2V0dGluZ3MudHNcIlxuXG4vKipcbiAqIENvcHkgYSBsaXZlbWFyayBkZWZhdWx0IGludG8gYDxyb290Pi8ubGl2ZW1hcmsvPHBhdGg+YC5cbiAqXG4gKiBUaHJvd3Mgd2hlbiB0aGUgcGF0aCBpcyBub3QgZXNjYXBhYmxlLCBpcyBub3QgYSBsaXZlbWFyayBmaWxlLCBvciB0aGVcbiAqIGRlc3RpbmF0aW9uIGFscmVhZHkgZXhpc3RzLiBSZXR1cm5zIHRoZSBkZXN0aW5hdGlvbiBwYXRoLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29weUVzY2FwZShwcm9wczogeyByb290OiBzdHJpbmc7IHNvdXJjZVJvb3Q6IHN0cmluZzsgcGF0aDogc3RyaW5nIH0pIHtcbiAgY29uc3QgaXNUb3BMZXZlbEZpbGUgPSAhcHJvcHMucGF0aC5pbmNsdWRlcyhcIi9cIikgJiYgRVNDQVBBQkxFX0ZJTEVTLmluY2x1ZGVzKHByb3BzLnBhdGgpXG4gIGNvbnN0IFtmaXJzdF0gPSBwcm9wcy5wYXRoLnNwbGl0KFwiL1wiKVxuICBjb25zdCBpc0ZvbGRlclBhdGggPVxuICAgICEhZmlyc3QgJiYgRVNDQVBBQkxFX0ZPTERFUlMuaW5jbHVkZXMoZmlyc3QpICYmICFwcm9wcy5wYXRoLmluY2x1ZGVzKFwiLi5cIilcbiAgaWYgKCFpc1RvcExldmVsRmlsZSAmJiAhaXNGb2xkZXJQYXRoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYCcke3Byb3BzLnBhdGh9JyBpcyBub3QgZXNjYXBhYmxlIChmb2xkZXJzOiAke0VTQ0FQQUJMRV9GT0xERVJTLmpvaW4oXCIsIFwiKX07IGZpbGVzOiAke0VTQ0FQQUJMRV9GSUxFUy5qb2luKFwiLCBcIil9KWAsXG4gICAgKVxuICB9XG5cbiAgY29uc3Qgc3JjID0gam9pbihwcm9wcy5zb3VyY2VSb290LCBwcm9wcy5wYXRoKVxuICBpZiAoIWV4aXN0c1N5bmMoc3JjKSB8fCAhc3RhdFN5bmMoc3JjKS5pc0ZpbGUoKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJyR7cHJvcHMucGF0aH0nIGlzIG5vdCBhIGxpdmVtYXJrIGZpbGVgKVxuICB9XG5cbiAgY29uc3QgZGVzdCA9IGpvaW4ocHJvcHMucm9vdCwgXCIubGl2ZW1hcmtcIiwgcHJvcHMucGF0aClcbiAgaWYgKGV4aXN0c1N5bmMoZGVzdCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYC5saXZlbWFyay8ke3Byb3BzLnBhdGh9IGFscmVhZHkgZXhpc3RzYClcbiAgfVxuXG4gIG1rZGlyU3luYyhkaXJuYW1lKGRlc3QpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KVxuICB3cml0ZUZpbGVTeW5jKGRlc3QsIHJlYWRGaWxlU3luYyhzcmMpKVxuICByZXR1cm4gZGVzdFxufVxuIl19
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,37 @@
1
+ import fs from "node:fs";
2
+ import { join } from "node:path";
3
+ import { temporaryDirectoryTask } from "tempy";
4
+ import { describe, expect, it } from "vite-plus/test";
5
+ import { copyEscape } from "./copy.js";
6
+ describe("copyEscape", () => {
7
+ it("should copy a default into .livemark/", () => temporaryDirectoryTask(async (tmpDir) => {
8
+ const sourceRoot = createSource(tmpDir);
9
+ const dest = copyEscape({ root: tmpDir, sourceRoot, path: "components/Footer.tsx" });
10
+ expect(dest).toBe(join(tmpDir, ".livemark", "components", "Footer.tsx"));
11
+ expect(fs.readFileSync(dest, "utf8")).toBe("default\n");
12
+ }));
13
+ it("should refuse to overwrite an existing override", () => temporaryDirectoryTask(async (tmpDir) => {
14
+ const sourceRoot = createSource(tmpDir);
15
+ copyEscape({ root: tmpDir, sourceRoot, path: "client.tsx" });
16
+ expect(() => copyEscape({ root: tmpDir, sourceRoot, path: "client.tsx" })).toThrow(/already exists/);
17
+ }));
18
+ it("should reject paths outside the escape contract", () => temporaryDirectoryTask(async (tmpDir) => {
19
+ const sourceRoot = createSource(tmpDir);
20
+ for (const path of ["index.ts", "components/../index.ts", "helpers/toc.ts"]) {
21
+ expect(() => copyEscape({ root: tmpDir, sourceRoot, path })).toThrow(/not escapable/);
22
+ }
23
+ }));
24
+ it("should reject an escapable path with no livemark file", () => temporaryDirectoryTask(async (tmpDir) => {
25
+ const sourceRoot = createSource(tmpDir);
26
+ expect(() => copyEscape({ root: tmpDir, sourceRoot, path: "components/Missing.tsx" })).toThrow(/not a livemark file/);
27
+ }));
28
+ });
29
+ function createSource(tmpDir) {
30
+ const sourceRoot = join(tmpDir, "source");
31
+ fs.mkdirSync(join(sourceRoot, "components"), { recursive: true });
32
+ fs.writeFileSync(join(sourceRoot, "components", "Footer.tsx"), "default\n");
33
+ fs.writeFileSync(join(sourceRoot, "client.tsx"), "default\n");
34
+ fs.writeFileSync(join(sourceRoot, "index.ts"), "default\n");
35
+ return sourceRoot;
36
+ }
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29weS51bml0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc291cmNlL2FjdGlvbnMvZXNjYXBlL2NvcHkudW5pdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxTQUFTLENBQUE7QUFDeEIsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUNoQyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxPQUFPLENBQUE7QUFDOUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0JBQWdCLENBQUE7QUFDckQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUV0QyxRQUFRLENBQUMsWUFBWSxFQUFFLEdBQUcsRUFBRTtJQUMxQixFQUFFLENBQUMsdUNBQXVDLEVBQUUsR0FBRyxFQUFFLENBQy9DLHNCQUFzQixDQUFDLEtBQUssRUFBQyxNQUFNLEVBQUMsRUFBRTtRQUNwQyxNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDdkMsTUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLHVCQUF1QixFQUFFLENBQUMsQ0FBQTtRQUNwRixNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFBO1FBQ3hFLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQTtJQUN6RCxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBRUwsRUFBRSxDQUFDLGlEQUFpRCxFQUFFLEdBQUcsRUFBRSxDQUN6RCxzQkFBc0IsQ0FBQyxLQUFLLEVBQUMsTUFBTSxFQUFDLEVBQUU7UUFDcEMsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ3ZDLFVBQVUsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFBO1FBQzVELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxVQUFVLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FDaEYsZ0JBQWdCLENBQ2pCLENBQUE7SUFDSCxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBRUwsRUFBRSxDQUFDLGlEQUFpRCxFQUFFLEdBQUcsRUFBRSxDQUN6RCxzQkFBc0IsQ0FBQyxLQUFLLEVBQUMsTUFBTSxFQUFDLEVBQUU7UUFDcEMsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ3ZDLEtBQUssTUFBTSxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsd0JBQXdCLEVBQUUsZ0JBQWdCLENBQUMsRUFBRSxDQUFDO1lBQzVFLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxVQUFVLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUNsRSxlQUFlLENBQ2hCLENBQUE7UUFDSCxDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUVMLEVBQUUsQ0FBQyx1REFBdUQsRUFBRSxHQUFHLEVBQUUsQ0FDL0Qsc0JBQXNCLENBQUMsS0FBSyxFQUFDLE1BQU0sRUFBQyxFQUFFO1FBQ3BDLE1BQU0sVUFBVSxHQUFHLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUN2QyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQ1YsVUFBVSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLHdCQUF3QixFQUFFLENBQUMsQ0FDekUsQ0FBQyxPQUFPLENBQUMscUJBQXFCLENBQUMsQ0FBQTtJQUNsQyxDQUFDLENBQUMsQ0FBQyxDQUFBO0FBQ1AsQ0FBQyxDQUFDLENBQUE7QUFFRixTQUFTLFlBQVksQ0FBQyxNQUFjO0lBQ2xDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUE7SUFDekMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFlBQVksQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7SUFDakUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFlBQVksRUFBRSxZQUFZLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQTtJQUMzRSxFQUFFLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsWUFBWSxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUE7SUFDN0QsRUFBRSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFBO0lBQzNELE9BQU8sVUFBVSxDQUFBO0FBQ25CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZnMgZnJvbSBcIm5vZGU6ZnNcIlxuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIlxuaW1wb3J0IHsgdGVtcG9yYXJ5RGlyZWN0b3J5VGFzayB9IGZyb20gXCJ0ZW1weVwiXG5pbXBvcnQgeyBkZXNjcmliZSwgZXhwZWN0LCBpdCB9IGZyb20gXCJ2aXRlLXBsdXMvdGVzdFwiXG5pbXBvcnQgeyBjb3B5RXNjYXBlIH0gZnJvbSBcIi4vY29weS50c1wiXG5cbmRlc2NyaWJlKFwiY29weUVzY2FwZVwiLCAoKSA9PiB7XG4gIGl0KFwic2hvdWxkIGNvcHkgYSBkZWZhdWx0IGludG8gLmxpdmVtYXJrL1wiLCAoKSA9PlxuICAgIHRlbXBvcmFyeURpcmVjdG9yeVRhc2soYXN5bmMgdG1wRGlyID0+IHtcbiAgICAgIGNvbnN0IHNvdXJjZVJvb3QgPSBjcmVhdGVTb3VyY2UodG1wRGlyKVxuICAgICAgY29uc3QgZGVzdCA9IGNvcHlFc2NhcGUoeyByb290OiB0bXBEaXIsIHNvdXJjZVJvb3QsIHBhdGg6IFwiY29tcG9uZW50cy9Gb290ZXIudHN4XCIgfSlcbiAgICAgIGV4cGVjdChkZXN0KS50b0JlKGpvaW4odG1wRGlyLCBcIi5saXZlbWFya1wiLCBcImNvbXBvbmVudHNcIiwgXCJGb290ZXIudHN4XCIpKVxuICAgICAgZXhwZWN0KGZzLnJlYWRGaWxlU3luYyhkZXN0LCBcInV0ZjhcIikpLnRvQmUoXCJkZWZhdWx0XFxuXCIpXG4gICAgfSkpXG5cbiAgaXQoXCJzaG91bGQgcmVmdXNlIHRvIG92ZXJ3cml0ZSBhbiBleGlzdGluZyBvdmVycmlkZVwiLCAoKSA9PlxuICAgIHRlbXBvcmFyeURpcmVjdG9yeVRhc2soYXN5bmMgdG1wRGlyID0+IHtcbiAgICAgIGNvbnN0IHNvdXJjZVJvb3QgPSBjcmVhdGVTb3VyY2UodG1wRGlyKVxuICAgICAgY29weUVzY2FwZSh7IHJvb3Q6IHRtcERpciwgc291cmNlUm9vdCwgcGF0aDogXCJjbGllbnQudHN4XCIgfSlcbiAgICAgIGV4cGVjdCgoKSA9PiBjb3B5RXNjYXBlKHsgcm9vdDogdG1wRGlyLCBzb3VyY2VSb290LCBwYXRoOiBcImNsaWVudC50c3hcIiB9KSkudG9UaHJvdyhcbiAgICAgICAgL2FscmVhZHkgZXhpc3RzLyxcbiAgICAgIClcbiAgICB9KSlcblxuICBpdChcInNob3VsZCByZWplY3QgcGF0aHMgb3V0c2lkZSB0aGUgZXNjYXBlIGNvbnRyYWN0XCIsICgpID0+XG4gICAgdGVtcG9yYXJ5RGlyZWN0b3J5VGFzayhhc3luYyB0bXBEaXIgPT4ge1xuICAgICAgY29uc3Qgc291cmNlUm9vdCA9IGNyZWF0ZVNvdXJjZSh0bXBEaXIpXG4gICAgICBmb3IgKGNvbnN0IHBhdGggb2YgW1wiaW5kZXgudHNcIiwgXCJjb21wb25lbnRzLy4uL2luZGV4LnRzXCIsIFwiaGVscGVycy90b2MudHNcIl0pIHtcbiAgICAgICAgZXhwZWN0KCgpID0+IGNvcHlFc2NhcGUoeyByb290OiB0bXBEaXIsIHNvdXJjZVJvb3QsIHBhdGggfSkpLnRvVGhyb3coXG4gICAgICAgICAgL25vdCBlc2NhcGFibGUvLFxuICAgICAgICApXG4gICAgICB9XG4gICAgfSkpXG5cbiAgaXQoXCJzaG91bGQgcmVqZWN0IGFuIGVzY2FwYWJsZSBwYXRoIHdpdGggbm8gbGl2ZW1hcmsgZmlsZVwiLCAoKSA9PlxuICAgIHRlbXBvcmFyeURpcmVjdG9yeVRhc2soYXN5bmMgdG1wRGlyID0+IHtcbiAgICAgIGNvbnN0IHNvdXJjZVJvb3QgPSBjcmVhdGVTb3VyY2UodG1wRGlyKVxuICAgICAgZXhwZWN0KCgpID0+XG4gICAgICAgIGNvcHlFc2NhcGUoeyByb290OiB0bXBEaXIsIHNvdXJjZVJvb3QsIHBhdGg6IFwiY29tcG9uZW50cy9NaXNzaW5nLnRzeFwiIH0pLFxuICAgICAgKS50b1Rocm93KC9ub3QgYSBsaXZlbWFyayBmaWxlLylcbiAgICB9KSlcbn0pXG5cbmZ1bmN0aW9uIGNyZWF0ZVNvdXJjZSh0bXBEaXI6IHN0cmluZykge1xuICBjb25zdCBzb3VyY2VSb290ID0gam9pbih0bXBEaXIsIFwic291cmNlXCIpXG4gIGZzLm1rZGlyU3luYyhqb2luKHNvdXJjZVJvb3QsIFwiY29tcG9uZW50c1wiKSwgeyByZWN1cnNpdmU6IHRydWUgfSlcbiAgZnMud3JpdGVGaWxlU3luYyhqb2luKHNvdXJjZVJvb3QsIFwiY29tcG9uZW50c1wiLCBcIkZvb3Rlci50c3hcIiksIFwiZGVmYXVsdFxcblwiKVxuICBmcy53cml0ZUZpbGVTeW5jKGpvaW4oc291cmNlUm9vdCwgXCJjbGllbnQudHN4XCIpLCBcImRlZmF1bHRcXG5cIilcbiAgZnMud3JpdGVGaWxlU3luYyhqb2luKHNvdXJjZVJvb3QsIFwiaW5kZXgudHNcIiksIFwiZGVmYXVsdFxcblwiKVxuICByZXR1cm4gc291cmNlUm9vdFxufVxuIl19
@@ -0,0 +1,12 @@
1
+ /** An escapable livemark file and whether the project already shadows it. */
2
+ export interface Escape {
3
+ path: string;
4
+ escaped: boolean;
5
+ }
6
+ /**
7
+ * List every file a project can shadow under `.livemark/`, sorted by path.
8
+ */
9
+ export declare function listEscapes(props: {
10
+ root: string;
11
+ sourceRoot: string;
12
+ }): Escape[];
@@ -0,0 +1,27 @@
1
+ import { existsSync, readdirSync, statSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { ESCAPABLE_FILES, ESCAPABLE_FOLDERS } from "../../settings.js";
4
+ /**
5
+ * List every file a project can shadow under `.livemark/`, sorted by path.
6
+ */
7
+ export function listEscapes(props) {
8
+ const paths = [];
9
+ for (const folder of ESCAPABLE_FOLDERS) {
10
+ const dir = join(props.sourceRoot, folder);
11
+ if (!existsSync(dir))
12
+ continue;
13
+ for (const entry of readdirSync(dir)) {
14
+ if (statSync(join(dir, entry)).isFile())
15
+ paths.push(`${folder}/${entry}`);
16
+ }
17
+ }
18
+ for (const file of ESCAPABLE_FILES) {
19
+ if (existsSync(join(props.sourceRoot, file)))
20
+ paths.push(file);
21
+ }
22
+ return paths.sort().map((path) => ({
23
+ path,
24
+ escaped: existsSync(join(props.root, ".livemark", path)),
25
+ }));
26
+ }
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NvdXJjZS9hY3Rpb25zL2VzY2FwZS9saXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxNQUFNLFNBQVMsQ0FBQTtBQUMzRCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQ2hDLE9BQU8sRUFBRSxlQUFlLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQVF0RTs7R0FFRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQUMsS0FBMkM7SUFDckUsTUFBTSxLQUFLLEdBQWEsRUFBRSxDQUFBO0lBQzFCLEtBQUssTUFBTSxNQUFNLElBQUksaUJBQWlCLEVBQUUsQ0FBQztRQUN2QyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQTtRQUMxQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQztZQUFFLFNBQVE7UUFDOUIsS0FBSyxNQUFNLEtBQUssSUFBSSxXQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNyQyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFO2dCQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLElBQUksS0FBSyxFQUFFLENBQUMsQ0FBQTtRQUMzRSxDQUFDO0lBQ0gsQ0FBQztJQUNELEtBQUssTUFBTSxJQUFJLElBQUksZUFBZSxFQUFFLENBQUM7UUFDbkMsSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ2hFLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQVUsRUFBRSxDQUFDLENBQUM7UUFDekMsSUFBSTtRQUNKLE9BQU8sRUFBRSxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxDQUFDO0tBQ3pELENBQUMsQ0FBQyxDQUFBO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGV4aXN0c1N5bmMsIHJlYWRkaXJTeW5jLCBzdGF0U3luYyB9IGZyb20gXCJub2RlOmZzXCJcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCJcbmltcG9ydCB7IEVTQ0FQQUJMRV9GSUxFUywgRVNDQVBBQkxFX0ZPTERFUlMgfSBmcm9tIFwiLi4vLi4vc2V0dGluZ3MudHNcIlxuXG4vKiogQW4gZXNjYXBhYmxlIGxpdmVtYXJrIGZpbGUgYW5kIHdoZXRoZXIgdGhlIHByb2plY3QgYWxyZWFkeSBzaGFkb3dzIGl0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBFc2NhcGUge1xuICBwYXRoOiBzdHJpbmdcbiAgZXNjYXBlZDogYm9vbGVhblxufVxuXG4vKipcbiAqIExpc3QgZXZlcnkgZmlsZSBhIHByb2plY3QgY2FuIHNoYWRvdyB1bmRlciBgLmxpdmVtYXJrL2AsIHNvcnRlZCBieSBwYXRoLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbGlzdEVzY2FwZXMocHJvcHM6IHsgcm9vdDogc3RyaW5nOyBzb3VyY2VSb290OiBzdHJpbmcgfSkge1xuICBjb25zdCBwYXRoczogc3RyaW5nW10gPSBbXVxuICBmb3IgKGNvbnN0IGZvbGRlciBvZiBFU0NBUEFCTEVfRk9MREVSUykge1xuICAgIGNvbnN0IGRpciA9IGpvaW4ocHJvcHMuc291cmNlUm9vdCwgZm9sZGVyKVxuICAgIGlmICghZXhpc3RzU3luYyhkaXIpKSBjb250aW51ZVxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgcmVhZGRpclN5bmMoZGlyKSkge1xuICAgICAgaWYgKHN0YXRTeW5jKGpvaW4oZGlyLCBlbnRyeSkpLmlzRmlsZSgpKSBwYXRocy5wdXNoKGAke2ZvbGRlcn0vJHtlbnRyeX1gKVxuICAgIH1cbiAgfVxuICBmb3IgKGNvbnN0IGZpbGUgb2YgRVNDQVBBQkxFX0ZJTEVTKSB7XG4gICAgaWYgKGV4aXN0c1N5bmMoam9pbihwcm9wcy5zb3VyY2VSb290LCBmaWxlKSkpIHBhdGhzLnB1c2goZmlsZSlcbiAgfVxuICByZXR1cm4gcGF0aHMuc29ydCgpLm1hcCgocGF0aCk6IEVzY2FwZSA9PiAoe1xuICAgIHBhdGgsXG4gICAgZXNjYXBlZDogZXhpc3RzU3luYyhqb2luKHByb3BzLnJvb3QsIFwiLmxpdmVtYXJrXCIsIHBhdGgpKSxcbiAgfSkpXG59XG4iXX0=
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
1
+ import fs from "node:fs";
2
+ import { join } from "node:path";
3
+ import { temporaryDirectoryTask } from "tempy";
4
+ import { describe, expect, it } from "vite-plus/test";
5
+ import { listEscapes } from "./list.js";
6
+ describe("listEscapes", () => {
7
+ it("should list folder files and top-level files, sorted", () => temporaryDirectoryTask(async (tmpDir) => {
8
+ const sourceRoot = join(tmpDir, "source");
9
+ writeFile(join(sourceRoot, "components", "Footer.tsx"));
10
+ writeFile(join(sourceRoot, "styles", "general.css"));
11
+ writeFile(join(sourceRoot, "client.tsx"));
12
+ writeFile(join(sourceRoot, "index.ts"));
13
+ fs.mkdirSync(join(sourceRoot, "elements", "nested"), { recursive: true });
14
+ const escapes = listEscapes({ root: tmpDir, sourceRoot });
15
+ expect(escapes.map(escape => escape.path)).toEqual([
16
+ "client.tsx",
17
+ "components/Footer.tsx",
18
+ "styles/general.css",
19
+ ]);
20
+ }));
21
+ it("should mark files the project already shadows", () => temporaryDirectoryTask(async (tmpDir) => {
22
+ const sourceRoot = join(tmpDir, "source");
23
+ writeFile(join(sourceRoot, "components", "Footer.tsx"));
24
+ writeFile(join(sourceRoot, "components", "Header.tsx"));
25
+ writeFile(join(tmpDir, ".livemark", "components", "Footer.tsx"));
26
+ expect(listEscapes({ root: tmpDir, sourceRoot })).toEqual([
27
+ { path: "components/Footer.tsx", escaped: true },
28
+ { path: "components/Header.tsx", escaped: false },
29
+ ]);
30
+ }));
31
+ });
32
+ function writeFile(path) {
33
+ fs.mkdirSync(join(path, ".."), { recursive: true });
34
+ fs.writeFileSync(path, "default\n");
35
+ }
36
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC51bml0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc291cmNlL2FjdGlvbnMvZXNjYXBlL2xpc3QudW5pdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxTQUFTLENBQUE7QUFDeEIsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUNoQyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxPQUFPLENBQUE7QUFDOUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0JBQWdCLENBQUE7QUFDckQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUV2QyxRQUFRLENBQUMsYUFBYSxFQUFFLEdBQUcsRUFBRTtJQUMzQixFQUFFLENBQUMsc0RBQXNELEVBQUUsR0FBRyxFQUFFLENBQzlELHNCQUFzQixDQUFDLEtBQUssRUFBQyxNQUFNLEVBQUMsRUFBRTtRQUNwQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFBO1FBQ3pDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFlBQVksRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFBO1FBQ3ZELFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFFBQVEsRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFBO1FBQ3BELFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUE7UUFDekMsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQTtRQUN2QyxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLFFBQVEsQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7UUFFekUsTUFBTSxPQUFPLEdBQUcsV0FBVyxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFBO1FBQ3pELE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQ2pELFlBQVk7WUFDWix1QkFBdUI7WUFDdkIsb0JBQW9CO1NBQ3JCLENBQUMsQ0FBQTtJQUNKLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFFTCxFQUFFLENBQUMsK0NBQStDLEVBQUUsR0FBRyxFQUFFLENBQ3ZELHNCQUFzQixDQUFDLEtBQUssRUFBQyxNQUFNLEVBQUMsRUFBRTtRQUNwQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFBO1FBQ3pDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFlBQVksRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFBO1FBQ3ZELFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFlBQVksRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFBO1FBQ3ZELFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQTtRQUVoRSxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQ3hELEVBQUUsSUFBSSxFQUFFLHVCQUF1QixFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUU7WUFDaEQsRUFBRSxJQUFJLEVBQUUsdUJBQXVCLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRTtTQUNsRCxDQUFDLENBQUE7SUFDSixDQUFDLENBQUMsQ0FBQyxDQUFBO0FBQ1AsQ0FBQyxDQUFDLENBQUE7QUFFRixTQUFTLFNBQVMsQ0FBQyxJQUFZO0lBQzdCLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFBO0lBQ25ELEVBQUUsQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFBO0FBQ3JDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZnMgZnJvbSBcIm5vZGU6ZnNcIlxuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIlxuaW1wb3J0IHsgdGVtcG9yYXJ5RGlyZWN0b3J5VGFzayB9IGZyb20gXCJ0ZW1weVwiXG5pbXBvcnQgeyBkZXNjcmliZSwgZXhwZWN0LCBpdCB9IGZyb20gXCJ2aXRlLXBsdXMvdGVzdFwiXG5pbXBvcnQgeyBsaXN0RXNjYXBlcyB9IGZyb20gXCIuL2xpc3QudHNcIlxuXG5kZXNjcmliZShcImxpc3RFc2NhcGVzXCIsICgpID0+IHtcbiAgaXQoXCJzaG91bGQgbGlzdCBmb2xkZXIgZmlsZXMgYW5kIHRvcC1sZXZlbCBmaWxlcywgc29ydGVkXCIsICgpID0+XG4gICAgdGVtcG9yYXJ5RGlyZWN0b3J5VGFzayhhc3luYyB0bXBEaXIgPT4ge1xuICAgICAgY29uc3Qgc291cmNlUm9vdCA9IGpvaW4odG1wRGlyLCBcInNvdXJjZVwiKVxuICAgICAgd3JpdGVGaWxlKGpvaW4oc291cmNlUm9vdCwgXCJjb21wb25lbnRzXCIsIFwiRm9vdGVyLnRzeFwiKSlcbiAgICAgIHdyaXRlRmlsZShqb2luKHNvdXJjZVJvb3QsIFwic3R5bGVzXCIsIFwiZ2VuZXJhbC5jc3NcIikpXG4gICAgICB3cml0ZUZpbGUoam9pbihzb3VyY2VSb290LCBcImNsaWVudC50c3hcIikpXG4gICAgICB3cml0ZUZpbGUoam9pbihzb3VyY2VSb290LCBcImluZGV4LnRzXCIpKVxuICAgICAgZnMubWtkaXJTeW5jKGpvaW4oc291cmNlUm9vdCwgXCJlbGVtZW50c1wiLCBcIm5lc3RlZFwiKSwgeyByZWN1cnNpdmU6IHRydWUgfSlcblxuICAgICAgY29uc3QgZXNjYXBlcyA9IGxpc3RFc2NhcGVzKHsgcm9vdDogdG1wRGlyLCBzb3VyY2VSb290IH0pXG4gICAgICBleHBlY3QoZXNjYXBlcy5tYXAoZXNjYXBlID0+IGVzY2FwZS5wYXRoKSkudG9FcXVhbChbXG4gICAgICAgIFwiY2xpZW50LnRzeFwiLFxuICAgICAgICBcImNvbXBvbmVudHMvRm9vdGVyLnRzeFwiLFxuICAgICAgICBcInN0eWxlcy9nZW5lcmFsLmNzc1wiLFxuICAgICAgXSlcbiAgICB9KSlcblxuICBpdChcInNob3VsZCBtYXJrIGZpbGVzIHRoZSBwcm9qZWN0IGFscmVhZHkgc2hhZG93c1wiLCAoKSA9PlxuICAgIHRlbXBvcmFyeURpcmVjdG9yeVRhc2soYXN5bmMgdG1wRGlyID0+IHtcbiAgICAgIGNvbnN0IHNvdXJjZVJvb3QgPSBqb2luKHRtcERpciwgXCJzb3VyY2VcIilcbiAgICAgIHdyaXRlRmlsZShqb2luKHNvdXJjZVJvb3QsIFwiY29tcG9uZW50c1wiLCBcIkZvb3Rlci50c3hcIikpXG4gICAgICB3cml0ZUZpbGUoam9pbihzb3VyY2VSb290LCBcImNvbXBvbmVudHNcIiwgXCJIZWFkZXIudHN4XCIpKVxuICAgICAgd3JpdGVGaWxlKGpvaW4odG1wRGlyLCBcIi5saXZlbWFya1wiLCBcImNvbXBvbmVudHNcIiwgXCJGb290ZXIudHN4XCIpKVxuXG4gICAgICBleHBlY3QobGlzdEVzY2FwZXMoeyByb290OiB0bXBEaXIsIHNvdXJjZVJvb3QgfSkpLnRvRXF1YWwoW1xuICAgICAgICB7IHBhdGg6IFwiY29tcG9uZW50cy9Gb290ZXIudHN4XCIsIGVzY2FwZWQ6IHRydWUgfSxcbiAgICAgICAgeyBwYXRoOiBcImNvbXBvbmVudHMvSGVhZGVyLnRzeFwiLCBlc2NhcGVkOiBmYWxzZSB9LFxuICAgICAgXSlcbiAgICB9KSlcbn0pXG5cbmZ1bmN0aW9uIHdyaXRlRmlsZShwYXRoOiBzdHJpbmcpIHtcbiAgZnMubWtkaXJTeW5jKGpvaW4ocGF0aCwgXCIuLlwiKSwgeyByZWN1cnNpdmU6IHRydWUgfSlcbiAgZnMud3JpdGVGaWxlU3luYyhwYXRoLCBcImRlZmF1bHRcXG5cIilcbn1cbiJdfQ==
@@ -1,29 +1,12 @@
1
1
  /**
2
- * Synthesize a fully self-contained per-consumer Vite mount at
3
- * `<livemark-pkg>/targets/<hash>/`.
4
- *
5
- * The mount is built by copying livemark's `source/` wholesale, then
6
- * overlaying any matching files from the consumer's `.livemark/`. Every
7
- * file lives at its target path as a real file — no symlinks — so
8
- * Vite's relative-import and bare-specifier resolution all anchor
9
- * inside the target dir, where node_modules walks reach livemark's pnpm
10
- * subtree natively.
11
- *
12
- * Behavior:
13
- * - First run (target dir missing): full source copy + overlay.
14
- * - Subsequent runs: skip the source copy. Source is immutable in
15
- * installed mode; in livemark's own dev the watcher keeps the target
16
- * in sync. Only the `.livemark/` overlay is re-applied each time —
17
- * cheap, and may have changed between runs.
18
- * - With `--clear` in argv: wipe the entire target dir (including
19
- * downstream caches like `.vite/`, `.content-collections/`,
20
- * `cache/`, `routeTree.gen.ts`) and rebuild from scratch. Use this
21
- * to recover from a stale or corrupted cache.
22
- *
23
- * Returns the absolute path to the target dir.
2
+ * Synthesize the project's Vite mount at `.livemark/.target/`: livemark's `source/` with
3
+ * the project's `.livemark/` escapes copied over it, plus a `node_modules` link to
4
+ * livemark's dependencies. Escapable folders are rebuilt on every run, so a removed escape
5
+ * never keeps rendering. Returns the target dir.
24
6
  */
25
- export declare function buildTarget(configPath: string): string;
26
- /** Compute the target dir for a given consumer config path without
27
- * rebuilding it. Used by code that needs to write into the target
28
- * (e.g. cache writers) outside of `buildTarget`'s setup phase. */
7
+ export declare function buildTarget(props: {
8
+ configPath: string;
9
+ sourceDir: string;
10
+ }): string;
11
+ /** Locate the project's target dir without building it. */
29
12
  export declare function targetDirFor(configPath: string): string;
@@ -1,84 +1,63 @@
1
- import { createHash } from "node:crypto";
2
- import { cpSync, existsSync, mkdirSync, readdirSync, rmSync } from "node:fs";
3
- import { dirname, join } from "node:path";
1
+ import { cpSync, existsSync, mkdirSync, readlinkSync, rmSync, symlinkSync } from "node:fs";
2
+ import { basename, dirname, join, relative, resolve } from "node:path";
3
+ import { resolveDependencyDir } from "../../helpers/dependency-dir.js";
4
4
  import { ESCAPABLE_FILES, ESCAPABLE_FOLDERS } from "../../settings.js";
5
- // This file ships at <livemark-pkg>/source/actions/target/build.ts AND
6
- // gets copied into <livemark-pkg>/targets/<hash>/actions/target/build.ts
7
- // as part of every per-consumer mount. content-collections loads the
8
- // COPIED version, so `import.meta.dirname` can land inside `targets/`.
9
- // Walk up to the first directory holding livemark's `package.json` so
10
- // SOURCE_DIR / TARGETS_ROOT always anchor at the package, never at a
11
- // per-consumer dir.
12
- const LIVEMARK_PKG = findLivemarkPkg(import.meta.dirname);
13
- const SOURCE_DIR = join(LIVEMARK_PKG, "source");
14
- const TARGETS_ROOT = join(LIVEMARK_PKG, "targets");
15
- function findLivemarkPkg(start) {
16
- let cur = start;
17
- while (cur !== dirname(cur)) {
18
- if (existsSync(join(cur, "package.json")))
19
- return cur;
20
- cur = dirname(cur);
21
- }
22
- throw new Error(`Could not locate livemark package root from ${start}`);
23
- }
24
5
  /**
25
- * Synthesize a fully self-contained per-consumer Vite mount at
26
- * `<livemark-pkg>/targets/<hash>/`.
27
- *
28
- * The mount is built by copying livemark's `source/` wholesale, then
29
- * overlaying any matching files from the consumer's `.livemark/`. Every
30
- * file lives at its target path as a real file — no symlinks — so
31
- * Vite's relative-import and bare-specifier resolution all anchor
32
- * inside the target dir, where node_modules walks reach livemark's pnpm
33
- * subtree natively.
34
- *
35
- * Behavior:
36
- * - First run (target dir missing): full source copy + overlay.
37
- * - Subsequent runs: skip the source copy. Source is immutable in
38
- * installed mode; in livemark's own dev the watcher keeps the target
39
- * in sync. Only the `.livemark/` overlay is re-applied each time —
40
- * cheap, and may have changed between runs.
41
- * - With `--clear` in argv: wipe the entire target dir (including
42
- * downstream caches like `.vite/`, `.content-collections/`,
43
- * `cache/`, `routeTree.gen.ts`) and rebuild from scratch. Use this
44
- * to recover from a stale or corrupted cache.
45
- *
46
- * Returns the absolute path to the target dir.
6
+ * Synthesize the project's Vite mount at `.livemark/.target/`: livemark's `source/` with
7
+ * the project's `.livemark/` escapes copied over it, plus a `node_modules` link to
8
+ * livemark's dependencies. Escapable folders are rebuilt on every run, so a removed escape
9
+ * never keeps rendering. Returns the target dir.
47
10
  */
48
- export function buildTarget(configPath) {
49
- const targetDir = targetDirFor(configPath);
50
- const overridesRoot = join(dirname(configPath), ".livemark");
51
- const clear = process.argv.includes("--clear");
52
- if (clear)
53
- rmSync(targetDir, { recursive: true, force: true });
54
- if (!existsSync(targetDir)) {
55
- mkdirSync(targetDir, { recursive: true });
56
- cpSync(SOURCE_DIR, targetDir, { recursive: true });
57
- }
11
+ export function buildTarget(props) {
12
+ const targetDir = targetDirFor(props.configPath);
13
+ const overridesRoot = dirname(targetDir);
14
+ mkdirSync(targetDir, { recursive: true });
15
+ cpSync(props.sourceDir, targetDir, {
16
+ recursive: true,
17
+ filter: src => isPackageFile(src) && !isEscapableFolder(src, props.sourceDir),
18
+ });
58
19
  for (const folder of ESCAPABLE_FOLDERS) {
59
- const overlay = join(overridesRoot, folder);
60
- if (!existsSync(overlay))
61
- continue;
62
20
  const dest = join(targetDir, folder);
63
- if (!existsSync(dest))
64
- mkdirSync(dest, { recursive: true });
65
- for (const f of readdirSync(overlay)) {
66
- cpSync(join(overlay, f), join(dest, f), { recursive: true, force: true });
67
- }
21
+ rmSync(dest, { recursive: true, force: true });
22
+ const source = join(props.sourceDir, folder);
23
+ if (existsSync(source))
24
+ cpSync(source, dest, { recursive: true, filter: isPackageFile });
25
+ const overlay = join(overridesRoot, folder);
26
+ if (existsSync(overlay))
27
+ cpSync(overlay, dest, { recursive: true });
68
28
  }
69
29
  for (const file of ESCAPABLE_FILES) {
70
30
  const overlay = join(overridesRoot, file);
71
- if (!existsSync(overlay))
72
- continue;
73
- cpSync(overlay, join(targetDir, file), { force: true });
31
+ if (existsSync(overlay))
32
+ cpSync(overlay, join(targetDir, file));
74
33
  }
34
+ linkDependencies(targetDir, resolveDependencyDir(props.sourceDir));
75
35
  return targetDir;
76
36
  }
77
- /** Compute the target dir for a given consumer config path without
78
- * rebuilding it. Used by code that needs to write into the target
79
- * (e.g. cache writers) outside of `buildTarget`'s setup phase. */
37
+ /** Locate the project's target dir without building it. */
80
38
  export function targetDirFor(configPath) {
81
- const hash = createHash("sha256").update(configPath).digest("hex").slice(0, 16);
82
- return join(TARGETS_ROOT, hash);
39
+ return join(dirname(configPath), ".livemark", ".target");
40
+ }
41
+ function isPackageFile(src) {
42
+ return !/\.unit\.tsx?$/.test(src) && basename(src) !== "fixtures";
43
+ }
44
+ function isEscapableFolder(src, sourceDir) {
45
+ return ESCAPABLE_FOLDERS.includes(relative(sourceDir, src));
46
+ }
47
+ function linkDependencies(targetDir, dependencyDir) {
48
+ const link = join(targetDir, "node_modules");
49
+ if (readLink(link) === resolve(dependencyDir))
50
+ return;
51
+ // Not recursive: a stale link must go without touching the store it points into.
52
+ rmSync(link, { force: true });
53
+ symlinkSync(dependencyDir, link, "junction");
54
+ }
55
+ function readLink(path) {
56
+ try {
57
+ return resolve(dirname(path), readlinkSync(path));
58
+ }
59
+ catch {
60
+ return undefined;
61
+ }
83
62
  }
84
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zb3VyY2UvYWN0aW9ucy90YXJnZXQvYnVpbGQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUN4QyxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxNQUFNLFNBQVMsQ0FBQTtBQUM1RSxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUN6QyxPQUFPLEVBQUUsZUFBZSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFFdEUsdUVBQXVFO0FBQ3ZFLHlFQUF5RTtBQUN6RSxxRUFBcUU7QUFDckUsdUVBQXVFO0FBQ3ZFLHNFQUFzRTtBQUN0RSxxRUFBcUU7QUFDckUsb0JBQW9CO0FBQ3BCLE1BQU0sWUFBWSxHQUFHLGVBQWUsQ0FBQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQTtBQUN6RCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLFFBQVEsQ0FBQyxDQUFBO0FBQy9DLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsU0FBUyxDQUFDLENBQUE7QUFFbEQsU0FBUyxlQUFlLENBQUMsS0FBYTtJQUNwQyxJQUFJLEdBQUcsR0FBRyxLQUFLLENBQUE7SUFDZixPQUFPLEdBQUcsS0FBSyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUM1QixJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLGNBQWMsQ0FBQyxDQUFDO1lBQUUsT0FBTyxHQUFHLENBQUE7UUFDckQsR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUNwQixDQUFDO0lBQ0QsTUFBTSxJQUFJLEtBQUssQ0FBQywrQ0FBK0MsS0FBSyxFQUFFLENBQUMsQ0FBQTtBQUN6RSxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBdUJHO0FBQ0gsTUFBTSxVQUFVLFdBQVcsQ0FBQyxVQUFrQjtJQUM1QyxNQUFNLFNBQVMsR0FBRyxZQUFZLENBQUMsVUFBVSxDQUFDLENBQUE7SUFDMUMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQTtJQUM1RCxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUU5QyxJQUFJLEtBQUs7UUFBRSxNQUFNLENBQUMsU0FBUyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUU5RCxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDM0IsU0FBUyxDQUFDLFNBQVMsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFBO1FBQ3pDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsU0FBUyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7SUFDcEQsQ0FBQztJQUVELEtBQUssTUFBTSxNQUFNLElBQUksaUJBQWlCLEVBQUUsQ0FBQztRQUN2QyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBQzNDLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDO1lBQUUsU0FBUTtRQUNsQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBQ3BDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDO1lBQUUsU0FBUyxDQUFDLElBQUksRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFBO1FBQzNELEtBQUssTUFBTSxDQUFDLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDckMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7UUFDM0UsQ0FBQztJQUNILENBQUM7SUFDRCxLQUFLLE1BQU0sSUFBSSxJQUFJLGVBQWUsRUFBRSxDQUFDO1FBQ25DLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLENBQUE7UUFDekMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUM7WUFBRSxTQUFRO1FBQ2xDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFBO0lBQ3pELENBQUM7SUFFRCxPQUFPLFNBQVMsQ0FBQTtBQUNsQixDQUFDO0FBRUQ7O21FQUVtRTtBQUNuRSxNQUFNLFVBQVUsWUFBWSxDQUFDLFVBQWtCO0lBQzdDLE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUE7SUFDL0UsT0FBTyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxDQUFBO0FBQ2pDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVIYXNoIH0gZnJvbSBcIm5vZGU6Y3J5cHRvXCJcbmltcG9ydCB7IGNwU3luYywgZXhpc3RzU3luYywgbWtkaXJTeW5jLCByZWFkZGlyU3luYywgcm1TeW5jIH0gZnJvbSBcIm5vZGU6ZnNcIlxuaW1wb3J0IHsgZGlybmFtZSwgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIlxuaW1wb3J0IHsgRVNDQVBBQkxFX0ZJTEVTLCBFU0NBUEFCTEVfRk9MREVSUyB9IGZyb20gXCIuLi8uLi9zZXR0aW5ncy50c1wiXG5cbi8vIFRoaXMgZmlsZSBzaGlwcyBhdCA8bGl2ZW1hcmstcGtnPi9zb3VyY2UvYWN0aW9ucy90YXJnZXQvYnVpbGQudHMgQU5EXG4vLyBnZXRzIGNvcGllZCBpbnRvIDxsaXZlbWFyay1wa2c+L3RhcmdldHMvPGhhc2g+L2FjdGlvbnMvdGFyZ2V0L2J1aWxkLnRzXG4vLyBhcyBwYXJ0IG9mIGV2ZXJ5IHBlci1jb25zdW1lciBtb3VudC4gY29udGVudC1jb2xsZWN0aW9ucyBsb2FkcyB0aGVcbi8vIENPUElFRCB2ZXJzaW9uLCBzbyBgaW1wb3J0Lm1ldGEuZGlybmFtZWAgY2FuIGxhbmQgaW5zaWRlIGB0YXJnZXRzL2AuXG4vLyBXYWxrIHVwIHRvIHRoZSBmaXJzdCBkaXJlY3RvcnkgaG9sZGluZyBsaXZlbWFyaydzIGBwYWNrYWdlLmpzb25gIHNvXG4vLyBTT1VSQ0VfRElSIC8gVEFSR0VUU19ST09UIGFsd2F5cyBhbmNob3IgYXQgdGhlIHBhY2thZ2UsIG5ldmVyIGF0IGFcbi8vIHBlci1jb25zdW1lciBkaXIuXG5jb25zdCBMSVZFTUFSS19QS0cgPSBmaW5kTGl2ZW1hcmtQa2coaW1wb3J0Lm1ldGEuZGlybmFtZSlcbmNvbnN0IFNPVVJDRV9ESVIgPSBqb2luKExJVkVNQVJLX1BLRywgXCJzb3VyY2VcIilcbmNvbnN0IFRBUkdFVFNfUk9PVCA9IGpvaW4oTElWRU1BUktfUEtHLCBcInRhcmdldHNcIilcblxuZnVuY3Rpb24gZmluZExpdmVtYXJrUGtnKHN0YXJ0OiBzdHJpbmcpIHtcbiAgbGV0IGN1ciA9IHN0YXJ0XG4gIHdoaWxlIChjdXIgIT09IGRpcm5hbWUoY3VyKSkge1xuICAgIGlmIChleGlzdHNTeW5jKGpvaW4oY3VyLCBcInBhY2thZ2UuanNvblwiKSkpIHJldHVybiBjdXJcbiAgICBjdXIgPSBkaXJuYW1lKGN1cilcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkIG5vdCBsb2NhdGUgbGl2ZW1hcmsgcGFja2FnZSByb290IGZyb20gJHtzdGFydH1gKVxufVxuXG4vKipcbiAqIFN5bnRoZXNpemUgYSBmdWxseSBzZWxmLWNvbnRhaW5lZCBwZXItY29uc3VtZXIgVml0ZSBtb3VudCBhdFxuICogYDxsaXZlbWFyay1wa2c+L3RhcmdldHMvPGhhc2g+L2AuXG4gKlxuICogVGhlIG1vdW50IGlzIGJ1aWx0IGJ5IGNvcHlpbmcgbGl2ZW1hcmsncyBgc291cmNlL2Agd2hvbGVzYWxlLCB0aGVuXG4gKiBvdmVybGF5aW5nIGFueSBtYXRjaGluZyBmaWxlcyBmcm9tIHRoZSBjb25zdW1lcidzIGAubGl2ZW1hcmsvYC4gRXZlcnlcbiAqIGZpbGUgbGl2ZXMgYXQgaXRzIHRhcmdldCBwYXRoIGFzIGEgcmVhbCBmaWxlIOKAlCBubyBzeW1saW5rcyDigJQgc29cbiAqIFZpdGUncyByZWxhdGl2ZS1pbXBvcnQgYW5kIGJhcmUtc3BlY2lmaWVyIHJlc29sdXRpb24gYWxsIGFuY2hvclxuICogaW5zaWRlIHRoZSB0YXJnZXQgZGlyLCB3aGVyZSBub2RlX21vZHVsZXMgd2Fsa3MgcmVhY2ggbGl2ZW1hcmsncyBwbnBtXG4gKiBzdWJ0cmVlIG5hdGl2ZWx5LlxuICpcbiAqIEJlaGF2aW9yOlxuICogLSBGaXJzdCBydW4gKHRhcmdldCBkaXIgbWlzc2luZyk6IGZ1bGwgc291cmNlIGNvcHkgKyBvdmVybGF5LlxuICogLSBTdWJzZXF1ZW50IHJ1bnM6IHNraXAgdGhlIHNvdXJjZSBjb3B5LiBTb3VyY2UgaXMgaW1tdXRhYmxlIGluXG4gKiAgIGluc3RhbGxlZCBtb2RlOyBpbiBsaXZlbWFyaydzIG93biBkZXYgdGhlIHdhdGNoZXIga2VlcHMgdGhlIHRhcmdldFxuICogICBpbiBzeW5jLiBPbmx5IHRoZSBgLmxpdmVtYXJrL2Agb3ZlcmxheSBpcyByZS1hcHBsaWVkIGVhY2ggdGltZSDigJRcbiAqICAgY2hlYXAsIGFuZCBtYXkgaGF2ZSBjaGFuZ2VkIGJldHdlZW4gcnVucy5cbiAqIC0gV2l0aCBgLS1jbGVhcmAgaW4gYXJndjogd2lwZSB0aGUgZW50aXJlIHRhcmdldCBkaXIgKGluY2x1ZGluZ1xuICogICBkb3duc3RyZWFtIGNhY2hlcyBsaWtlIGAudml0ZS9gLCBgLmNvbnRlbnQtY29sbGVjdGlvbnMvYCxcbiAqICAgYGNhY2hlL2AsIGByb3V0ZVRyZWUuZ2VuLnRzYCkgYW5kIHJlYnVpbGQgZnJvbSBzY3JhdGNoLiBVc2UgdGhpc1xuICogICB0byByZWNvdmVyIGZyb20gYSBzdGFsZSBvciBjb3JydXB0ZWQgY2FjaGUuXG4gKlxuICogUmV0dXJucyB0aGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgdGFyZ2V0IGRpci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkVGFyZ2V0KGNvbmZpZ1BhdGg6IHN0cmluZykge1xuICBjb25zdCB0YXJnZXREaXIgPSB0YXJnZXREaXJGb3IoY29uZmlnUGF0aClcbiAgY29uc3Qgb3ZlcnJpZGVzUm9vdCA9IGpvaW4oZGlybmFtZShjb25maWdQYXRoKSwgXCIubGl2ZW1hcmtcIilcbiAgY29uc3QgY2xlYXIgPSBwcm9jZXNzLmFyZ3YuaW5jbHVkZXMoXCItLWNsZWFyXCIpXG5cbiAgaWYgKGNsZWFyKSBybVN5bmModGFyZ2V0RGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSwgZm9yY2U6IHRydWUgfSlcblxuICBpZiAoIWV4aXN0c1N5bmModGFyZ2V0RGlyKSkge1xuICAgIG1rZGlyU3luYyh0YXJnZXREaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pXG4gICAgY3BTeW5jKFNPVVJDRV9ESVIsIHRhcmdldERpciwgeyByZWN1cnNpdmU6IHRydWUgfSlcbiAgfVxuXG4gIGZvciAoY29uc3QgZm9sZGVyIG9mIEVTQ0FQQUJMRV9GT0xERVJTKSB7XG4gICAgY29uc3Qgb3ZlcmxheSA9IGpvaW4ob3ZlcnJpZGVzUm9vdCwgZm9sZGVyKVxuICAgIGlmICghZXhpc3RzU3luYyhvdmVybGF5KSkgY29udGludWVcbiAgICBjb25zdCBkZXN0ID0gam9pbih0YXJnZXREaXIsIGZvbGRlcilcbiAgICBpZiAoIWV4aXN0c1N5bmMoZGVzdCkpIG1rZGlyU3luYyhkZXN0LCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KVxuICAgIGZvciAoY29uc3QgZiBvZiByZWFkZGlyU3luYyhvdmVybGF5KSkge1xuICAgICAgY3BTeW5jKGpvaW4ob3ZlcmxheSwgZiksIGpvaW4oZGVzdCwgZiksIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KVxuICAgIH1cbiAgfVxuICBmb3IgKGNvbnN0IGZpbGUgb2YgRVNDQVBBQkxFX0ZJTEVTKSB7XG4gICAgY29uc3Qgb3ZlcmxheSA9IGpvaW4ob3ZlcnJpZGVzUm9vdCwgZmlsZSlcbiAgICBpZiAoIWV4aXN0c1N5bmMob3ZlcmxheSkpIGNvbnRpbnVlXG4gICAgY3BTeW5jKG92ZXJsYXksIGpvaW4odGFyZ2V0RGlyLCBmaWxlKSwgeyBmb3JjZTogdHJ1ZSB9KVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldERpclxufVxuXG4vKiogQ29tcHV0ZSB0aGUgdGFyZ2V0IGRpciBmb3IgYSBnaXZlbiBjb25zdW1lciBjb25maWcgcGF0aCB3aXRob3V0XG4gKiAgcmVidWlsZGluZyBpdC4gVXNlZCBieSBjb2RlIHRoYXQgbmVlZHMgdG8gd3JpdGUgaW50byB0aGUgdGFyZ2V0XG4gKiAgKGUuZy4gY2FjaGUgd3JpdGVycykgb3V0c2lkZSBvZiBgYnVpbGRUYXJnZXRgJ3Mgc2V0dXAgcGhhc2UuICovXG5leHBvcnQgZnVuY3Rpb24gdGFyZ2V0RGlyRm9yKGNvbmZpZ1BhdGg6IHN0cmluZykge1xuICBjb25zdCBoYXNoID0gY3JlYXRlSGFzaChcInNoYTI1NlwiKS51cGRhdGUoY29uZmlnUGF0aCkuZGlnZXN0KFwiaGV4XCIpLnNsaWNlKDAsIDE2KVxuICByZXR1cm4gam9pbihUQVJHRVRTX1JPT1QsIGhhc2gpXG59XG4iXX0=
63
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zb3VyY2UvYWN0aW9ucy90YXJnZXQvYnVpbGQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLE1BQU0sU0FBUyxDQUFBO0FBQzFGLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQ3RFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFBO0FBQ3RFLE9BQU8sRUFBRSxlQUFlLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUV0RTs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQUMsS0FBZ0Q7SUFDMUUsTUFBTSxTQUFTLEdBQUcsWUFBWSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUNoRCxNQUFNLGFBQWEsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUE7SUFDeEMsU0FBUyxDQUFDLFNBQVMsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFBO0lBRXpDLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRTtRQUNqQyxTQUFTLEVBQUUsSUFBSTtRQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDO0tBQzlFLENBQUMsQ0FBQTtJQUNGLEtBQUssTUFBTSxNQUFNLElBQUksaUJBQWlCLEVBQUUsQ0FBQztRQUN2QyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBQ3BDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFBO1FBQzlDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBQzVDLElBQUksVUFBVSxDQUFDLE1BQU0sQ0FBQztZQUNwQixNQUFNLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxDQUFDLENBQUE7UUFDbEUsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQTtRQUMzQyxJQUFJLFVBQVUsQ0FBQyxPQUFPLENBQUM7WUFBRSxNQUFNLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFBO0lBQ3JFLENBQUM7SUFDRCxLQUFLLE1BQU0sSUFBSSxJQUFJLGVBQWUsRUFBRSxDQUFDO1FBQ25DLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLENBQUE7UUFDekMsSUFBSSxVQUFVLENBQUMsT0FBTyxDQUFDO1lBQUUsTUFBTSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUE7SUFDakUsQ0FBQztJQUVELGdCQUFnQixDQUFDLFNBQVMsRUFBRSxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQTtJQUNsRSxPQUFPLFNBQVMsQ0FBQTtBQUNsQixDQUFDO0FBRUQsMkRBQTJEO0FBQzNELE1BQU0sVUFBVSxZQUFZLENBQUMsVUFBa0I7SUFDN0MsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFLFdBQVcsRUFBRSxTQUFTLENBQUMsQ0FBQTtBQUMxRCxDQUFDO0FBRUQsU0FBUyxhQUFhLENBQUMsR0FBVztJQUNoQyxPQUFPLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxRQUFRLENBQUMsR0FBRyxDQUFDLEtBQUssVUFBVSxDQUFBO0FBQ25FLENBQUM7QUFFRCxTQUFTLGlCQUFpQixDQUFDLEdBQVcsRUFBRSxTQUFpQjtJQUN2RCxPQUFPLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUE7QUFDN0QsQ0FBQztBQUVELFNBQVMsZ0JBQWdCLENBQUMsU0FBaUIsRUFBRSxhQUFxQjtJQUNoRSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLGNBQWMsQ0FBQyxDQUFBO0lBQzVDLElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLE9BQU8sQ0FBQyxhQUFhLENBQUM7UUFBRSxPQUFNO0lBQ3JELGlGQUFpRjtJQUNqRixNQUFNLENBQUMsSUFBSSxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7SUFDN0IsV0FBVyxDQUFDLGFBQWEsRUFBRSxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUE7QUFDOUMsQ0FBQztBQUVELFNBQVMsUUFBUSxDQUFDLElBQVk7SUFDNUIsSUFBSSxDQUFDO1FBQ0gsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO0lBQ25ELENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLFNBQVMsQ0FBQTtJQUNsQixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNwU3luYywgZXhpc3RzU3luYywgbWtkaXJTeW5jLCByZWFkbGlua1N5bmMsIHJtU3luYywgc3ltbGlua1N5bmMgfSBmcm9tIFwibm9kZTpmc1wiXG5pbXBvcnQgeyBiYXNlbmFtZSwgZGlybmFtZSwgam9pbiwgcmVsYXRpdmUsIHJlc29sdmUgfSBmcm9tIFwibm9kZTpwYXRoXCJcbmltcG9ydCB7IHJlc29sdmVEZXBlbmRlbmN5RGlyIH0gZnJvbSBcIi4uLy4uL2hlbHBlcnMvZGVwZW5kZW5jeS1kaXIudHNcIlxuaW1wb3J0IHsgRVNDQVBBQkxFX0ZJTEVTLCBFU0NBUEFCTEVfRk9MREVSUyB9IGZyb20gXCIuLi8uLi9zZXR0aW5ncy50c1wiXG5cbi8qKlxuICogU3ludGhlc2l6ZSB0aGUgcHJvamVjdCdzIFZpdGUgbW91bnQgYXQgYC5saXZlbWFyay8udGFyZ2V0L2A6IGxpdmVtYXJrJ3MgYHNvdXJjZS9gIHdpdGhcbiAqIHRoZSBwcm9qZWN0J3MgYC5saXZlbWFyay9gIGVzY2FwZXMgY29waWVkIG92ZXIgaXQsIHBsdXMgYSBgbm9kZV9tb2R1bGVzYCBsaW5rIHRvXG4gKiBsaXZlbWFyaydzIGRlcGVuZGVuY2llcy4gRXNjYXBhYmxlIGZvbGRlcnMgYXJlIHJlYnVpbHQgb24gZXZlcnkgcnVuLCBzbyBhIHJlbW92ZWQgZXNjYXBlXG4gKiBuZXZlciBrZWVwcyByZW5kZXJpbmcuIFJldHVybnMgdGhlIHRhcmdldCBkaXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFRhcmdldChwcm9wczogeyBjb25maWdQYXRoOiBzdHJpbmc7IHNvdXJjZURpcjogc3RyaW5nIH0pIHtcbiAgY29uc3QgdGFyZ2V0RGlyID0gdGFyZ2V0RGlyRm9yKHByb3BzLmNvbmZpZ1BhdGgpXG4gIGNvbnN0IG92ZXJyaWRlc1Jvb3QgPSBkaXJuYW1lKHRhcmdldERpcilcbiAgbWtkaXJTeW5jKHRhcmdldERpciwgeyByZWN1cnNpdmU6IHRydWUgfSlcblxuICBjcFN5bmMocHJvcHMuc291cmNlRGlyLCB0YXJnZXREaXIsIHtcbiAgICByZWN1cnNpdmU6IHRydWUsXG4gICAgZmlsdGVyOiBzcmMgPT4gaXNQYWNrYWdlRmlsZShzcmMpICYmICFpc0VzY2FwYWJsZUZvbGRlcihzcmMsIHByb3BzLnNvdXJjZURpciksXG4gIH0pXG4gIGZvciAoY29uc3QgZm9sZGVyIG9mIEVTQ0FQQUJMRV9GT0xERVJTKSB7XG4gICAgY29uc3QgZGVzdCA9IGpvaW4odGFyZ2V0RGlyLCBmb2xkZXIpXG4gICAgcm1TeW5jKGRlc3QsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KVxuICAgIGNvbnN0IHNvdXJjZSA9IGpvaW4ocHJvcHMuc291cmNlRGlyLCBmb2xkZXIpXG4gICAgaWYgKGV4aXN0c1N5bmMoc291cmNlKSlcbiAgICAgIGNwU3luYyhzb3VyY2UsIGRlc3QsIHsgcmVjdXJzaXZlOiB0cnVlLCBmaWx0ZXI6IGlzUGFja2FnZUZpbGUgfSlcbiAgICBjb25zdCBvdmVybGF5ID0gam9pbihvdmVycmlkZXNSb290LCBmb2xkZXIpXG4gICAgaWYgKGV4aXN0c1N5bmMob3ZlcmxheSkpIGNwU3luYyhvdmVybGF5LCBkZXN0LCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KVxuICB9XG4gIGZvciAoY29uc3QgZmlsZSBvZiBFU0NBUEFCTEVfRklMRVMpIHtcbiAgICBjb25zdCBvdmVybGF5ID0gam9pbihvdmVycmlkZXNSb290LCBmaWxlKVxuICAgIGlmIChleGlzdHNTeW5jKG92ZXJsYXkpKSBjcFN5bmMob3ZlcmxheSwgam9pbih0YXJnZXREaXIsIGZpbGUpKVxuICB9XG5cbiAgbGlua0RlcGVuZGVuY2llcyh0YXJnZXREaXIsIHJlc29sdmVEZXBlbmRlbmN5RGlyKHByb3BzLnNvdXJjZURpcikpXG4gIHJldHVybiB0YXJnZXREaXJcbn1cblxuLyoqIExvY2F0ZSB0aGUgcHJvamVjdCdzIHRhcmdldCBkaXIgd2l0aG91dCBidWlsZGluZyBpdC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0YXJnZXREaXJGb3IoY29uZmlnUGF0aDogc3RyaW5nKSB7XG4gIHJldHVybiBqb2luKGRpcm5hbWUoY29uZmlnUGF0aCksIFwiLmxpdmVtYXJrXCIsIFwiLnRhcmdldFwiKVxufVxuXG5mdW5jdGlvbiBpc1BhY2thZ2VGaWxlKHNyYzogc3RyaW5nKSB7XG4gIHJldHVybiAhL1xcLnVuaXRcXC50c3g/JC8udGVzdChzcmMpICYmIGJhc2VuYW1lKHNyYykgIT09IFwiZml4dHVyZXNcIlxufVxuXG5mdW5jdGlvbiBpc0VzY2FwYWJsZUZvbGRlcihzcmM6IHN0cmluZywgc291cmNlRGlyOiBzdHJpbmcpIHtcbiAgcmV0dXJuIEVTQ0FQQUJMRV9GT0xERVJTLmluY2x1ZGVzKHJlbGF0aXZlKHNvdXJjZURpciwgc3JjKSlcbn1cblxuZnVuY3Rpb24gbGlua0RlcGVuZGVuY2llcyh0YXJnZXREaXI6IHN0cmluZywgZGVwZW5kZW5jeURpcjogc3RyaW5nKSB7XG4gIGNvbnN0IGxpbmsgPSBqb2luKHRhcmdldERpciwgXCJub2RlX21vZHVsZXNcIilcbiAgaWYgKHJlYWRMaW5rKGxpbmspID09PSByZXNvbHZlKGRlcGVuZGVuY3lEaXIpKSByZXR1cm5cbiAgLy8gTm90IHJlY3Vyc2l2ZTogYSBzdGFsZSBsaW5rIG11c3QgZ28gd2l0aG91dCB0b3VjaGluZyB0aGUgc3RvcmUgaXQgcG9pbnRzIGludG8uXG4gIHJtU3luYyhsaW5rLCB7IGZvcmNlOiB0cnVlIH0pXG4gIHN5bWxpbmtTeW5jKGRlcGVuZGVuY3lEaXIsIGxpbmssIFwianVuY3Rpb25cIilcbn1cblxuZnVuY3Rpb24gcmVhZExpbmsocGF0aDogc3RyaW5nKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHJlc29sdmUoZGlybmFtZShwYXRoKSwgcmVhZGxpbmtTeW5jKHBhdGgpKVxuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,76 @@
1
+ import { existsSync, readFileSync, readlinkSync, realpathSync } from "node:fs";
2
+ import { mkdir, rm, symlink, writeFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ import { temporaryDirectoryTask } from "tempy";
5
+ import { describe, expect, it } from "vite-plus/test";
6
+ import { buildTarget, targetDirFor } from "./build.js";
7
+ describe("buildTarget", () => {
8
+ it("copies the source, overlays escapes and skips unit tests", () => temporaryDirectoryTask(async (root) => {
9
+ const { configPath, sourceDir } = await createFixture(root);
10
+ await put(join(root, "project/.livemark/components/Footer.tsx"), "escaped");
11
+ await put(join(root, "project/.livemark/head.ts"), "escaped head");
12
+ const targetDir = buildTarget({ configPath, sourceDir });
13
+ expect(targetDir).toBe(join(root, "project/.livemark/.target"));
14
+ expect(read(targetDir, "components/Footer.tsx")).toBe("escaped");
15
+ expect(read(targetDir, "components/Header.tsx")).toBe("default");
16
+ expect(read(targetDir, "head.ts")).toBe("escaped head");
17
+ expect(read(targetDir, "helpers/util.ts")).toBe("util");
18
+ expect(existsSync(join(targetDir, "helpers/util.unit.ts"))).toBe(false);
19
+ }));
20
+ it("drops escapes removed since the last run", () => temporaryDirectoryTask(async (root) => {
21
+ const { configPath, sourceDir } = await createFixture(root);
22
+ const overrides = join(root, "project/.livemark");
23
+ await put(join(overrides, "components/Footer.tsx"), "escaped");
24
+ await put(join(overrides, "routes/about.tsx"), "about");
25
+ await put(join(overrides, "head.ts"), "escaped head");
26
+ buildTarget({ configPath, sourceDir });
27
+ await rm(join(overrides, "components"), { recursive: true });
28
+ await rm(join(overrides, "routes"), { recursive: true });
29
+ await rm(join(overrides, "head.ts"));
30
+ const targetDir = buildTarget({ configPath, sourceDir });
31
+ expect(read(targetDir, "components/Footer.tsx")).toBe("default");
32
+ expect(existsSync(join(targetDir, "routes/about.tsx"))).toBe(false);
33
+ expect(read(targetDir, "head.ts")).toBe("head");
34
+ }));
35
+ it("keeps generated entries between runs", () => temporaryDirectoryTask(async (root) => {
36
+ const { configPath, sourceDir } = await createFixture(root);
37
+ const targetDir = buildTarget({ configPath, sourceDir });
38
+ await put(join(targetDir, "cache/changelog/entry.md"), "cached");
39
+ buildTarget({ configPath, sourceDir });
40
+ expect(read(targetDir, "cache/changelog/entry.md")).toBe("cached");
41
+ }));
42
+ it("links node_modules to livemark's dependencies and repairs a stale link", () => temporaryDirectoryTask(async (root) => {
43
+ const { configPath, sourceDir } = await createFixture(root);
44
+ const link = join(targetDirFor(configPath), "node_modules");
45
+ const dependencyDir = realpathSync(join(root, "livemark/node_modules"));
46
+ buildTarget({ configPath, sourceDir });
47
+ expect(readlinkSync(link)).toBe(dependencyDir);
48
+ await rm(link);
49
+ await mkdir(join(root, "elsewhere"));
50
+ await symlink(join(root, "elsewhere"), link, "junction");
51
+ buildTarget({ configPath, sourceDir });
52
+ expect(readlinkSync(link)).toBe(dependencyDir);
53
+ expect(existsSync(join(root, "elsewhere"))).toBe(true);
54
+ }));
55
+ });
56
+ async function createFixture(root) {
57
+ const sourceDir = join(root, "livemark/source");
58
+ await put(join(sourceDir, "components/Footer.tsx"), "default");
59
+ await put(join(sourceDir, "components/Header.tsx"), "default");
60
+ await put(join(sourceDir, "routes/index.tsx"), "index");
61
+ await put(join(sourceDir, "helpers/util.ts"), "util");
62
+ await put(join(sourceDir, "helpers/util.unit.ts"), "test");
63
+ await put(join(sourceDir, "head.ts"), "head");
64
+ await mkdir(join(root, "livemark/node_modules"));
65
+ const configPath = join(root, "project/livemark.config.ts");
66
+ await put(configPath, "export default {}");
67
+ return { configPath, sourceDir };
68
+ }
69
+ async function put(path, content) {
70
+ await mkdir(dirname(path), { recursive: true });
71
+ await writeFile(path, content);
72
+ }
73
+ function read(dir, path) {
74
+ return readFileSync(join(dir, path), "utf-8");
75
+ }
76
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQudW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NvdXJjZS9hY3Rpb25zL3RhcmdldC9idWlsZC51bml0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTSxTQUFTLENBQUE7QUFDOUUsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGtCQUFrQixDQUFBO0FBQ2hFLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQ3pDLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLE9BQU8sQ0FBQTtBQUM5QyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQTtBQUNyRCxPQUFPLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUV0RCxRQUFRLENBQUMsYUFBYSxFQUFFLEdBQUcsRUFBRTtJQUMzQixFQUFFLENBQUMsMERBQTBELEVBQUUsR0FBRyxFQUFFLENBQ2xFLHNCQUFzQixDQUFDLEtBQUssRUFBQyxJQUFJLEVBQUMsRUFBRTtRQUNsQyxNQUFNLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxHQUFHLE1BQU0sYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQzNELE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUseUNBQXlDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQTtRQUMzRSxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLDJCQUEyQixDQUFDLEVBQUUsY0FBYyxDQUFDLENBQUE7UUFFbEUsTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUFDLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUE7UUFFeEQsTUFBTSxDQUFD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MUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsQ0FBQTtBQUNsQyxDQUFDO0FBRUQsS0FBSyxVQUFVLEdBQUcsQ0FBQyxJQUFZLEVBQUUsT0FBZTtJQUM5QyxNQUFNLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUMvQyxNQUFNLFNBQVMsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUE7QUFDaEMsQ0FBQztBQUVELFNBQVMsSUFBSSxDQUFDLEdBQVcsRUFBRSxJQUFZO0lBQ3JDLE9BQU8sWUFBWSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUE7QUFDL0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGV4aXN0c1N5bmMsIHJlYWRGaWxlU3luYywgcmVhZGxpbmtTeW5jLCByZWFscGF0aFN5bmMgfSBmcm9tIFwibm9kZTpmc1wiXG5pbXBvcnQgeyBta2Rpciwgcm0sIHN5bWxpbmssIHdyaXRlRmlsZSB9IGZyb20gXCJub2RlOmZzL3Byb21pc2VzXCJcbmltcG9ydCB7IGRpcm5hbWUsIGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCJcbmltcG9ydCB7IHRlbXBvcmFyeURpcmVjdG9yeVRhc2sgfSBmcm9tIFwidGVtcHlcIlxuaW1wb3J0IHsgZGVzY3JpYmUsIGV4cGVjdCwgaXQgfSBmcm9tIFwidml0ZS1wbHVzL3Rlc3RcIlxuaW1wb3J0IHsgYnVpbGRUYXJnZXQsIHRhcmdldERpckZvciB9IGZyb20gXCIuL2J1aWxkLnRzXCJcblxuZGVzY3JpYmUoXCJidWlsZFRhcmdldFwiLCAoKSA9PiB7XG4gIGl0KFwiY29waWVzIHRoZSBzb3VyY2UsIG92ZXJsYXlzIGVzY2FwZXMgYW5kIHNraXBzIHVuaXQgdGVzdHNcIiwgKCkgPT5cbiAgICB0ZW1wb3JhcnlEaXJlY3RvcnlUYXNrKGFzeW5jIHJvb3QgPT4ge1xuICAgICAgY29uc3QgeyBjb25maWdQYXRoLCBzb3VyY2VEaXIgfSA9IGF3YWl0IGNyZWF0ZUZpeHR1cmUocm9vdClcbiAgICAgIGF3YWl0IHB1dChqb2luKHJvb3QsIFwicHJvamVjdC8ubGl2ZW1hcmsvY29tcG9uZW50cy9Gb290ZXIudHN4XCIpLCBcImVzY2FwZWRcIilcbiAgICAgIGF3YWl0IHB1dChqb2luKHJvb3QsIFwicHJvamVjdC8ubGl2ZW1hcmsvaGVhZC50c1wiKSwgXCJlc2NhcGVkIGhlYWRcIilcblxuICAgICAgY29uc3QgdGFyZ2V0RGlyID0gYnVpbGRUYXJnZXQoeyBjb25maWdQYXRoLCBzb3VyY2VEaXIgfSlcblxuICAgICAgZXhwZWN0KHRhcmdldERpcikudG9CZShqb2luKHJvb3QsIFwicHJvamVjdC8ubGl2ZW1hcmsvLnRhcmdldFwiKSlcbiAgICAgIGV4cGVjdChyZWFkKHRhcmdldERpciwgXCJjb21wb25lbnRzL0Zvb3Rlci50c3hcIikpLnRvQmUoXCJlc2NhcGVkXCIpXG4gICAgICBleHBlY3QocmVhZCh0YXJnZXREaXIsIFwiY29tcG9uZW50cy9IZWFkZXIudHN4XCIpKS50b0JlKFwiZGVmYXVsdFwiKVxuICAgICAgZXhwZWN0KHJlYWQodGFyZ2V0RGlyLCBcImhlYWQudHNcIikpLnRvQmUoXCJlc2NhcGVkIGhlYWRcIilcbiAgICAgIGV4cGVjdChyZWFkKHRhcmdldERpciwgXCJoZWxwZXJzL3V0aWwudHNcIikpLnRvQmUoXCJ1dGlsXCIpXG4gICAgICBleHBlY3QoZXhpc3RzU3luYyhqb2luKHRhcmdldERpciwgXCJoZWxwZXJzL3V0aWwudW5pdC50c1wiKSkpLnRvQmUoZmFsc2UpXG4gICAgfSkpXG5cbiAgaXQoXCJkcm9wcyBlc2NhcGVzIHJlbW92ZWQgc2luY2UgdGhlIGxhc3QgcnVuXCIsICgpID0+XG4gICAgdGVtcG9yYXJ5RGlyZWN0b3J5VGFzayhhc3luYyByb290ID0+IHtcbiAgICAgIGNvbnN0IHsgY29uZmlnUGF0aCwgc291cmNlRGlyIH0gPSBhd2FpdCBjcmVhdGVGaXh0dXJlKHJvb3QpXG4gICAgICBjb25zdCBvdmVycmlkZXMgPSBqb2luKHJvb3QsIFwicHJvamVjdC8ubGl2ZW1hcmtcIilcbiAgICAgIGF3YWl0IHB1dChqb2luKG92ZXJyaWRlcywgXCJjb21wb25lbnRzL0Zvb3Rlci50c3hcIiksIFwiZXNjYXBlZFwiKVxuICAgICAgYXdhaXQgcHV0KGpvaW4ob3ZlcnJpZGVzLCBcInJvdXRlcy9hYm91dC50c3hcIiksIFwiYWJvdXRcIilcbiAgICAgIGF3YWl0IHB1dChqb2luKG92ZXJyaWRlcywgXCJoZWFkLnRzXCIpLCBcImVzY2FwZWQgaGVhZFwiKVxuICAgICAgYnVpbGRUYXJnZXQoeyBjb25maWdQYXRoLCBzb3VyY2VEaXIgfSlcblxuICAgICAgYXdhaXQgcm0oam9pbihvdmVycmlkZXMsIFwiY29tcG9uZW50c1wiKSwgeyByZWN1cnNpdmU6IHRydWUgfSlcbiAgICAgIGF3YWl0IHJtKGpvaW4ob3ZlcnJpZGVzLCBcInJvdXRlc1wiKSwgeyByZWN1cnNpdmU6IHRydWUgfSlcbiAgICAgIGF3YWl0IHJtKGpvaW4ob3ZlcnJpZGVzLCBcImhlYWQudHNcIikpXG4gICAgICBjb25zdCB0YXJnZXREaXIgPSBidWlsZFRhcmdldCh7IGNvbmZpZ1BhdGgsIHNvdXJjZURpciB9KVxuXG4gICAgICBleHBlY3QocmVhZCh0YXJnZXREaXIsIFwiY29tcG9uZW50cy9Gb290ZXIudHN4XCIpKS50b0JlKFwiZGVmYXVsdFwiKVxuICAgICAgZXhwZWN0KGV4aXN0c1N5bmMoam9pbih0YXJnZXREaXIsIFwicm91dGVzL2Fib3V0LnRzeFwiKSkpLnRvQmUoZmFsc2UpXG4gICAgICBleHBlY3QocmVhZCh0YXJnZXREaXIsIFwiaGVhZC50c1wiKSkudG9CZShcImhlYWRcIilcbiAgICB9KSlcblxuICBpdChcImtlZXBzIGdlbmVyYXRlZCBlbnRyaWVzIGJldHdlZW4gcnVuc1wiLCAoKSA9PlxuICAgIHRlbXBvcmFyeURpcmVjdG9yeVRhc2soYXN5bmMgcm9vdCA9PiB7XG4gICAgICBjb25zdCB7IGNvbmZpZ1BhdGgsIHNvdXJjZURpciB9ID0gYXdhaXQgY3JlYXRlRml4dHVyZShyb290KVxuICAgICAgY29uc3QgdGFyZ2V0RGlyID0gYnVpbGRUYXJnZXQoeyBjb25maWdQYXRoLCBzb3VyY2VEaXIgfSlcbiAgICAgIGF3YWl0IHB1dChqb2luKHRhcmdldERpciwgXCJjYWNoZS9jaGFuZ2Vsb2cvZW50cnkubWRcIiksIFwiY2FjaGVkXCIpXG5cbiAgICAgIGJ1aWxkVGFyZ2V0KHsgY29uZmlnUGF0aCwgc291cmNlRGlyIH0pXG5cbiAgICAgIGV4cGVjdChyZWFkKHRhcmdldERpciwgXCJjYWNoZS9jaGFuZ2Vsb2cvZW50cnkubWRcIikpLnRvQmUoXCJjYWNoZWRcIilcbiAgICB9KSlcblxuICBpdChcImxpbmtzIG5vZGVfbW9kdWxlcyB0byBsaXZlbWFyaydzIGRlcGVuZGVuY2llcyBhbmQgcmVwYWlycyBhIHN0YWxlIGxpbmtcIiwgKCkgPT5cbiAgICB0ZW1wb3JhcnlEaXJlY3RvcnlUYXNrKGFzeW5jIHJvb3QgPT4ge1xuICAgICAgY29uc3QgeyBjb25maWdQYXRoLCBzb3VyY2VEaXIgfSA9IGF3YWl0IGNyZWF0ZUZpeHR1cmUocm9vdClcbiAgICAgIGNvbnN0IGxpbmsgPSBqb2luKHRhcmdldERpckZvcihjb25maWdQYXRoKSwgXCJub2RlX21vZHVsZXNcIilcbiAgICAgIGNvbnN0IGRlcGVuZGVuY3lEaXIgPSByZWFscGF0aFN5bmMoam9pbihyb290LCBcImxpdmVtYXJrL25vZGVfbW9kdWxlc1wiKSlcblxuICAgICAgYnVpbGRUYXJnZXQoeyBjb25maWdQYXRoLCBzb3VyY2VEaXIgfSlcbiAgICAgIGV4cGVjdChyZWFkbGlua1N5bmMobGluaykpLnRvQmUoZGVwZW5kZW5jeURpcilcblxuICAgICAgYXdhaXQgcm0obGluaylcbiAgICAgIGF3YWl0IG1rZGlyKGpvaW4ocm9vdCwgXCJlbHNld2hlcmVcIikpXG4gICAgICBhd2FpdCBzeW1saW5rKGpvaW4ocm9vdCwgXCJlbHNld2hlcmVcIiksIGxpbmssIFwianVuY3Rpb25cIilcbiAgICAgIGJ1aWxkVGFyZ2V0KHsgY29uZmlnUGF0aCwgc291cmNlRGlyIH0pXG5cbiAgICAgIGV4cGVjdChyZWFkbGlua1N5bmMobGluaykpLnRvQmUoZGVwZW5kZW5jeURpcilcbiAgICAgIGV4cGVjdChleGlzdHNTeW5jKGpvaW4ocm9vdCwgXCJlbHNld2hlcmVcIikpKS50b0JlKHRydWUpXG4gICAgfSkpXG59KVxuXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVGaXh0dXJlKHJvb3Q6IHN0cmluZykge1xuICBjb25zdCBzb3VyY2VEaXIgPSBqb2luKHJvb3QsIFwibGl2ZW1hcmsvc291cmNlXCIpXG4gIGF3YWl0IHB1dChqb2luKHNvdXJjZURpciwgXCJjb21wb25lbnRzL0Zvb3Rlci50c3hcIiksIFwiZGVmYXVsdFwiKVxuICBhd2FpdCBwdXQoam9pbihzb3VyY2VEaXIsIFwiY29tcG9uZW50cy9IZWFkZXIudHN4XCIpLCBcImRlZmF1bHRcIilcbiAgYXdhaXQgcHV0KGpvaW4oc291cmNlRGlyLCBcInJvdXRlcy9pbmRleC50c3hcIiksIFwiaW5kZXhcIilcbiAgYXdhaXQgcHV0KGpvaW4oc291cmNlRGlyLCBcImhlbHBlcnMvdXRpbC50c1wiKSwgXCJ1dGlsXCIpXG4gIGF3YWl0IHB1dChqb2luKHNvdXJjZURpciwgXCJoZWxwZXJzL3V0aWwudW5pdC50c1wiKSwgXCJ0ZXN0XCIpXG4gIGF3YWl0IHB1dChqb2luKHNvdXJjZURpciwgXCJoZWFkLnRzXCIpLCBcImhlYWRcIilcbiAgYXdhaXQgbWtkaXIoam9pbihyb290LCBcImxpdmVtYXJrL25vZGVfbW9kdWxlc1wiKSlcbiAgY29uc3QgY29uZmlnUGF0aCA9IGpvaW4ocm9vdCwgXCJwcm9qZWN0L2xpdmVtYXJrLmNvbmZpZy50c1wiKVxuICBhd2FpdCBwdXQoY29uZmlnUGF0aCwgXCJleHBvcnQgZGVmYXVsdCB7fVwiKVxuICByZXR1cm4geyBjb25maWdQYXRoLCBzb3VyY2VEaXIgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBwdXQocGF0aDogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpIHtcbiAgYXdhaXQgbWtkaXIoZGlybmFtZShwYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSlcbiAgYXdhaXQgd3JpdGVGaWxlKHBhdGgsIGNvbnRlbnQpXG59XG5cbmZ1bmN0aW9uIHJlYWQoZGlyOiBzdHJpbmcsIHBhdGg6IHN0cmluZykge1xuICByZXR1cm4gcmVhZEZpbGVTeW5jKGpvaW4oZGlyLCBwYXRoKSwgXCJ1dGYtOFwiKVxufVxuIl19
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Wipe the project's target dir so the next run rebuilds it from scratch.
3
+ */
4
+ export declare function clearTarget(configPath: string): string;
@@ -0,0 +1,14 @@
1
+ import { rmSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { targetDirFor } from "./build.js";
4
+ /**
5
+ * Wipe the project's target dir so the next run rebuilds it from scratch.
6
+ */
7
+ export function clearTarget(configPath) {
8
+ const targetDir = targetDirFor(configPath);
9
+ // Unlink the dependency link first so the recursive remove cannot reach the store.
10
+ rmSync(join(targetDir, "node_modules"), { force: true });
11
+ rmSync(targetDir, { recursive: true, force: true });
12
+ return targetDir;
13
+ }
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xlYXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zb3VyY2UvYWN0aW9ucy90YXJnZXQvY2xlYXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFNBQVMsQ0FBQTtBQUNoQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBQ2hDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFFekM7O0dBRUc7QUFDSCxNQUFNLFVBQVUsV0FBVyxDQUFDLFVBQWtCO0lBQzVDLE1BQU0sU0FBUyxHQUFHLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUMxQyxtRkFBbUY7SUFDbkYsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsY0FBYyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUN4RCxNQUFNLENBQUMsU0FBUyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUNuRCxPQUFPLFNBQVMsQ0FBQTtBQUNsQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcm1TeW5jIH0gZnJvbSBcIm5vZGU6ZnNcIlxuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIlxuaW1wb3J0IHsgdGFyZ2V0RGlyRm9yIH0gZnJvbSBcIi4vYnVpbGQudHNcIlxuXG4vKipcbiAqIFdpcGUgdGhlIHByb2plY3QncyB0YXJnZXQgZGlyIHNvIHRoZSBuZXh0IHJ1biByZWJ1aWxkcyBpdCBmcm9tIHNjcmF0Y2guXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjbGVhclRhcmdldChjb25maWdQYXRoOiBzdHJpbmcpIHtcbiAgY29uc3QgdGFyZ2V0RGlyID0gdGFyZ2V0RGlyRm9yKGNvbmZpZ1BhdGgpXG4gIC8vIFVubGluayB0aGUgZGVwZW5kZW5jeSBsaW5rIGZpcnN0IHNvIHRoZSByZWN1cnNpdmUgcmVtb3ZlIGNhbm5vdCByZWFjaCB0aGUgc3RvcmUuXG4gIHJtU3luYyhqb2luKHRhcmdldERpciwgXCJub2RlX21vZHVsZXNcIiksIHsgZm9yY2U6IHRydWUgfSlcbiAgcm1TeW5jKHRhcmdldERpciwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pXG4gIHJldHVybiB0YXJnZXREaXJcbn1cbiJdfQ==
@@ -0,0 +1 @@
1
+ export {};