@motion-proto/live-tokens 0.6.2 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/README.md +14 -13
  2. package/dist-plugin/index.cjs +147 -136
  3. package/dist-plugin/index.d.cts +1 -1
  4. package/dist-plugin/index.d.ts +1 -1
  5. package/dist-plugin/index.js +145 -135
  6. package/package.json +25 -40
  7. package/src/{component-editor → editor/component-editor}/BadgeEditor.svelte +8 -82
  8. package/src/{component-editor → editor/component-editor}/CalloutEditor.svelte +4 -4
  9. package/src/{component-editor → editor/component-editor}/CardEditor.svelte +28 -76
  10. package/src/{component-editor → editor/component-editor}/CollapsibleSectionEditor.svelte +3 -3
  11. package/src/{component-editor → editor/component-editor}/CornerBadgeEditor.svelte +31 -93
  12. package/src/{component-editor → editor/component-editor}/DialogEditor.svelte +60 -57
  13. package/src/editor/component-editor/ImageEditor.svelte +30 -0
  14. package/src/{component-editor → editor/component-editor}/InlineEditActionsEditor.svelte +6 -4
  15. package/src/editor/component-editor/MenuSelectEditor.svelte +160 -0
  16. package/src/{component-editor → editor/component-editor}/NotificationEditor.svelte +64 -37
  17. package/src/{component-editor → editor/component-editor}/ProgressBarEditor.svelte +5 -4
  18. package/src/{component-editor → editor/component-editor}/RadioButtonEditor.svelte +3 -3
  19. package/src/{component-editor → editor/component-editor}/SectionDividerEditor.svelte +57 -84
  20. package/src/{component-editor → editor/component-editor}/SegmentedControlEditor.svelte +2 -2
  21. package/src/{component-editor → editor/component-editor}/StandardButtonsEditor.svelte +16 -20
  22. package/src/{component-editor → editor/component-editor}/TabBarEditor.svelte +9 -14
  23. package/src/{component-editor → editor/component-editor}/TableEditor.svelte +9 -18
  24. package/src/{component-editor → editor/component-editor}/TooltipEditor.svelte +11 -47
  25. package/src/{component-editor → editor/component-editor}/registry.ts +28 -18
  26. package/src/{component-editor → editor/component-editor}/scaffolding/AngleDial.svelte +2 -2
  27. package/src/{component-editor → editor/component-editor}/scaffolding/ComponentEditorBase.svelte +3 -51
  28. package/src/{component-editor → editor/component-editor}/scaffolding/ComponentFileManager.svelte +144 -416
  29. package/src/{component-editor → editor/component-editor}/scaffolding/ComponentFileMenu.svelte +18 -170
  30. package/src/{component-editor → editor/component-editor}/scaffolding/ComponentsTab.svelte +2 -2
  31. package/src/{component-editor → editor/component-editor}/scaffolding/CopyFromMenu.svelte +44 -4
  32. package/src/{component-editor → editor/component-editor}/scaffolding/DividerEditor.svelte +1 -1
  33. package/src/{component-editor → editor/component-editor}/scaffolding/FieldsetWrapper.svelte +1 -1
  34. package/src/{component-editor → editor/component-editor}/scaffolding/GradientCard.svelte +6 -6
  35. package/src/{component-editor → editor/component-editor}/scaffolding/LinkageChart.svelte +6 -6
  36. package/src/{component-editor → editor/component-editor}/scaffolding/LinkedBlock.svelte +6 -11
  37. package/src/editor/component-editor/scaffolding/NonStylableConfig.svelte +38 -0
  38. package/src/{component-editor → editor/component-editor}/scaffolding/SaveAsDialog.svelte +66 -12
  39. package/src/editor/component-editor/scaffolding/ShadowBackdrop.svelte +72 -0
  40. package/src/editor/component-editor/scaffolding/ShadowBackdropControls.svelte +132 -0
  41. package/src/editor/component-editor/scaffolding/StateBlock.svelte +257 -0
  42. package/src/{component-editor → editor/component-editor}/scaffolding/TokenLayout.svelte +9 -7
  43. package/src/editor/component-editor/scaffolding/VariantGroup.svelte +644 -0
  44. package/src/{component-editor → editor/component-editor}/scaffolding/editorContext.ts +19 -9
  45. package/src/{component-editor → editor/component-editor}/scaffolding/linkedBlock.ts +2 -2
  46. package/src/{component-editor → editor/component-editor}/scaffolding/types.ts +14 -0
  47. package/src/{lib → editor/core/components}/componentConfigService.ts +2 -2
  48. package/src/{lib → editor/core/components}/componentPersist.ts +5 -5
  49. package/src/editor/core/flashStatus.ts +30 -0
  50. package/src/{lib → editor/core/fonts}/fontLoader.ts +2 -2
  51. package/src/{lib → editor/core/fonts}/fontMigration.ts +4 -4
  52. package/src/{lib → editor/core/fonts}/fontParse.ts +1 -1
  53. package/src/editor/core/manifests/manifestService.ts +116 -0
  54. package/src/{lib → editor/core/palettes}/paletteDerivation.ts +2 -2
  55. package/src/{lib → editor/core/palettes}/tokenRegistry.ts +5 -5
  56. package/src/editor/core/productionPulse.ts +37 -0
  57. package/src/{lib → editor/core/routing}/router.ts +1 -1
  58. package/src/{lib/files/versionedFileResource.ts → editor/core/storage/files/versionedFileResourceClient.ts} +8 -1
  59. package/src/{lib → editor/core/store}/editorCore.ts +24 -8
  60. package/src/{lib → editor/core/store}/editorPersistence.ts +3 -3
  61. package/src/{lib → editor/core/store}/editorRenderer.ts +2 -2
  62. package/src/{lib → editor/core/store}/editorStore.ts +17 -17
  63. package/src/{lib → editor/core/store}/editorTypes.ts +1 -1
  64. package/src/{lib → editor/core/themes}/slices/columns.ts +2 -2
  65. package/src/{lib → editor/core/themes}/slices/components.ts +2 -2
  66. package/src/{lib → editor/core/themes}/slices/fonts.ts +1 -1
  67. package/src/{lib → editor/core/themes}/slices/gradients.ts +2 -2
  68. package/src/{lib → editor/core/themes}/slices/overlays.ts +1 -1
  69. package/src/{lib → editor/core/themes}/slices/palettes.ts +1 -1
  70. package/src/{lib → editor/core/themes}/slices/shadows.ts +3 -3
  71. package/src/{lib → editor/core/themes}/themeInit.ts +6 -6
  72. package/src/{lib → editor/core/themes}/themeService.ts +6 -6
  73. package/src/{lib → editor/core/themes}/themeTypes.ts +11 -7
  74. package/src/editor/index.ts +69 -0
  75. package/src/{lib → editor/overlay}/LiveEditorOverlay.svelte +79 -125
  76. package/src/{lib → editor/overlay}/columnsOverlay.ts +2 -2
  77. package/src/{pages → editor/pages}/ComponentEditorPage.svelte +12 -12
  78. package/src/{pages → editor/pages}/Editor.svelte +4 -4
  79. package/src/{pages → editor/pages}/EditorShell.svelte +18 -36
  80. package/src/{styles → editor/styles}/ui-editor.css +41 -21
  81. package/src/{styles → editor/styles}/ui-form-controls.css +8 -8
  82. package/src/{ui → editor/ui}/BezierCurveEditor.svelte +8 -8
  83. package/src/{ui → editor/ui}/ColorEditPanel.svelte +13 -13
  84. package/src/{ui → editor/ui}/EditorViewSwitcher.svelte +8 -6
  85. package/src/editor/ui/FileLoadList.svelte +350 -0
  86. package/src/editor/ui/FilePill.svelte +80 -0
  87. package/src/{ui → editor/ui}/FontStackEditor.svelte +7 -7
  88. package/src/{ui → editor/ui}/GradientEditor.svelte +11 -11
  89. package/src/{ui → editor/ui}/GradientStopPicker.svelte +1 -1
  90. package/src/editor/ui/ManifestFileManager.svelte +371 -0
  91. package/src/{ui → editor/ui}/PaletteEditor.svelte +132 -598
  92. package/src/{ui → editor/ui}/ProjectFontsSection.svelte +102 -144
  93. package/src/{ui → editor/ui}/SurfacesTab.svelte +3 -3
  94. package/src/{ui → editor/ui}/TextTab.svelte +3 -3
  95. package/src/{ui → editor/ui}/ThemeFileManager.svelte +286 -519
  96. package/src/{ui → editor/ui}/UICopyPopover.svelte +4 -4
  97. package/src/{ui → editor/ui}/UIFontFamilySelector.svelte +6 -6
  98. package/src/{ui → editor/ui}/UIFontSizeSelector.svelte +1 -1
  99. package/src/editor/ui/UIInfoPopover.svelte +244 -0
  100. package/src/{ui → editor/ui}/UILineHeightSelector.svelte +5 -5
  101. package/src/{ui → editor/ui}/UILinkToggle.svelte +2 -2
  102. package/src/{ui → editor/ui}/UIPaddingSelector.svelte +6 -6
  103. package/src/{ui → editor/ui}/UIPaletteSelector.svelte +26 -26
  104. package/src/editor/ui/UIPillButton.svelte +138 -0
  105. package/src/{ui → editor/ui}/UIRadio.svelte +2 -2
  106. package/src/{ui → editor/ui}/UIRelinkConfirmPopover.svelte +4 -4
  107. package/src/editor/ui/UISquareButton.svelte +172 -0
  108. package/src/{ui → editor/ui}/UITokenSelector.svelte +10 -10
  109. package/src/{ui → editor/ui}/UIVariantSelector.svelte +1 -1
  110. package/src/{ui → editor/ui}/VariablesTab.svelte +31 -8
  111. package/src/{ui → editor/ui}/palette/GradientStopEditor.svelte +13 -13
  112. package/src/{ui → editor/ui}/palette/OverridesPanel.svelte +13 -13
  113. package/src/{ui → editor/ui}/palette/PaletteBase.svelte +8 -5
  114. package/src/{ui → editor/ui}/palette/paletteEditorState.ts +1 -1
  115. package/src/editor/ui/palette/paletteMath.ts +275 -0
  116. package/src/{ui → editor/ui}/sections/ColumnsSection.svelte +137 -17
  117. package/src/{ui → editor/ui}/sections/GradientsSection.svelte +7 -7
  118. package/src/{ui → editor/ui}/sections/OverlaysSection.svelte +17 -17
  119. package/src/{ui → editor/ui}/sections/ShadowsSection.svelte +22 -22
  120. package/src/{ui → editor/ui}/sections/TokenScaleTable.svelte +3 -3
  121. package/src/{components → system/components}/Badge.svelte +0 -36
  122. package/src/{components → system/components}/Card.svelte +8 -62
  123. package/src/{components → system/components}/CornerBadge.svelte +8 -24
  124. package/src/{components → system/components}/Dialog.svelte +1 -1
  125. package/src/system/components/FloatingTokenTags.css +256 -0
  126. package/src/system/components/FloatingTokenTags.svelte +592 -0
  127. package/src/{components → system/components}/InlineEditActions.svelte +6 -4
  128. package/src/system/components/MenuSelect.svelte +229 -0
  129. package/src/{components → system/components}/ProgressBar.svelte +29 -11
  130. package/src/{components → system/components}/SegmentedControl.svelte +49 -43
  131. package/src/{components → system/components}/TabBar.svelte +81 -65
  132. package/src/{components → system/components}/Table.svelte +17 -3
  133. package/src/{components → system/components}/Tooltip.svelte +6 -4
  134. package/src/system/styles/CONVENTIONS.md +178 -0
  135. package/src/{styles → system/styles}/fonts.css +6 -3
  136. package/src/{styles → system/styles}/tokens.css +149 -29
  137. package/src/component-editor/ImageEditor.svelte +0 -74
  138. package/src/component-editor/scaffolding/NonStylableConfig.svelte +0 -62
  139. package/src/component-editor/scaffolding/ShadowBackdrop.svelte +0 -37
  140. package/src/component-editor/scaffolding/ShadowBackdropControls.svelte +0 -61
  141. package/src/component-editor/scaffolding/StateBlock.svelte +0 -132
  142. package/src/component-editor/scaffolding/VariantGroup.svelte +0 -310
  143. package/src/data/google-fonts.json +0 -75
  144. package/src/lib/index.ts +0 -68
  145. package/src/lib/presetService.ts +0 -214
  146. package/src/lib/productionPulse.ts +0 -32
  147. package/src/ui/PresetFileManager.svelte +0 -1116
  148. package/src/ui/UnsavedComponentsDialog.svelte +0 -315
  149. /package/src/{styles → app}/site.css +0 -0
  150. /package/src/{component-editor → editor/component-editor}/index.ts +0 -0
  151. /package/src/{component-editor → editor/component-editor}/scaffolding/DemoHeader.svelte +0 -0
  152. /package/src/{component-editor → editor/component-editor}/scaffolding/TypeEditor.svelte +0 -0
  153. /package/src/{component-editor → editor/component-editor}/scaffolding/buildTypeGroupTokens.ts +0 -0
  154. /package/src/{component-editor → editor/component-editor}/scaffolding/componentSectionType.ts +0 -0
  155. /package/src/{component-editor → editor/component-editor}/scaffolding/componentSources.ts +0 -0
  156. /package/src/{component-editor → editor/component-editor}/scaffolding/defaultSections.ts +0 -0
  157. /package/src/{component-editor → editor/component-editor}/scaffolding/siblings.ts +0 -0
  158. /package/src/{lib → editor/core/components}/componentConfigKeys.ts +0 -0
  159. /package/src/{lib → editor/core}/cssVarSync.ts +0 -0
  160. /package/src/{lib → editor/core/palettes}/oklch.ts +0 -0
  161. /package/src/{lib → editor/core/routing}/navLinkTypes.ts +0 -0
  162. /package/src/{lib → editor/core/routing}/parentRouteStore.ts +0 -0
  163. /package/src/{lib → editor/core/storage}/storage.ts +0 -0
  164. /package/src/{lib → editor/core/store}/editorConfig.ts +0 -0
  165. /package/src/{lib → editor/core/store}/editorConfigStore.ts +0 -0
  166. /package/src/{lib → editor/core/store}/editorKeybindings.ts +0 -0
  167. /package/src/{lib → editor/core/store}/editorViewStore.ts +0 -0
  168. /package/src/{lib → editor/core/themes}/migrations/2026-04-24-component-prefix-and-suffix-renames.ts +0 -0
  169. /package/src/{lib → editor/core/themes}/migrations/2026-04-24-legacy-keys-and-bg-to-canvas.ts +0 -0
  170. /package/src/{lib → editor/core/themes}/migrations/2026-04-27-segmentedcontrol-disabled-flatten.ts +0 -0
  171. /package/src/{lib → editor/core/themes}/migrations/2026-05-08-collapsiblesection-frame-and-cleanup.ts +0 -0
  172. /package/src/{lib → editor/core/themes}/migrations/2026-05-08-collapsiblesection-variant-namespace.ts +0 -0
  173. /package/src/{lib → editor/core/themes}/migrations/2026-05-10-sectiondivider-gradient-stops.ts +0 -0
  174. /package/src/{lib → editor/core/themes}/migrations/2026-05-13-primary-to-brand.ts +0 -0
  175. /package/src/{lib → editor/core/themes}/migrations/index.ts +0 -0
  176. /package/src/{lib → editor/core/themes}/parsers/globalRootBlock.ts +0 -0
  177. /package/src/{lib → editor/core/themes}/slices/domainVars.ts +0 -0
  178. /package/src/{lib → editor/overlay}/ColumnsOverlay.svelte +0 -0
  179. /package/src/{lib → editor/overlay}/overlayState.ts +0 -0
  180. /package/src/{pages → editor/pages}/ComponentEditorPage.svelte.d.ts +0 -0
  181. /package/src/{pages → editor/pages}/Editor.svelte.d.ts +0 -0
  182. /package/src/{ui → editor/ui}/Toggle.svelte +0 -0
  183. /package/src/{ui → editor/ui}/UIDialog.svelte +0 -0
  184. /package/src/{ui → editor/ui}/UIFontWeightSelector.svelte +0 -0
  185. /package/src/{ui → editor/ui}/UIOptionItem.svelte +0 -0
  186. /package/src/{ui → editor/ui}/UIOptionList.svelte +0 -0
  187. /package/src/{ui → editor/ui}/UIRadioGroup.svelte +0 -0
  188. /package/src/{lib → editor/ui}/copyPopover.ts +0 -0
  189. /package/src/{ui → editor/ui}/curveEngine.ts +0 -0
  190. /package/src/{ui → editor/ui}/index.ts +0 -0
  191. /package/src/{ui → editor/ui}/keepInViewport.ts +0 -0
  192. /package/src/{ui → editor/ui}/palette/ScaleCurveEditor.svelte +0 -0
  193. /package/src/{lib → editor/ui}/scrollSection.ts +0 -0
  194. /package/src/{ui → editor/ui}/sections/tokenScales.ts +0 -0
  195. /package/src/{ui → editor/ui}/variantScales.ts +0 -0
  196. /package/src/{assets → system/assets}/newspaper.webp +0 -0
  197. /package/src/{assets → system/assets}/offering.webp +0 -0
  198. /package/src/{components → system/components}/Button.svelte +0 -0
  199. /package/src/{components → system/components}/Callout.svelte +0 -0
  200. /package/src/{components → system/components}/CollapsibleSection.svelte +0 -0
  201. /package/src/{components → system/components}/Image.svelte +0 -0
  202. /package/src/{components → system/components}/Notification.svelte +0 -0
  203. /package/src/{components → system/components}/RadioButton.svelte +0 -0
  204. /package/src/{components → system/components}/SectionDivider.svelte +0 -0
  205. /package/src/{components → system/components}/types.ts +0 -0
  206. /package/src/{styles → system/styles}/_padding.scss +0 -0
  207. /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-italic-latin-ext.woff2 +0 -0
  208. /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-italic-latin.woff2 +0 -0
  209. /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-roman-latin-ext.woff2 +0 -0
  210. /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-roman-latin.woff2 +0 -0
  211. /package/src/{styles → system/styles}/fonts/Manrope/Manrope-latin-ext.woff2 +0 -0
  212. /package/src/{styles → system/styles}/fonts/Manrope/Manrope-latin.woff2 +0 -0
package/README.md CHANGED
@@ -33,7 +33,7 @@ export default defineConfig({
33
33
  svelte(),
34
34
  themeFileApi({
35
35
  themesDir: 'themes',
36
- tokensCssPath: 'src/styles/tokens.css',
36
+ tokensCssPath: 'src/system/styles/tokens.css',
37
37
  }),
38
38
  ],
39
39
  optimizeDeps: {
@@ -44,7 +44,7 @@ export default defineConfig({
44
44
 
45
45
  The `themeFileApi` plugin:
46
46
  - Seeds `themes/` with a default theme on first dev-server start.
47
- - Discovers components at `src/components/*.svelte` and seeds `component-configs/{comp}/default.json` from each component's `:global(:root)` block.
47
+ - Discovers components at `src/system/components/*.svelte` and seeds `component-configs/{comp}/default.json` from each component's `:global(:root)` block.
48
48
  - Hosts the `/api/*` routes the editor uses to save and load themes + per-component configs.
49
49
  - Auto-injects `__PROJECT_ROOT__` for the overlay's "Page Source" link.
50
50
 
@@ -61,6 +61,7 @@ import {
61
61
  initEditorStore,
62
62
  } from '@motion-proto/live-tokens';
63
63
  import App from './App.svelte';
64
+ import { mount } from 'svelte';
64
65
 
65
66
  configureEditor({ storagePrefix: 'my-app-' });
66
67
 
@@ -72,7 +73,7 @@ async function boot() {
72
73
  if (import.meta.env.DEV) {
73
74
  await initializeTheme();
74
75
  }
75
- new App({ target: document.getElementById('app')! });
76
+ mount(App, { target: document.getElementById('app')! });
76
77
  }
77
78
 
78
79
  boot();
@@ -95,7 +96,7 @@ boot();
95
96
  { path: '/components', label: 'Components', icon: 'fa-puzzle-piece' },
96
97
  ]}
97
98
  pageSources={{
98
- '/': 'src/pages/Home.svelte',
99
+ '/': 'src/app/Home.svelte',
99
100
  }}
100
101
  />
101
102
  <ColumnsOverlay />
@@ -135,12 +136,12 @@ CSS variables on `:root`.
135
136
  You can use the package's default as a starting point:
136
137
 
137
138
  ```ts
138
- import '@motion-proto/live-tokens/starter/tokens.css';
139
- import '@motion-proto/live-tokens/starter/site.css'; // optional: themed h1/p/a styles
140
- import '@motion-proto/live-tokens/starter/fonts.css'; // optional: Fraunces + Manrope @font-face
139
+ import '@motion-proto/live-tokens/app/tokens.css';
140
+ import '@motion-proto/live-tokens/app/site.css'; // optional: themed h1/p/a styles
141
+ import '@motion-proto/live-tokens/app/fonts.css'; // optional: Fraunces + Manrope @font-face
141
142
  ```
142
143
 
143
- …or copy `node_modules/@motion-proto/live-tokens/src/styles/tokens.css` into
144
+ …or copy `node_modules/@motion-proto/live-tokens/src/system/styles/tokens.css` into
144
145
  your project and edit. The editor will seed `themes/default.json` on first
145
146
  run and you can promote your edits back into the file.
146
147
 
@@ -150,7 +151,7 @@ The minimum a consumer needs after `npm install @motion-proto/live-tokens`:
150
151
 
151
152
  ```ts
152
153
  // src/main.ts
153
- import '@motion-proto/live-tokens/starter/tokens.css';
154
+ import '@motion-proto/live-tokens/app/tokens.css';
154
155
  import { mount } from 'svelte';
155
156
  import App from './App.svelte';
156
157
 
@@ -189,12 +190,12 @@ npm install
189
190
  npm run dev
190
191
  ```
191
192
 
192
- Open http://localhost:5173 and replace `src/pages/Home.svelte` with your content. The rest of the wiring is already done — it's the same code the npm package ships, just with the App-shell scaffolding included.
193
+ Open http://localhost:5173 and replace `src/app/Home.svelte` with your content. The rest of the wiring is already done — it's the same code the npm package ships, just with the App-shell scaffolding included.
193
194
 
194
195
  ## How the editor ships changes to prod
195
196
 
196
197
  1. Edit in `/editor` or `/components`. Saves write to `themes/{name}.json` and `component-configs/{comp}/{name}.json`.
197
- 2. Promote a theme to "production." Its variables are written into `src/styles/tokens.css` and backed up under `src/styles/_backups/`.
198
+ 2. Promote a theme to "production." Its variables are written into `src/system/styles/tokens.css` and backed up under `src/system/styles/_backups/`.
198
199
  3. `npm run build` bundles `tokens.css` as plain CSS. No editor code, no JSON lookups, no dev surfaces ship to prod.
199
200
 
200
201
  ## File ownership — what the plugin writes
@@ -213,8 +214,8 @@ Knowing which files the plugin touches matters when upgrading the package or wor
213
214
  **At dev-time editor actions, these files get rewritten by your explicit save/promote:**
214
215
 
215
216
  - `themes/{name}.json` — every save in the editor.
216
- - `src/styles/tokens.css` — fully regenerated when you save or promote the production theme. **Treat this as a build artifact.** Hand-edits get clobbered next time the production theme is saved; promote a theme instead.
217
- - `src/styles/fonts.css` — same rule: regenerated from the theme's font sources.
217
+ - `src/system/styles/tokens.css` — fully regenerated when you save or promote the production theme. **Treat this as a build artifact.** Hand-edits get clobbered next time the production theme is saved; promote a theme instead.
218
+ - `src/system/styles/fonts.css` — same rule: regenerated from the theme's font sources.
218
219
  - `component-configs/{comp}/{name}.json` — every save of a per-component config.
219
220
 
220
221
  ## Maintainer notes — publishing
@@ -27,18 +27,18 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
- // src/vite-plugin/index.ts
30
+ // vite-plugin/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  themeFileApi: () => themeFileApi
34
34
  });
35
35
  module.exports = __toCommonJS(index_exports);
36
36
 
37
- // src/vite-plugin/themeFileApi.ts
37
+ // vite-plugin/themeFileApi.ts
38
38
  var import_fs2 = __toESM(require("fs"), 1);
39
39
  var import_path2 = __toESM(require("path"), 1);
40
40
 
41
- // src/lib/parsers/globalRootBlock.ts
41
+ // src/editor/core/themes/parsers/globalRootBlock.ts
42
42
  function extractGlobalRootBody(source) {
43
43
  const re = /:global\(:root\)\s*\{([^}]*)\}/g;
44
44
  const bodies = [];
@@ -49,12 +49,12 @@ function extractGlobalRootBody(source) {
49
49
  return bodies.join("\n");
50
50
  }
51
51
 
52
- // src/lib/files/versionedFileResource.ts
52
+ // src/editor/core/storage/files/versionedFileResourceClient.ts
53
53
  function sanitizeFileName(name) {
54
54
  return name.toLowerCase().trim().replace(/\s+/g, "-").replace(/[^a-z0-9\-_]/g, "").replace(/-+/g, "-").replace(/^-|-$/g, "") || "unnamed";
55
55
  }
56
56
 
57
- // src/vite-plugin/files/versionedFileResource.ts
57
+ // vite-plugin/files/versionedFileResourceServer.ts
58
58
  var import_fs = __toESM(require("fs"), 1);
59
59
  var import_path = __toESM(require("path"), 1);
60
60
  function versionedFileResourceServer(opts) {
@@ -114,7 +114,7 @@ function versionedFileResourceServer(opts) {
114
114
  };
115
115
  }
116
116
 
117
- // src/vite-plugin/files/routeTable.ts
117
+ // vite-plugin/files/routeTable.ts
118
118
  async function dispatch(req, res, routes) {
119
119
  const url = req.url || "";
120
120
  const method = req.method || "GET";
@@ -142,16 +142,35 @@ async function dispatch(req, res, routes) {
142
142
  return false;
143
143
  }
144
144
 
145
- // src/vite-plugin/themeFileApi.ts
146
- var PKG_VERSION = true ? "0.6.2" : "";
145
+ // vite-plugin/themeFileApi.ts
146
+ var import_node_url = require("url");
147
+ var import_meta = {};
148
+ var PKG_VERSION = (() => {
149
+ try {
150
+ let dir = import_path2.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
151
+ for (let i = 0; i < 4; i++) {
152
+ const p = import_path2.default.join(dir, "package.json");
153
+ if (import_fs2.default.existsSync(p)) {
154
+ const json = JSON.parse(import_fs2.default.readFileSync(p, "utf-8"));
155
+ if (json?.name === "@motion-proto/live-tokens") return json.version ?? "";
156
+ }
157
+ const up = import_path2.default.dirname(dir);
158
+ if (up === dir) break;
159
+ dir = up;
160
+ }
161
+ } catch {
162
+ }
163
+ return "";
164
+ })();
147
165
  function themeFileApi(opts) {
148
166
  const THEMES_DIR = import_path2.default.resolve(opts.themesDir);
149
167
  const CSS_PATH = import_path2.default.resolve(opts.tokensCssPath);
150
168
  const FONTS_CSS_PATH = opts.fontsCssPath ? import_path2.default.resolve(opts.fontsCssPath) : import_path2.default.join(import_path2.default.dirname(CSS_PATH), "fonts.css");
151
169
  const API_BASE = opts.apiBase ?? "/api";
152
170
  const COMPONENT_CONFIGS_DIR = opts.componentConfigsDir ? import_path2.default.resolve(opts.componentConfigsDir) : import_path2.default.resolve("component-configs");
153
- const COMPONENTS_SRC_DIR = opts.componentsSrcDir ? import_path2.default.resolve(opts.componentsSrcDir) : import_path2.default.resolve("src/components");
154
- const PRESETS_DIR = opts.presetsDir ? import_path2.default.resolve(opts.presetsDir) : import_path2.default.resolve("presets");
171
+ const COMPONENTS_SRC_DIR = opts.componentsSrcDir ? import_path2.default.resolve(opts.componentsSrcDir) : import_path2.default.resolve("src/system/components");
172
+ const MANIFESTS_DIR = opts.manifestsDir ? import_path2.default.resolve(opts.manifestsDir) : import_path2.default.resolve("manifests");
173
+ const LEGACY_PRESETS_DIR = import_path2.default.resolve("presets");
155
174
  const themesResource = versionedFileResourceServer({
156
175
  dir: THEMES_DIR
157
176
  });
@@ -164,7 +183,7 @@ function themeFileApi(opts) {
164
183
  }
165
184
  return r;
166
185
  }
167
- const presetsResource = versionedFileResourceServer({ dir: PRESETS_DIR });
186
+ const manifestsResource = versionedFileResourceServer({ dir: MANIFESTS_DIR });
168
187
  function ensureThemesDir() {
169
188
  themesResource.ensureDir();
170
189
  if (!import_fs2.default.existsSync(import_path2.default.join(THEMES_DIR, "default.json"))) {
@@ -360,25 +379,63 @@ ${newVars}
360
379
  r.ensureMeta();
361
380
  }
362
381
  }
363
- function ensurePresetsDir() {
364
- presetsResource.ensureDir();
365
- const defaultPath = import_path2.default.join(PRESETS_DIR, "default.json");
382
+ function ensureManifestsDir() {
383
+ if (!import_fs2.default.existsSync(MANIFESTS_DIR) && import_fs2.default.existsSync(LEGACY_PRESETS_DIR)) {
384
+ import_fs2.default.renameSync(LEGACY_PRESETS_DIR, MANIFESTS_DIR);
385
+ const legacyProd = import_path2.default.join(MANIFESTS_DIR, "_production.json");
386
+ if (import_fs2.default.existsSync(legacyProd)) import_fs2.default.unlinkSync(legacyProd);
387
+ }
388
+ manifestsResource.ensureDir();
389
+ const defaultPath = import_path2.default.join(MANIFESTS_DIR, "default.json");
366
390
  if (!import_fs2.default.existsSync(defaultPath)) {
367
391
  const componentConfigs = {};
368
392
  for (const comp of listComponentNames()) {
369
393
  componentConfigs[comp] = componentResource(comp).getActiveName();
370
394
  }
371
395
  const now = (/* @__PURE__ */ new Date()).toISOString();
372
- const defaultPreset = {
373
- name: "Default Preset",
396
+ const defaultManifest = {
397
+ name: "Default",
374
398
  createdAt: now,
375
399
  updatedAt: now,
376
400
  theme: themesResource.getActiveName(),
377
401
  componentConfigs
378
402
  };
379
- import_fs2.default.writeFileSync(defaultPath, JSON.stringify(defaultPreset, null, 2));
403
+ import_fs2.default.writeFileSync(defaultPath, JSON.stringify(defaultManifest, null, 2));
404
+ }
405
+ if (!import_fs2.default.existsSync(manifestsResource.activePath)) {
406
+ import_fs2.default.writeFileSync(
407
+ manifestsResource.activePath,
408
+ JSON.stringify({ activeFile: "default" })
409
+ );
410
+ } else {
411
+ const activeName = manifestsResource.getActiveName();
412
+ if (!import_fs2.default.existsSync(manifestsResource.filePath(activeName))) {
413
+ manifestsResource.setActiveName("default");
414
+ }
380
415
  }
381
- presetsResource.ensureMeta();
416
+ const stragglerProd = import_path2.default.join(MANIFESTS_DIR, "_production.json");
417
+ if (import_fs2.default.existsSync(stragglerProd)) import_fs2.default.unlinkSync(stragglerProd);
418
+ }
419
+ function patchActiveManifest(field, comp, fileName) {
420
+ const activeFile = manifestsResource.getActiveName();
421
+ if (activeFile === "default") return false;
422
+ const manifestPath = manifestsResource.filePath(activeFile);
423
+ if (!import_fs2.default.existsSync(manifestPath)) return false;
424
+ let manifest;
425
+ try {
426
+ manifest = JSON.parse(import_fs2.default.readFileSync(manifestPath, "utf-8"));
427
+ } catch {
428
+ return false;
429
+ }
430
+ if (field === "theme") {
431
+ manifest.theme = fileName;
432
+ } else if (field === "component" && comp) {
433
+ manifest.componentConfigs = manifest.componentConfigs ?? {};
434
+ manifest.componentConfigs[comp] = fileName;
435
+ }
436
+ manifest.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
437
+ import_fs2.default.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
438
+ return true;
382
439
  }
383
440
  function readComponentConfig(comp, name) {
384
441
  const filePath = componentResource(comp).filePath(name);
@@ -443,16 +500,15 @@ ${COMPONENT_OVERRIDES_END}
443
500
  const THEMES_ACTIVE_ROUTE = `${API_BASE}/themes/active`;
444
501
  const THEMES_PRODUCTION_ROUTE = `${API_BASE}/themes/production`;
445
502
  const COMPONENT_CONFIGS_ROUTE = `${API_BASE}/component-configs`;
446
- const PRESETS_ROUTE = `${API_BASE}/presets`;
447
- const PRESETS_ACTIVE_ROUTE = `${API_BASE}/presets/active`;
448
- const PRESETS_PRODUCTION_ROUTE = `${API_BASE}/presets/production`;
503
+ const MANIFESTS_ROUTE = `${API_BASE}/manifests`;
504
+ const MANIFESTS_ACTIVE_ROUTE = `${API_BASE}/manifests/active`;
449
505
  const THEME_BY_NAME_REGEX = new RegExp(`^${escapedBase}/themes/([a-z0-9\\-_]+)$`);
450
506
  const COMP_LIST_REGEX = new RegExp(`^${escapedBase}/component-configs/([a-z0-9\\-_]+)$`);
451
507
  const COMP_ACTIVE_REGEX = new RegExp(`^${escapedBase}/component-configs/([a-z0-9\\-_]+)/active$`);
452
508
  const COMP_PRODUCTION_REGEX = new RegExp(`^${escapedBase}/component-configs/([a-z0-9\\-_]+)/production$`);
453
509
  const COMP_BY_NAME_REGEX = new RegExp(`^${escapedBase}/component-configs/([a-z0-9\\-_]+)/([a-z0-9\\-_]+)$`);
454
- const PRESET_APPLY_REGEX = new RegExp(`^${escapedBase}/presets/([a-z0-9\\-_]+)/apply$`);
455
- const PRESET_BY_NAME_REGEX = new RegExp(`^${escapedBase}/presets/([a-z0-9\\-_]+)$`);
510
+ const MANIFEST_APPLY_REGEX = new RegExp(`^${escapedBase}/manifests/([a-z0-9\\-_]+)/apply$`);
511
+ const MANIFEST_BY_NAME_REGEX = new RegExp(`^${escapedBase}/manifests/([a-z0-9\\-_]+)$`);
456
512
  async function handleListThemes(_ctx) {
457
513
  const activeFile = themesResource.getActiveName();
458
514
  const files = import_fs2.default.readdirSync(THEMES_DIR).filter((f) => f.endsWith(".json") && !f.startsWith("_")).map((f) => {
@@ -511,10 +567,18 @@ ${COMPONENT_OVERRIDES_END}
511
567
  jsonResponse(res, 404, { error: "Theme not found" });
512
568
  return;
513
569
  }
570
+ if (manifestsResource.getActiveName() === "default") {
571
+ jsonResponse(res, 409, {
572
+ error: "Active manifest is protected. Save As first.",
573
+ code: "ACTIVE_IS_PROTECTED"
574
+ });
575
+ return;
576
+ }
514
577
  themesResource.setProductionName(fileName);
515
578
  syncTokensToCss(fileName);
516
579
  syncFontsToCss(fileName);
517
580
  syncComponentsToCss();
581
+ patchActiveManifest("theme", null, fileName);
518
582
  const data = JSON.parse(import_fs2.default.readFileSync(themesResource.filePath(fileName), "utf-8"));
519
583
  jsonResponse(res, 200, {
520
584
  ok: true,
@@ -561,6 +625,13 @@ ${COMPONENT_OVERRIDES_END}
561
625
  jsonResponse(res, 403, { error: "Cannot delete the default theme" });
562
626
  return;
563
627
  }
628
+ if (themesResource.getProductionName() === fileName) {
629
+ jsonResponse(res, 403, {
630
+ error: "Cannot delete the production theme. Adopt a different theme first.",
631
+ code: "PRODUCTION_THEME"
632
+ });
633
+ return;
634
+ }
564
635
  if (import_fs2.default.existsSync(filePath)) {
565
636
  import_fs2.default.unlinkSync(filePath);
566
637
  if (themesResource.getActiveName() === fileName) {
@@ -628,9 +699,17 @@ ${COMPONENT_OVERRIDES_END}
628
699
  jsonResponse(res, 404, { error: "Config not found" });
629
700
  return;
630
701
  }
702
+ if (manifestsResource.getActiveName() === "default") {
703
+ jsonResponse(res, 409, {
704
+ error: "Active manifest is protected. Save As first.",
705
+ code: "ACTIVE_IS_PROTECTED"
706
+ });
707
+ return;
708
+ }
631
709
  r.ensureDir();
632
710
  r.setProductionName(fileName);
633
711
  syncComponentsToCss();
712
+ patchActiveManifest("component", comp, fileName);
634
713
  const cfg = readComponentConfig(comp, fileName);
635
714
  jsonResponse(res, 200, {
636
715
  ok: true,
@@ -720,112 +799,46 @@ ${COMPONENT_OVERRIDES_END}
720
799
  });
721
800
  jsonResponse(res, 200, { component: comp, files, activeFile, productionFile });
722
801
  }
723
- async function handleListPresets({ res }) {
724
- const activeFile = presetsResource.getActiveName();
725
- const files = import_fs2.default.readdirSync(PRESETS_DIR).filter((f) => f.endsWith(".json") && !f.startsWith("_")).map((f) => {
726
- const filePath = import_path2.default.join(PRESETS_DIR, f);
802
+ async function handleListManifests({ res }) {
803
+ const activeFile = manifestsResource.getActiveName();
804
+ const files = import_fs2.default.readdirSync(MANIFESTS_DIR).filter((f) => f.endsWith(".json") && !f.startsWith("_")).map((f) => {
805
+ const filePath = import_path2.default.join(MANIFESTS_DIR, f);
727
806
  const data = JSON.parse(import_fs2.default.readFileSync(filePath, "utf-8"));
728
807
  const fileName = f.replace(".json", "");
729
808
  return {
730
809
  name: data.name || fileName,
731
810
  fileName,
732
811
  updatedAt: data.updatedAt || "",
733
- isActive: fileName === activeFile
812
+ isActive: fileName === activeFile,
813
+ isProtected: fileName === "default"
734
814
  };
735
815
  });
736
816
  jsonResponse(res, 200, { files, activeFile });
737
817
  }
738
- async function handleGetActivePreset({ res }) {
739
- const activeFile = presetsResource.getActiveName();
740
- const filePath = presetsResource.filePath(activeFile);
818
+ async function handleGetActiveManifest({ res }) {
819
+ const activeFile = manifestsResource.getActiveName();
820
+ const filePath = manifestsResource.filePath(activeFile);
741
821
  if (!import_fs2.default.existsSync(filePath)) {
742
- jsonResponse(res, 404, { error: "Active preset not found" });
822
+ jsonResponse(res, 404, { error: "Active manifest not found" });
743
823
  return;
744
824
  }
745
825
  const data = JSON.parse(import_fs2.default.readFileSync(filePath, "utf-8"));
746
826
  data._fileName = activeFile;
747
827
  jsonResponse(res, 200, data);
748
828
  }
749
- async function handleSetActivePreset({ req, res }) {
829
+ async function handleSetActiveManifest({ req, res }) {
750
830
  const body = JSON.parse(await readBody(req));
751
831
  const fileName = sanitizeFileName(body.name || "default");
752
- if (!import_fs2.default.existsSync(presetsResource.filePath(fileName))) {
753
- jsonResponse(res, 404, { error: "Preset not found" });
832
+ if (!import_fs2.default.existsSync(manifestsResource.filePath(fileName))) {
833
+ jsonResponse(res, 404, { error: "Manifest not found" });
754
834
  return;
755
835
  }
756
- presetsResource.setActiveName(fileName);
836
+ manifestsResource.setActiveName(fileName);
757
837
  jsonResponse(res, 200, { ok: true, activeFile: fileName });
758
838
  }
759
- async function handleGetProductionPreset({ res }) {
760
- const prodFile = presetsResource.getProductionName();
761
- const filePath = presetsResource.filePath(prodFile);
762
- if (!import_fs2.default.existsSync(filePath)) {
763
- jsonResponse(res, 200, {
764
- fileName: prodFile,
765
- name: prodFile,
766
- theme: "default",
767
- componentConfigs: {},
768
- updatedAt: ""
769
- });
770
- return;
771
- }
772
- const data = JSON.parse(import_fs2.default.readFileSync(filePath, "utf-8"));
773
- jsonResponse(res, 200, {
774
- fileName: prodFile,
775
- name: data.name || prodFile,
776
- theme: data.theme || "default",
777
- componentConfigs: data.componentConfigs || {},
778
- updatedAt: data.updatedAt || ""
779
- });
780
- }
781
- async function handleSetProductionPreset({ req, res }) {
782
- const body = JSON.parse(await readBody(req));
783
- const fileName = sanitizeFileName(body.name || "default");
784
- const presetPath = presetsResource.filePath(fileName);
785
- if (!import_fs2.default.existsSync(presetPath)) {
786
- jsonResponse(res, 404, { error: "Preset not found" });
787
- return;
788
- }
789
- const preset = JSON.parse(import_fs2.default.readFileSync(presetPath, "utf-8"));
790
- const themeName = sanitizeFileName(preset.theme || "default");
791
- if (!import_fs2.default.existsSync(themesResource.filePath(themeName))) {
792
- jsonResponse(res, 422, { error: `Preset references missing theme: ${themeName}` });
793
- return;
794
- }
795
- const knownComponents = new Set(listComponentNames());
796
- const componentConfigs = preset.componentConfigs ?? {};
797
- const apply = [];
798
- for (const [comp, configFile] of Object.entries(componentConfigs)) {
799
- if (!knownComponents.has(comp)) continue;
800
- const sanitized = sanitizeFileName(String(configFile) || "default");
801
- if (!import_fs2.default.existsSync(componentResource(comp).filePath(sanitized))) {
802
- jsonResponse(res, 422, {
803
- error: `Preset references missing config: ${comp}/${sanitized}`
804
- });
805
- return;
806
- }
807
- apply.push([comp, sanitized]);
808
- }
809
- themesResource.setProductionName(themeName);
810
- for (const [comp, configFile] of apply) {
811
- componentResource(comp).setProductionName(configFile);
812
- }
813
- presetsResource.setProductionName(fileName);
814
- syncTokensToCss(themeName);
815
- syncFontsToCss(themeName);
816
- syncComponentsToCss();
817
- jsonResponse(res, 200, {
818
- ok: true,
819
- fileName,
820
- name: preset.name || fileName,
821
- theme: themeName,
822
- componentConfigs: Object.fromEntries(apply),
823
- updatedAt: preset.updatedAt || ""
824
- });
825
- }
826
- async function handlePresetByName({ params, req, res }) {
839
+ async function handleManifestByName({ params, req, res }) {
827
840
  const [fileName] = params;
828
- const filePath = presetsResource.filePath(fileName);
841
+ const filePath = manifestsResource.filePath(fileName);
829
842
  if (req.method === "GET") {
830
843
  if (!import_fs2.default.existsSync(filePath)) {
831
844
  jsonResponse(res, 404, { error: "Not found" });
@@ -838,7 +851,7 @@ ${COMPONENT_OVERRIDES_END}
838
851
  }
839
852
  if (req.method === "PUT") {
840
853
  if (fileName === "default") {
841
- jsonResponse(res, 403, { error: "Cannot overwrite the default preset" });
854
+ jsonResponse(res, 403, { error: "Cannot overwrite the default manifest" });
842
855
  return;
843
856
  }
844
857
  const body = JSON.parse(await readBody(req));
@@ -857,35 +870,35 @@ ${COMPONENT_OVERRIDES_END}
857
870
  }
858
871
  if (req.method === "DELETE") {
859
872
  if (fileName === "default") {
860
- jsonResponse(res, 403, { error: "Cannot delete the default preset" });
873
+ jsonResponse(res, 403, { error: "Cannot delete the default manifest" });
861
874
  return;
862
875
  }
863
876
  if (import_fs2.default.existsSync(filePath)) {
864
877
  import_fs2.default.unlinkSync(filePath);
865
- if (presetsResource.getActiveName() === fileName) {
866
- presetsResource.setActiveName("default");
878
+ if (manifestsResource.getActiveName() === fileName) {
879
+ manifestsResource.setActiveName("default");
867
880
  }
868
881
  }
869
882
  jsonResponse(res, 200, { ok: true });
870
883
  return;
871
884
  }
872
885
  }
873
- async function handleApplyPreset({ params, res }) {
886
+ async function handleApplyManifest({ params, res }) {
874
887
  const [fileName] = params;
875
- const presetPath = presetsResource.filePath(fileName);
876
- if (!import_fs2.default.existsSync(presetPath)) {
877
- jsonResponse(res, 404, { error: "Preset not found" });
888
+ const manifestPath = manifestsResource.filePath(fileName);
889
+ if (!import_fs2.default.existsSync(manifestPath)) {
890
+ jsonResponse(res, 404, { error: "Manifest not found" });
878
891
  return;
879
892
  }
880
- const preset = JSON.parse(import_fs2.default.readFileSync(presetPath, "utf-8"));
881
- const themeName = sanitizeFileName(preset.theme || "default");
893
+ const manifest = JSON.parse(import_fs2.default.readFileSync(manifestPath, "utf-8"));
894
+ const themeName = sanitizeFileName(manifest.theme || "default");
882
895
  const themePath = themesResource.filePath(themeName);
883
896
  if (!import_fs2.default.existsSync(themePath)) {
884
- jsonResponse(res, 422, { error: `Preset references missing theme: ${themeName}` });
897
+ jsonResponse(res, 422, { error: `Manifest references missing theme: ${themeName}` });
885
898
  return;
886
899
  }
887
900
  const knownComponents = new Set(listComponentNames());
888
- const componentConfigs = preset.componentConfigs ?? {};
901
+ const componentConfigs = manifest.componentConfigs ?? {};
889
902
  const resolvedConfigs = {};
890
903
  const apply = [];
891
904
  for (const [comp, configFile] of Object.entries(componentConfigs)) {
@@ -895,7 +908,7 @@ ${COMPONENT_OVERRIDES_END}
895
908
  const cfgPath = r.filePath(sanitized);
896
909
  if (!import_fs2.default.existsSync(cfgPath)) {
897
910
  jsonResponse(res, 422, {
898
- error: `Preset references missing config: ${comp}/${sanitized}`
911
+ error: `Manifest references missing config: ${comp}/${sanitized}`
899
912
  });
900
913
  return;
901
914
  }
@@ -916,10 +929,10 @@ ${COMPONENT_OVERRIDES_END}
916
929
  const cfg = readComponentConfig(comp, activeName);
917
930
  if (cfg) resolvedConfigs[comp] = { ...cfg, _fileName: activeName };
918
931
  }
919
- presetsResource.setActiveName(fileName);
932
+ manifestsResource.setActiveName(fileName);
920
933
  jsonResponse(res, 200, {
921
934
  ok: true,
922
- preset: { ...preset, _fileName: fileName },
935
+ manifest: { ...manifest, _fileName: fileName },
923
936
  theme: themeData,
924
937
  componentConfigs: resolvedConfigs
925
938
  });
@@ -957,21 +970,19 @@ ${COMPONENT_OVERRIDES_END}
957
970
  { method: "GET", pattern: THEME_BY_NAME_REGEX, handler: handleThemeByName },
958
971
  { method: "PUT", pattern: THEME_BY_NAME_REGEX, handler: handleThemeByName },
959
972
  { method: "DELETE", pattern: THEME_BY_NAME_REGEX, handler: handleThemeByName },
960
- // Presets — list / active / production are exact strings, must run before regexes
961
- { method: "GET", pattern: PRESETS_ROUTE, handler: handleListPresets },
962
- { method: "GET", pattern: PRESETS_ACTIVE_ROUTE, handler: handleGetActivePreset },
963
- { method: "PUT", pattern: PRESETS_ACTIVE_ROUTE, handler: handleSetActivePreset },
964
- { method: "GET", pattern: PRESETS_PRODUCTION_ROUTE, handler: handleGetProductionPreset },
965
- { method: "PUT", pattern: PRESETS_PRODUCTION_ROUTE, handler: handleSetProductionPreset },
966
- // Presets :name/apply (more specific than :name)
967
- { method: "PUT", pattern: PRESET_APPLY_REGEX, handler: handleApplyPreset },
968
- { method: "POST", pattern: PRESET_APPLY_REGEX, handler: methodNotAllowed },
969
- { method: "GET", pattern: PRESET_APPLY_REGEX, handler: methodNotAllowed },
970
- { method: "DELETE", pattern: PRESET_APPLY_REGEX, handler: methodNotAllowed },
971
- // Presets :name CRUD (broadest preset route, runs last)
972
- { method: "GET", pattern: PRESET_BY_NAME_REGEX, handler: handlePresetByName },
973
- { method: "PUT", pattern: PRESET_BY_NAME_REGEX, handler: handlePresetByName },
974
- { method: "DELETE", pattern: PRESET_BY_NAME_REGEX, handler: handlePresetByName }
973
+ // Manifests — list / active are exact strings, must run before regexes
974
+ { method: "GET", pattern: MANIFESTS_ROUTE, handler: handleListManifests },
975
+ { method: "GET", pattern: MANIFESTS_ACTIVE_ROUTE, handler: handleGetActiveManifest },
976
+ { method: "PUT", pattern: MANIFESTS_ACTIVE_ROUTE, handler: handleSetActiveManifest },
977
+ // Manifests :name/apply (more specific than :name)
978
+ { method: "PUT", pattern: MANIFEST_APPLY_REGEX, handler: handleApplyManifest },
979
+ { method: "POST", pattern: MANIFEST_APPLY_REGEX, handler: methodNotAllowed },
980
+ { method: "GET", pattern: MANIFEST_APPLY_REGEX, handler: methodNotAllowed },
981
+ { method: "DELETE", pattern: MANIFEST_APPLY_REGEX, handler: methodNotAllowed },
982
+ // Manifests :name CRUD (broadest manifest route, runs last)
983
+ { method: "GET", pattern: MANIFEST_BY_NAME_REGEX, handler: handleManifestByName },
984
+ { method: "PUT", pattern: MANIFEST_BY_NAME_REGEX, handler: handleManifestByName },
985
+ { method: "DELETE", pattern: MANIFEST_BY_NAME_REGEX, handler: handleManifestByName }
975
986
  ];
976
987
  return {
977
988
  name: "theme-file-api",
@@ -986,7 +997,7 @@ ${COMPONENT_OVERRIDES_END}
986
997
  configureServer(server) {
987
998
  ensureThemesDir();
988
999
  ensureComponentConfigsDir();
989
- ensurePresetsDir();
1000
+ ensureManifestsDir();
990
1001
  server.middlewares.use(async (req, res, next) => {
991
1002
  const handled = await dispatch(req, res, routes);
992
1003
  if (!handled) next();
@@ -7,7 +7,7 @@ interface ThemeFileApiOptions {
7
7
  apiBase?: string;
8
8
  componentConfigsDir?: string;
9
9
  componentsSrcDir?: string;
10
- presetsDir?: string;
10
+ manifestsDir?: string;
11
11
  }
12
12
  declare function themeFileApi(opts: ThemeFileApiOptions): Plugin;
13
13
 
@@ -7,7 +7,7 @@ interface ThemeFileApiOptions {
7
7
  apiBase?: string;
8
8
  componentConfigsDir?: string;
9
9
  componentsSrcDir?: string;
10
- presetsDir?: string;
10
+ manifestsDir?: string;
11
11
  }
12
12
  declare function themeFileApi(opts: ThemeFileApiOptions): Plugin;
13
13