@elytracms/studio 0.0.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 (558) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -0
  3. package/convex/assets.ts +107 -0
  4. package/convex/auth.config.ts +15 -0
  5. package/convex/auth.ts +50 -0
  6. package/convex/cliTokens.ts +63 -0
  7. package/convex/cms.ts +174 -0
  8. package/convex/content.ts +316 -0
  9. package/convex/delivery.ts +266 -0
  10. package/convex/functions.ts +35 -0
  11. package/convex/graphs.ts +51 -0
  12. package/convex/guard.ts +67 -0
  13. package/convex/http.ts +30 -0
  14. package/convex/members.ts +83 -0
  15. package/convex/publishing.ts +102 -0
  16. package/convex/references.ts +168 -0
  17. package/convex/schema.ts +173 -0
  18. package/convex/sync.ts +322 -0
  19. package/convex/tsconfig.json +12 -0
  20. package/convex/users.ts +23 -0
  21. package/convex/webhooks.ts +85 -0
  22. package/dist/components/assets/asset-library.d.ts +14 -0
  23. package/dist/components/assets/asset-library.js +191 -0
  24. package/dist/components/assets/asset-library.js.map +1 -0
  25. package/dist/components/assets/asset-metadata.d.ts +34 -0
  26. package/dist/components/assets/asset-metadata.js +40 -0
  27. package/dist/components/assets/asset-metadata.js.map +1 -0
  28. package/dist/components/assets/asset-search.d.ts +7 -0
  29. package/dist/components/assets/asset-search.js +12 -0
  30. package/dist/components/assets/asset-search.js.map +1 -0
  31. package/dist/components/assets/asset-selection.d.ts +17 -0
  32. package/dist/components/assets/asset-selection.js +33 -0
  33. package/dist/components/assets/asset-selection.js.map +1 -0
  34. package/dist/components/assets/assets-store.d.ts +51 -0
  35. package/dist/components/assets/assets-store.js +153 -0
  36. package/dist/components/assets/assets-store.js.map +1 -0
  37. package/dist/components/auth-context.d.ts +38 -0
  38. package/dist/components/auth-context.js +88 -0
  39. package/dist/components/auth-context.js.map +1 -0
  40. package/dist/components/backend-gate.d.ts +19 -0
  41. package/dist/components/backend-gate.js +63 -0
  42. package/dist/components/backend-gate.js.map +1 -0
  43. package/dist/components/breadcrumb-context.d.ts +39 -0
  44. package/dist/components/breadcrumb-context.js +38 -0
  45. package/dist/components/breadcrumb-context.js.map +1 -0
  46. package/dist/components/builder/blocks-model.d.ts +80 -0
  47. package/dist/components/builder/blocks-model.js +181 -0
  48. package/dist/components/builder/blocks-model.js.map +1 -0
  49. package/dist/components/builder/blocks-panel.d.ts +44 -0
  50. package/dist/components/builder/blocks-panel.js +147 -0
  51. package/dist/components/builder/blocks-panel.js.map +1 -0
  52. package/dist/components/builder/builder-store.d.ts +69 -0
  53. package/dist/components/builder/builder-store.js +294 -0
  54. package/dist/components/builder/builder-store.js.map +1 -0
  55. package/dist/components/builder/canvas-stylesheet.d.ts +4 -0
  56. package/dist/components/builder/canvas-stylesheet.js +24 -0
  57. package/dist/components/builder/canvas-stylesheet.js.map +1 -0
  58. package/dist/components/builder/canvas.d.ts +8 -0
  59. package/dist/components/builder/canvas.js +723 -0
  60. package/dist/components/builder/canvas.js.map +1 -0
  61. package/dist/components/builder/clipboard-actions.d.ts +93 -0
  62. package/dist/components/builder/clipboard-actions.js +246 -0
  63. package/dist/components/builder/clipboard-actions.js.map +1 -0
  64. package/dist/components/builder/composition-field-editor.d.ts +11 -0
  65. package/dist/components/builder/composition-field-editor.js +150 -0
  66. package/dist/components/builder/composition-field-editor.js.map +1 -0
  67. package/dist/components/builder/composition-scope.d.ts +16 -0
  68. package/dist/components/builder/composition-scope.js +7 -0
  69. package/dist/components/builder/composition-scope.js.map +1 -0
  70. package/dist/components/builder/drag-session.d.ts +41 -0
  71. package/dist/components/builder/drag-session.js +51 -0
  72. package/dist/components/builder/drag-session.js.map +1 -0
  73. package/dist/components/builder/fixture-thumbnail.d.ts +18 -0
  74. package/dist/components/builder/fixture-thumbnail.js +97 -0
  75. package/dist/components/builder/fixture-thumbnail.js.map +1 -0
  76. package/dist/components/builder/inline-edit.d.ts +142 -0
  77. package/dist/components/builder/inline-edit.js +136 -0
  78. package/dist/components/builder/inline-edit.js.map +1 -0
  79. package/dist/components/builder/insert-context.d.ts +14 -0
  80. package/dist/components/builder/insert-context.js +65 -0
  81. package/dist/components/builder/insert-context.js.map +1 -0
  82. package/dist/components/builder/insert-menu.d.ts +9 -0
  83. package/dist/components/builder/insert-menu.js +9 -0
  84. package/dist/components/builder/insert-menu.js.map +1 -0
  85. package/dist/components/builder/layout-inspector.d.ts +14 -0
  86. package/dist/components/builder/layout-inspector.js +84 -0
  87. package/dist/components/builder/layout-inspector.js.map +1 -0
  88. package/dist/components/builder/node-factory.d.ts +17 -0
  89. package/dist/components/builder/node-factory.js +90 -0
  90. package/dist/components/builder/node-factory.js.map +1 -0
  91. package/dist/components/builder/page-tree.d.ts +3 -0
  92. package/dist/components/builder/page-tree.js +207 -0
  93. package/dist/components/builder/page-tree.js.map +1 -0
  94. package/dist/components/builder/property-inspector.d.ts +1 -0
  95. package/dist/components/builder/property-inspector.js +233 -0
  96. package/dist/components/builder/property-inspector.js.map +1 -0
  97. package/dist/components/builder/rich-text-toolbar.d.ts +4 -0
  98. package/dist/components/builder/rich-text-toolbar.js +104 -0
  99. package/dist/components/builder/rich-text-toolbar.js.map +1 -0
  100. package/dist/components/builder/spacing-handles.d.ts +22 -0
  101. package/dist/components/builder/spacing-handles.js +213 -0
  102. package/dist/components/builder/spacing-handles.js.map +1 -0
  103. package/dist/components/cms/asset-picker.d.ts +12 -0
  104. package/dist/components/cms/asset-picker.js +60 -0
  105. package/dist/components/cms/asset-picker.js.map +1 -0
  106. package/dist/components/cms/bulk-actions.d.ts +60 -0
  107. package/dist/components/cms/bulk-actions.js +95 -0
  108. package/dist/components/cms/bulk-actions.js.map +1 -0
  109. package/dist/components/cms/bulk-bar.d.ts +23 -0
  110. package/dist/components/cms/bulk-bar.js +26 -0
  111. package/dist/components/cms/bulk-bar.js.map +1 -0
  112. package/dist/components/cms/cell-edit.d.ts +91 -0
  113. package/dist/components/cms/cell-edit.js +144 -0
  114. package/dist/components/cms/cell-edit.js.map +1 -0
  115. package/dist/components/cms/cell.d.ts +29 -0
  116. package/dist/components/cms/cell.js +127 -0
  117. package/dist/components/cms/cell.js.map +1 -0
  118. package/dist/components/cms/cms-index.d.ts +8 -0
  119. package/dist/components/cms/cms-index.js +23 -0
  120. package/dist/components/cms/cms-index.js.map +1 -0
  121. package/dist/components/cms/cms-store.d.ts +188 -0
  122. package/dist/components/cms/cms-store.js +702 -0
  123. package/dist/components/cms/cms-store.js.map +1 -0
  124. package/dist/components/cms/collection-table.d.ts +6 -0
  125. package/dist/components/cms/collection-table.js +250 -0
  126. package/dist/components/cms/collection-table.js.map +1 -0
  127. package/dist/components/cms/collections-sidebar.d.ts +9 -0
  128. package/dist/components/cms/collections-sidebar.js +25 -0
  129. package/dist/components/cms/collections-sidebar.js.map +1 -0
  130. package/dist/components/cms/detail-editor.d.ts +7 -0
  131. package/dist/components/cms/detail-editor.js +386 -0
  132. package/dist/components/cms/detail-editor.js.map +1 -0
  133. package/dist/components/cms/doc-state.d.ts +13 -0
  134. package/dist/components/cms/doc-state.js +18 -0
  135. package/dist/components/cms/doc-state.js.map +1 -0
  136. package/dist/components/cms/document-editor-context.d.ts +48 -0
  137. package/dist/components/cms/document-editor-context.js +23 -0
  138. package/dist/components/cms/document-editor-context.js.map +1 -0
  139. package/dist/components/cms/editable-cell.d.ts +22 -0
  140. package/dist/components/cms/editable-cell.js +176 -0
  141. package/dist/components/cms/editable-cell.js.map +1 -0
  142. package/dist/components/cms/field-control.d.ts +8 -0
  143. package/dist/components/cms/field-control.js +149 -0
  144. package/dist/components/cms/field-control.js.map +1 -0
  145. package/dist/components/cms/filter-builder.d.ts +12 -0
  146. package/dist/components/cms/filter-builder.js +84 -0
  147. package/dist/components/cms/filter-builder.js.map +1 -0
  148. package/dist/components/cms/import-export.d.ts +6 -0
  149. package/dist/components/cms/import-export.js +33 -0
  150. package/dist/components/cms/import-export.js.map +1 -0
  151. package/dist/components/cms/new-page-dialog.d.ts +22 -0
  152. package/dist/components/cms/new-page-dialog.js +42 -0
  153. package/dist/components/cms/new-page-dialog.js.map +1 -0
  154. package/dist/components/cms/reference-confirm.d.ts +25 -0
  155. package/dist/components/cms/reference-confirm.js +124 -0
  156. package/dist/components/cms/reference-confirm.js.map +1 -0
  157. package/dist/components/cms/relation-picker.d.ts +16 -0
  158. package/dist/components/cms/relation-picker.js +47 -0
  159. package/dist/components/cms/relation-picker.js.map +1 -0
  160. package/dist/components/cms/use-cell-edit.d.ts +33 -0
  161. package/dist/components/cms/use-cell-edit.js +125 -0
  162. package/dist/components/cms/use-cell-edit.js.map +1 -0
  163. package/dist/components/cms/versions-model.d.ts +15 -0
  164. package/dist/components/cms/versions-model.js +23 -0
  165. package/dist/components/cms/versions-model.js.map +1 -0
  166. package/dist/components/cms/versions-pane.d.ts +14 -0
  167. package/dist/components/cms/versions-pane.js +86 -0
  168. package/dist/components/cms/versions-pane.js.map +1 -0
  169. package/dist/components/cms/view-bar.d.ts +11 -0
  170. package/dist/components/cms/view-bar.js +80 -0
  171. package/dist/components/cms/view-bar.js.map +1 -0
  172. package/dist/components/collab/collab-context.d.ts +34 -0
  173. package/dist/components/collab/collab-context.js +52 -0
  174. package/dist/components/collab/collab-context.js.map +1 -0
  175. package/dist/components/collab/collab-seed.d.ts +27 -0
  176. package/dist/components/collab/collab-seed.js +42 -0
  177. package/dist/components/collab/collab-seed.js.map +1 -0
  178. package/dist/components/components/component-detail.d.ts +9 -0
  179. package/dist/components/components/component-detail.js +30 -0
  180. package/dist/components/components/component-detail.js.map +1 -0
  181. package/dist/components/components/component-status.d.ts +10 -0
  182. package/dist/components/components/component-status.js +30 -0
  183. package/dist/components/components/component-status.js.map +1 -0
  184. package/dist/components/components/components-index.d.ts +8 -0
  185. package/dist/components/components/components-index.js +42 -0
  186. package/dist/components/components/components-index.js.map +1 -0
  187. package/dist/components/components/field-inspector.d.ts +9 -0
  188. package/dist/components/components/field-inspector.js +38 -0
  189. package/dist/components/components/field-inspector.js.map +1 -0
  190. package/dist/components/components/fixture-runner.d.ts +10 -0
  191. package/dist/components/components/fixture-runner.js +24 -0
  192. package/dist/components/components/fixture-runner.js.map +1 -0
  193. package/dist/components/components/registry-browser.d.ts +4 -0
  194. package/dist/components/components/registry-browser.js +64 -0
  195. package/dist/components/components/registry-browser.js.map +1 -0
  196. package/dist/components/current-user-menu.d.ts +13 -0
  197. package/dist/components/current-user-menu.js +31 -0
  198. package/dist/components/current-user-menu.js.map +1 -0
  199. package/dist/components/dev-login-badge.d.ts +9 -0
  200. package/dist/components/dev-login-badge.js +18 -0
  201. package/dist/components/dev-login-badge.js.map +1 -0
  202. package/dist/components/extensions/extensions-view.d.ts +7 -0
  203. package/dist/components/extensions/extensions-view.js +126 -0
  204. package/dist/components/extensions/extensions-view.js.map +1 -0
  205. package/dist/components/guards.d.ts +27 -0
  206. package/dist/components/guards.js +46 -0
  207. package/dist/components/guards.js.map +1 -0
  208. package/dist/components/inspector/inspector-sidebar.d.ts +26 -0
  209. package/dist/components/inspector/inspector-sidebar.js +17 -0
  210. package/dist/components/inspector/inspector-sidebar.js.map +1 -0
  211. package/dist/components/operation-error.d.ts +17 -0
  212. package/dist/components/operation-error.js +54 -0
  213. package/dist/components/operation-error.js.map +1 -0
  214. package/dist/components/playground-badge.d.ts +10 -0
  215. package/dist/components/playground-badge.js +19 -0
  216. package/dist/components/playground-badge.js.map +1 -0
  217. package/dist/components/project-list.d.ts +15 -0
  218. package/dist/components/project-list.js +52 -0
  219. package/dist/components/project-list.js.map +1 -0
  220. package/dist/components/project-session.d.ts +46 -0
  221. package/dist/components/project-session.js +107 -0
  222. package/dist/components/project-session.js.map +1 -0
  223. package/dist/components/project-switcher.d.ts +11 -0
  224. package/dist/components/project-switcher.js +44 -0
  225. package/dist/components/project-switcher.js.map +1 -0
  226. package/dist/components/references/builder-deep-link.d.ts +12 -0
  227. package/dist/components/references/builder-deep-link.js +53 -0
  228. package/dist/components/references/builder-deep-link.js.map +1 -0
  229. package/dist/components/references/references-panel.d.ts +17 -0
  230. package/dist/components/references/references-panel.js +66 -0
  231. package/dist/components/references/references-panel.js.map +1 -0
  232. package/dist/components/routes/redirect-chain.d.ts +9 -0
  233. package/dist/components/routes/redirect-chain.js +16 -0
  234. package/dist/components/routes/redirect-chain.js.map +1 -0
  235. package/dist/components/routes/redirect-manager.d.ts +13 -0
  236. package/dist/components/routes/redirect-manager.js +24 -0
  237. package/dist/components/routes/redirect-manager.js.map +1 -0
  238. package/dist/components/routes/route-list.d.ts +35 -0
  239. package/dist/components/routes/route-list.js +69 -0
  240. package/dist/components/routes/route-list.js.map +1 -0
  241. package/dist/components/routes/routes-shell.d.ts +14 -0
  242. package/dist/components/routes/routes-shell.js +68 -0
  243. package/dist/components/routes/routes-shell.js.map +1 -0
  244. package/dist/components/section-nav.d.ts +17 -0
  245. package/dist/components/section-nav.js +33 -0
  246. package/dist/components/section-nav.js.map +1 -0
  247. package/dist/components/section-state.d.ts +24 -0
  248. package/dist/components/section-state.js +78 -0
  249. package/dist/components/section-state.js.map +1 -0
  250. package/dist/components/section-surface.d.ts +31 -0
  251. package/dist/components/section-surface.js +46 -0
  252. package/dist/components/section-surface.js.map +1 -0
  253. package/dist/components/sections.d.ts +38 -0
  254. package/dist/components/sections.js +72 -0
  255. package/dist/components/sections.js.map +1 -0
  256. package/dist/components/settings-form.d.ts +10 -0
  257. package/dist/components/settings-form.js +17 -0
  258. package/dist/components/settings-form.js.map +1 -0
  259. package/dist/components/studio-context.d.ts +22 -0
  260. package/dist/components/studio-context.js +48 -0
  261. package/dist/components/studio-context.js.map +1 -0
  262. package/dist/components/studio-project-screen.d.ts +19 -0
  263. package/dist/components/studio-project-screen.js +195 -0
  264. package/dist/components/studio-project-screen.js.map +1 -0
  265. package/dist/components/studio-shell.d.ts +18 -0
  266. package/dist/components/studio-shell.js +64 -0
  267. package/dist/components/studio-shell.js.map +1 -0
  268. package/dist/components/theme-context.d.ts +17 -0
  269. package/dist/components/theme-context.js +26 -0
  270. package/dist/components/theme-context.js.map +1 -0
  271. package/dist/components/workspace-gate.d.ts +12 -0
  272. package/dist/components/workspace-gate.js +27 -0
  273. package/dist/components/workspace-gate.js.map +1 -0
  274. package/dist/components/workspace-projects.d.ts +13 -0
  275. package/dist/components/workspace-projects.js +18 -0
  276. package/dist/components/workspace-projects.js.map +1 -0
  277. package/dist/lib/assets/delete-asset.d.ts +34 -0
  278. package/dist/lib/assets/delete-asset.js +34 -0
  279. package/dist/lib/assets/delete-asset.js.map +1 -0
  280. package/dist/lib/assets/image-dimensions.d.ts +18 -0
  281. package/dist/lib/assets/image-dimensions.js +26 -0
  282. package/dist/lib/assets/image-dimensions.js.map +1 -0
  283. package/dist/lib/assets/index.d.ts +9 -0
  284. package/dist/lib/assets/index.js +10 -0
  285. package/dist/lib/assets/index.js.map +1 -0
  286. package/dist/lib/assets/upload-state.d.ts +53 -0
  287. package/dist/lib/assets/upload-state.js +59 -0
  288. package/dist/lib/assets/upload-state.js.map +1 -0
  289. package/dist/lib/assets/upload.d.ts +56 -0
  290. package/dist/lib/assets/upload.js +125 -0
  291. package/dist/lib/assets/upload.js.map +1 -0
  292. package/dist/lib/auth/auth-adapter.d.ts +57 -0
  293. package/dist/lib/auth/auth-adapter.js +13 -0
  294. package/dist/lib/auth/auth-adapter.js.map +1 -0
  295. package/dist/lib/auth/convex-auth-adapter.d.ts +39 -0
  296. package/dist/lib/auth/convex-auth-adapter.js +171 -0
  297. package/dist/lib/auth/convex-auth-adapter.js.map +1 -0
  298. package/dist/lib/auth/dev-auto-login-adapter.d.ts +25 -0
  299. package/dist/lib/auth/dev-auto-login-adapter.js +40 -0
  300. package/dist/lib/auth/dev-auto-login-adapter.js.map +1 -0
  301. package/dist/lib/auth/index.d.ts +28 -0
  302. package/dist/lib/auth/index.js +61 -0
  303. package/dist/lib/auth/index.js.map +1 -0
  304. package/dist/lib/auth/local-auth-adapter.d.ts +57 -0
  305. package/dist/lib/auth/local-auth-adapter.js +78 -0
  306. package/dist/lib/auth/local-auth-adapter.js.map +1 -0
  307. package/dist/lib/auth/route-guard.d.ts +33 -0
  308. package/dist/lib/auth/route-guard.js +51 -0
  309. package/dist/lib/auth/route-guard.js.map +1 -0
  310. package/dist/lib/auth-errors.d.ts +42 -0
  311. package/dist/lib/auth-errors.js +74 -0
  312. package/dist/lib/auth-errors.js.map +1 -0
  313. package/dist/lib/bindings/section-bindings.d.ts +24 -0
  314. package/dist/lib/bindings/section-bindings.js +9 -0
  315. package/dist/lib/bindings/section-bindings.js.map +1 -0
  316. package/dist/lib/clipboard/index.d.ts +7 -0
  317. package/dist/lib/clipboard/index.js +8 -0
  318. package/dist/lib/clipboard/index.js.map +1 -0
  319. package/dist/lib/clipboard/os-clipboard.d.ts +46 -0
  320. package/dist/lib/clipboard/os-clipboard.js +105 -0
  321. package/dist/lib/clipboard/os-clipboard.js.map +1 -0
  322. package/dist/lib/clipboard/paste-issues.d.ts +34 -0
  323. package/dist/lib/clipboard/paste-issues.js +67 -0
  324. package/dist/lib/clipboard/paste-issues.js.map +1 -0
  325. package/dist/lib/clipboard/paste-target.d.ts +20 -0
  326. package/dist/lib/clipboard/paste-target.js +28 -0
  327. package/dist/lib/clipboard/paste-target.js.map +1 -0
  328. package/dist/lib/cms/published-documents.d.ts +30 -0
  329. package/dist/lib/cms/published-documents.js +75 -0
  330. package/dist/lib/cms/published-documents.js.map +1 -0
  331. package/dist/lib/cms-views/index.d.ts +9 -0
  332. package/dist/lib/cms-views/index.js +10 -0
  333. package/dist/lib/cms-views/index.js.map +1 -0
  334. package/dist/lib/cms-views/selection.d.ts +29 -0
  335. package/dist/lib/cms-views/selection.js +46 -0
  336. package/dist/lib/cms-views/selection.js.map +1 -0
  337. package/dist/lib/cms-views/view-model.d.ts +192 -0
  338. package/dist/lib/cms-views/view-model.js +353 -0
  339. package/dist/lib/cms-views/view-model.js.map +1 -0
  340. package/dist/lib/cms-views/views-store.d.ts +70 -0
  341. package/dist/lib/cms-views/views-store.js +129 -0
  342. package/dist/lib/cms-views/views-store.js.map +1 -0
  343. package/dist/lib/data/collection-content.d.ts +105 -0
  344. package/dist/lib/data/collection-content.js +196 -0
  345. package/dist/lib/data/collection-content.js.map +1 -0
  346. package/dist/lib/data/data-store.d.ts +97 -0
  347. package/dist/lib/data/data-store.js +205 -0
  348. package/dist/lib/data/data-store.js.map +1 -0
  349. package/dist/lib/data/index.d.ts +4 -0
  350. package/dist/lib/data/index.js +8 -0
  351. package/dist/lib/data/index.js.map +1 -0
  352. package/dist/lib/data/providers.d.ts +143 -0
  353. package/dist/lib/data/providers.js +255 -0
  354. package/dist/lib/data/providers.js.map +1 -0
  355. package/dist/lib/data/sample-capture.d.ts +30 -0
  356. package/dist/lib/data/sample-capture.js +70 -0
  357. package/dist/lib/data/sample-capture.js.map +1 -0
  358. package/dist/lib/data/sources-store.d.ts +42 -0
  359. package/dist/lib/data/sources-store.js +120 -0
  360. package/dist/lib/data/sources-store.js.map +1 -0
  361. package/dist/lib/dnd/drop-rules.d.ts +219 -0
  362. package/dist/lib/dnd/drop-rules.js +257 -0
  363. package/dist/lib/dnd/drop-rules.js.map +1 -0
  364. package/dist/lib/dnd/gap-drag.d.ts +66 -0
  365. package/dist/lib/dnd/gap-drag.js +95 -0
  366. package/dist/lib/dnd/gap-drag.js.map +1 -0
  367. package/dist/lib/locale/binding-fallback.d.ts +28 -0
  368. package/dist/lib/locale/binding-fallback.js +66 -0
  369. package/dist/lib/locale/binding-fallback.js.map +1 -0
  370. package/dist/lib/locale/fallback.d.ts +43 -0
  371. package/dist/lib/locale/fallback.js +52 -0
  372. package/dist/lib/locale/fallback.js.map +1 -0
  373. package/dist/lib/locale/index.d.ts +6 -0
  374. package/dist/lib/locale/index.js +7 -0
  375. package/dist/lib/locale/index.js.map +1 -0
  376. package/dist/lib/locale/locale-store.d.ts +40 -0
  377. package/dist/lib/locale/locale-store.js +61 -0
  378. package/dist/lib/locale/locale-store.js.map +1 -0
  379. package/dist/lib/locale/locale-switcher.d.ts +10 -0
  380. package/dist/lib/locale/locale-switcher.js +24 -0
  381. package/dist/lib/locale/locale-switcher.js.map +1 -0
  382. package/dist/lib/locale/route-variant.d.ts +14 -0
  383. package/dist/lib/locale/route-variant.js +11 -0
  384. package/dist/lib/locale/route-variant.js.map +1 -0
  385. package/dist/lib/locale/use-studio-locale.d.ts +10 -0
  386. package/dist/lib/locale/use-studio-locale.js +8 -0
  387. package/dist/lib/locale/use-studio-locale.js.map +1 -0
  388. package/dist/lib/operations/asset-repository.d.ts +15 -0
  389. package/dist/lib/operations/asset-repository.js +56 -0
  390. package/dist/lib/operations/asset-repository.js.map +1 -0
  391. package/dist/lib/operations/cms-persistence.d.ts +35 -0
  392. package/dist/lib/operations/cms-persistence.js +75 -0
  393. package/dist/lib/operations/cms-persistence.js.map +1 -0
  394. package/dist/lib/operations/graph-commands.d.ts +140 -0
  395. package/dist/lib/operations/graph-commands.js +86 -0
  396. package/dist/lib/operations/graph-commands.js.map +1 -0
  397. package/dist/lib/operations/graph-persistence.d.ts +27 -0
  398. package/dist/lib/operations/graph-persistence.js +35 -0
  399. package/dist/lib/operations/graph-persistence.js.map +1 -0
  400. package/dist/lib/operations/index.d.ts +13 -0
  401. package/dist/lib/operations/index.js +14 -0
  402. package/dist/lib/operations/index.js.map +1 -0
  403. package/dist/lib/operations/operations-package.d.ts +6 -0
  404. package/dist/lib/operations/operations-package.js +7 -0
  405. package/dist/lib/operations/operations-package.js.map +1 -0
  406. package/dist/lib/operations/persist-queue.d.ts +16 -0
  407. package/dist/lib/operations/persist-queue.js +18 -0
  408. package/dist/lib/operations/persist-queue.js.map +1 -0
  409. package/dist/lib/operations/session-hydration.d.ts +84 -0
  410. package/dist/lib/operations/session-hydration.js +112 -0
  411. package/dist/lib/operations/session-hydration.js.map +1 -0
  412. package/dist/lib/operations/studio-operations.d.ts +59 -0
  413. package/dist/lib/operations/studio-operations.js +92 -0
  414. package/dist/lib/operations/studio-operations.js.map +1 -0
  415. package/dist/lib/persistence/backend-mode.d.ts +69 -0
  416. package/dist/lib/persistence/backend-mode.js +120 -0
  417. package/dist/lib/persistence/backend-mode.js.map +1 -0
  418. package/dist/lib/persistence/convex-adapter.d.ts +34 -0
  419. package/dist/lib/persistence/convex-adapter.js +681 -0
  420. package/dist/lib/persistence/convex-adapter.js.map +1 -0
  421. package/dist/lib/persistence/convex-blob-storage.d.ts +57 -0
  422. package/dist/lib/persistence/convex-blob-storage.js +97 -0
  423. package/dist/lib/persistence/convex-blob-storage.js.map +1 -0
  424. package/dist/lib/persistence/convex-client.d.ts +19 -0
  425. package/dist/lib/persistence/convex-client.js +40 -0
  426. package/dist/lib/persistence/convex-client.js.map +1 -0
  427. package/dist/lib/persistence/index.d.ts +30 -0
  428. package/dist/lib/persistence/index.js +60 -0
  429. package/dist/lib/persistence/index.js.map +1 -0
  430. package/dist/lib/persona/labels.d.ts +23 -0
  431. package/dist/lib/persona/labels.js +122 -0
  432. package/dist/lib/persona/labels.js.map +1 -0
  433. package/dist/lib/rail.d.ts +11 -0
  434. package/dist/lib/rail.js +26 -0
  435. package/dist/lib/rail.js.map +1 -0
  436. package/dist/lib/references/impact.d.ts +64 -0
  437. package/dist/lib/references/impact.js +62 -0
  438. package/dist/lib/references/impact.js.map +1 -0
  439. package/dist/lib/references/index.d.ts +7 -0
  440. package/dist/lib/references/index.js +8 -0
  441. package/dist/lib/references/index.js.map +1 -0
  442. package/dist/lib/references/reference-model.d.ts +125 -0
  443. package/dist/lib/references/reference-model.js +242 -0
  444. package/dist/lib/references/reference-model.js.map +1 -0
  445. package/dist/lib/references/references-store.d.ts +65 -0
  446. package/dist/lib/references/references-store.js +221 -0
  447. package/dist/lib/references/references-store.js.map +1 -0
  448. package/dist/lib/registry/index.d.ts +65 -0
  449. package/dist/lib/registry/index.js +114 -0
  450. package/dist/lib/registry/index.js.map +1 -0
  451. package/dist/lib/registry/preview.d.ts +15 -0
  452. package/dist/lib/registry/preview.js +110 -0
  453. package/dist/lib/registry/preview.js.map +1 -0
  454. package/dist/lib/registry/project-components.d.ts +16 -0
  455. package/dist/lib/registry/project-components.js +152 -0
  456. package/dist/lib/registry/project-components.js.map +1 -0
  457. package/dist/lib/routing/index.d.ts +10 -0
  458. package/dist/lib/routing/index.js +11 -0
  459. package/dist/lib/routing/index.js.map +1 -0
  460. package/dist/lib/routing/routing-analysis.d.ts +26 -0
  461. package/dist/lib/routing/routing-analysis.js +37 -0
  462. package/dist/lib/routing/routing-analysis.js.map +1 -0
  463. package/dist/lib/routing/routing-store.d.ts +50 -0
  464. package/dist/lib/routing/routing-store.js +72 -0
  465. package/dist/lib/routing/routing-store.js.map +1 -0
  466. package/dist/lib/starters/kit-session.d.ts +5 -0
  467. package/dist/lib/starters/kit-session.js +17 -0
  468. package/dist/lib/starters/kit-session.js.map +1 -0
  469. package/dist/lib/theme.d.ts +21 -0
  470. package/dist/lib/theme.js +32 -0
  471. package/dist/lib/theme.js.map +1 -0
  472. package/dist/lib/utils.d.ts +11 -0
  473. package/dist/lib/utils.js +28 -0
  474. package/dist/lib/utils.js.map +1 -0
  475. package/dist/lib/webhooks/config.d.ts +15 -0
  476. package/dist/lib/webhooks/config.js +64 -0
  477. package/dist/lib/webhooks/config.js.map +1 -0
  478. package/dist/lib/webhooks/dispatcher.d.ts +67 -0
  479. package/dist/lib/webhooks/dispatcher.js +61 -0
  480. package/dist/lib/webhooks/dispatcher.js.map +1 -0
  481. package/dist/lib/webhooks/index.d.ts +11 -0
  482. package/dist/lib/webhooks/index.js +10 -0
  483. package/dist/lib/webhooks/index.js.map +1 -0
  484. package/dist/lib/webhooks/signing.d.ts +15 -0
  485. package/dist/lib/webhooks/signing.js +24 -0
  486. package/dist/lib/webhooks/signing.js.map +1 -0
  487. package/dist/lib/webhooks/tags.d.ts +25 -0
  488. package/dist/lib/webhooks/tags.js +173 -0
  489. package/dist/lib/webhooks/tags.js.map +1 -0
  490. package/dist/lib/working-graph.d.ts +82 -0
  491. package/dist/lib/working-graph.js +113 -0
  492. package/dist/lib/working-graph.js.map +1 -0
  493. package/dist/lib/workspace/index.d.ts +109 -0
  494. package/dist/lib/workspace/index.js +206 -0
  495. package/dist/lib/workspace/index.js.map +1 -0
  496. package/dist/lib/workspace/switcher-source.d.ts +39 -0
  497. package/dist/lib/workspace/switcher-source.js +23 -0
  498. package/dist/lib/workspace/switcher-source.js.map +1 -0
  499. package/dist/lib/workspace/workspace-source.d.ts +47 -0
  500. package/dist/lib/workspace/workspace-source.js +67 -0
  501. package/dist/lib/workspace/workspace-source.js.map +1 -0
  502. package/dist/router/index.d.ts +32 -0
  503. package/dist/router/index.js +32 -0
  504. package/dist/router/index.js.map +1 -0
  505. package/dist/router/match.d.ts +75 -0
  506. package/dist/router/match.js +87 -0
  507. package/dist/router/match.js.map +1 -0
  508. package/dist/router/search.d.ts +22 -0
  509. package/dist/router/search.js +16 -0
  510. package/dist/router/search.js.map +1 -0
  511. package/dist/ui/avatar.d.ts +17 -0
  512. package/dist/ui/avatar.js +38 -0
  513. package/dist/ui/avatar.js.map +1 -0
  514. package/dist/ui/badge.d.ts +9 -0
  515. package/dist/ui/badge.js +23 -0
  516. package/dist/ui/badge.js.map +1 -0
  517. package/dist/ui/button.d.ts +11 -0
  518. package/dist/ui/button.js +30 -0
  519. package/dist/ui/button.js.map +1 -0
  520. package/dist/ui/card.d.ts +11 -0
  521. package/dist/ui/card.js +23 -0
  522. package/dist/ui/card.js.map +1 -0
  523. package/dist/ui/dialog.d.ts +12 -0
  524. package/dist/ui/dialog.js +27 -0
  525. package/dist/ui/dialog.js.map +1 -0
  526. package/dist/ui/dropdown-menu.d.ts +15 -0
  527. package/dist/ui/dropdown-menu.js +24 -0
  528. package/dist/ui/dropdown-menu.js.map +1 -0
  529. package/dist/ui/field.d.ts +15 -0
  530. package/dist/ui/field.js +14 -0
  531. package/dist/ui/field.js.map +1 -0
  532. package/dist/ui/index.d.ts +14 -0
  533. package/dist/ui/index.js +15 -0
  534. package/dist/ui/index.js.map +1 -0
  535. package/dist/ui/input.d.ts +3 -0
  536. package/dist/ui/input.js +7 -0
  537. package/dist/ui/input.js.map +1 -0
  538. package/dist/ui/inspector.d.ts +18 -0
  539. package/dist/ui/inspector.js +14 -0
  540. package/dist/ui/inspector.js.map +1 -0
  541. package/dist/ui/layout.d.ts +45 -0
  542. package/dist/ui/layout.js +48 -0
  543. package/dist/ui/layout.js.map +1 -0
  544. package/dist/ui/panel.d.ts +12 -0
  545. package/dist/ui/panel.js +20 -0
  546. package/dist/ui/panel.js.map +1 -0
  547. package/dist/ui/separator.d.ts +6 -0
  548. package/dist/ui/separator.js +7 -0
  549. package/dist/ui/separator.js.map +1 -0
  550. package/dist/ui/toolbar.d.ts +9 -0
  551. package/dist/ui/toolbar.js +16 -0
  552. package/dist/ui/toolbar.js.map +1 -0
  553. package/dist/ui/typography.d.ts +50 -0
  554. package/dist/ui/typography.js +43 -0
  555. package/dist/ui/typography.js.map +1 -0
  556. package/package.json +149 -0
  557. package/src/styles/studio.css +101 -0
  558. package/src/styles/tokens.css +63 -0
@@ -0,0 +1,34 @@
1
+ import type { AssetRepository, BlobStorageAdapter, ReferenceIndexRepository } from '@elytracms/persistence';
2
+ /**
3
+ * Reference-respecting asset deletion (EC-151, reworked EC-202). Deleting an
4
+ * asset that is referenced is blocked until explicitly confirmed; the usage
5
+ * count comes from the **EC-155 reference index** (`references.inbound` for the
6
+ * `{ type: 'asset' }` target) — index-accurate, replacing the interim string
7
+ * scan (`find-asset-usages`), which could miss rich-text asset hrefs and
8
+ * false-positive on unrelated strings. Deleting an unused asset removes bytes
9
+ * (blob) AND the metadata record. Results are structured data — never throws.
10
+ */
11
+ export interface DeleteAssetDeps {
12
+ assets: AssetRepository;
13
+ blobs: BlobStorageAdapter;
14
+ /** The EC-155 reference index — the accurate inbound-usage source (EC-202). */
15
+ references: Pick<ReferenceIndexRepository, 'inbound'>;
16
+ }
17
+ export type DeleteAssetResult = {
18
+ outcome: 'deleted';
19
+ }
20
+ /** The asset is referenced and `confirmInUse` was not set: nothing was removed. */
21
+ | {
22
+ outcome: 'blocked';
23
+ usageCount: number;
24
+ } | {
25
+ outcome: 'not-found';
26
+ } | {
27
+ outcome: 'error';
28
+ message: string;
29
+ };
30
+ export interface DeleteAssetOptions {
31
+ /** Caller has seen the usage count and explicitly confirmed deletion. */
32
+ confirmInUse?: boolean;
33
+ }
34
+ export declare function deleteAsset(deps: DeleteAssetDeps, projectId: string, assetId: string, options?: DeleteAssetOptions): Promise<DeleteAssetResult>;
@@ -0,0 +1,34 @@
1
+ import { RecordNotFoundError } from '@elytracms/persistence';
2
+ export async function deleteAsset(deps, projectId, assetId, options = {}) {
3
+ try {
4
+ const asset = await deps.assets.findAsset(projectId, assetId);
5
+ if (!asset)
6
+ return { outcome: 'not-found' };
7
+ const usageCount = await assetUsageCount(deps, projectId, assetId);
8
+ if (usageCount > 0 && options.confirmInUse !== true) {
9
+ return { outcome: 'blocked', usageCount };
10
+ }
11
+ // Bytes first, metadata last: a failure midway leaves a visible metadata
12
+ // record (re-deletable) rather than invisible orphaned bytes.
13
+ await deps.blobs.delete(asset.storageKey);
14
+ await deps.assets.removeAsset(projectId, assetId);
15
+ return { outcome: 'deleted' };
16
+ }
17
+ catch (error) {
18
+ if (error instanceof RecordNotFoundError)
19
+ return { outcome: 'not-found' };
20
+ return { outcome: 'error', message: error instanceof Error ? error.message : String(error) };
21
+ }
22
+ }
23
+ /**
24
+ * Distinct inbound usages of an asset from the reference index (EC-202). One
25
+ * `source + path` (e.g. `post:hello · values/cover`) can carry both a draft and
26
+ * a published index entry — that is a single usage, so variants collapse before
27
+ * counting (the gate is "is this referenced", not "how many index rows").
28
+ */
29
+ async function assetUsageCount(deps, projectId, assetId) {
30
+ const inbound = await deps.references.inbound(projectId, { type: 'asset', id: assetId });
31
+ const distinct = new Set(inbound.map((entry) => `${entry.source.type}:${entry.source.id}:${entry.path}`));
32
+ return distinct.size;
33
+ }
34
+ //# sourceMappingURL=delete-asset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-asset.js","sourceRoot":"","sources":["../../../src/lib/assets/delete-asset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAoC5D,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAqB,EACrB,SAAiB,EACjB,OAAe,EACf,UAA8B,EAAE;IAEhC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QAC7D,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAA;QAE3C,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAA;QAClE,IAAI,UAAU,GAAG,CAAC,IAAI,OAAO,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;YACpD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,CAAA;QAC3C,CAAC;QAED,yEAAyE;QACzE,8DAA8D;QAC9D,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;QACzC,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QACjD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAA;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,mBAAmB;YAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAA;QACzE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;IAC9F,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,eAAe,CAC5B,IAAqB,EACrB,SAAiB,EACjB,OAAe;IAEf,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;IACxF,MAAM,QAAQ,GAAG,IAAI,GAAG,CACtB,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAChF,CAAA;IACD,OAAO,QAAQ,CAAC,IAAI,CAAA;AACtB,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Client-side image dimension detection (EC-151). Uses `createImageBitmap`
3
+ * when available (injectable for tests); failure is never fatal — an asset
4
+ * without detectable dimensions simply stores no width/height.
5
+ */
6
+ export interface ImageDimensions {
7
+ width: number;
8
+ height: number;
9
+ }
10
+ type BitmapFactory = (blob: Blob) => Promise<{
11
+ width: number;
12
+ height: number;
13
+ close?: () => void;
14
+ }>;
15
+ export declare function detectImageDimensions(file: Blob & {
16
+ type: string;
17
+ }, createBitmap?: BitmapFactory | undefined): Promise<ImageDimensions | undefined>;
18
+ export {};
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Client-side image dimension detection (EC-151). Uses `createImageBitmap`
3
+ * when available (injectable for tests); failure is never fatal — an asset
4
+ * without detectable dimensions simply stores no width/height.
5
+ */
6
+ export async function detectImageDimensions(file, createBitmap = typeof createImageBitmap === 'function'
7
+ ? createImageBitmap
8
+ : undefined) {
9
+ if (!file.type.startsWith('image/'))
10
+ return undefined;
11
+ if (!createBitmap)
12
+ return undefined;
13
+ try {
14
+ const bitmap = await createBitmap(file);
15
+ const dimensions = bitmap.width > 0 && bitmap.height > 0
16
+ ? { width: bitmap.width, height: bitmap.height }
17
+ : undefined;
18
+ bitmap.close?.();
19
+ return dimensions;
20
+ }
21
+ catch {
22
+ // Undecodable image (corrupt bytes, unsupported format) — not an error.
23
+ return undefined;
24
+ }
25
+ }
26
+ //# sourceMappingURL=image-dimensions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-dimensions.js","sourceRoot":"","sources":["../../../src/lib/assets/image-dimensions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAA6B,EAC7B,eAA0C,OAAO,iBAAiB,KAAK,UAAU;IAC/E,CAAC,CAAC,iBAAiB;IACnB,CAAC,CAAC,SAAS;IAEb,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAA;IACrD,IAAI,CAAC,YAAY;QAAE,OAAO,SAAS,CAAA;IACnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAA;QACvC,MAAM,UAAU,GACd,MAAM,CAAC,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YACnC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;YAChD,CAAC,CAAC,SAAS,CAAA;QACf,MAAM,CAAC,KAAK,EAAE,EAAE,CAAA;QAChB,OAAO,UAAU,CAAA;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,wEAAwE;QACxE,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Asset upload, deletion, and usage logic (EC-151). Pure/injectable modules:
3
+ * the studio UI consumes these; storage is reached only through the
4
+ * `BlobStorageAdapter` boundary.
5
+ */
6
+ export * from './upload-state';
7
+ export * from './image-dimensions';
8
+ export * from './upload';
9
+ export * from './delete-asset';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Asset upload, deletion, and usage logic (EC-151). Pure/injectable modules:
3
+ * the studio UI consumes these; storage is reached only through the
4
+ * `BlobStorageAdapter` boundary.
5
+ */
6
+ export * from './upload-state';
7
+ export * from './image-dimensions';
8
+ export * from './upload';
9
+ export * from './delete-asset';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/assets/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,gBAAgB,CAAA;AAC9B,cAAc,oBAAoB,CAAA;AAClC,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Upload state machine (EC-151). Pure, deterministic transition logic for the
3
+ * studio upload flow: request upload URL → transfer bytes → confirm metadata.
4
+ * Failure at any stage is an explicit, visible state with a retry affordance —
5
+ * never a silent loss. Kept free of DOM/network so it unit-tests as plain data.
6
+ */
7
+ export type UploadStage = 'prepare' | 'transfer' | 'confirm';
8
+ export type UploadPhase = 'idle' | 'preparing' | 'uploading' | 'confirming' | 'done' | 'failed';
9
+ export interface UploadFailure {
10
+ stage: UploadStage;
11
+ message: string;
12
+ /** Whether retrying the same file can plausibly succeed (default true). */
13
+ retryable: boolean;
14
+ }
15
+ export interface UploadState {
16
+ phase: UploadPhase;
17
+ /** Byte progress in [0, 1]; only meaningful while `uploading`. */
18
+ progress: number;
19
+ /** 1-based attempt counter; increments on `retry`. */
20
+ attempt: number;
21
+ failure?: UploadFailure;
22
+ /** The created asset id once `done`. */
23
+ assetId?: string;
24
+ }
25
+ export type UploadEvent = {
26
+ type: 'start';
27
+ } | {
28
+ type: 'url-ready';
29
+ } | {
30
+ type: 'progress';
31
+ loaded: number;
32
+ total: number;
33
+ } | {
34
+ type: 'transferred';
35
+ } | {
36
+ type: 'confirmed';
37
+ assetId: string;
38
+ } | {
39
+ type: 'failed';
40
+ stage: UploadStage;
41
+ message: string;
42
+ retryable?: boolean;
43
+ } | {
44
+ type: 'retry';
45
+ } | {
46
+ type: 'reset';
47
+ };
48
+ export declare const initialUploadState: UploadState;
49
+ /**
50
+ * Pure reducer. Invalid transitions return the state unchanged (deterministic,
51
+ * never throws) so a late progress event after a failure cannot corrupt the UI.
52
+ */
53
+ export declare function uploadReducer(state: UploadState, event: UploadEvent): UploadState;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Upload state machine (EC-151). Pure, deterministic transition logic for the
3
+ * studio upload flow: request upload URL → transfer bytes → confirm metadata.
4
+ * Failure at any stage is an explicit, visible state with a retry affordance —
5
+ * never a silent loss. Kept free of DOM/network so it unit-tests as plain data.
6
+ */
7
+ export const initialUploadState = { phase: 'idle', progress: 0, attempt: 0 };
8
+ const clamp01 = (n) => (Number.isFinite(n) ? Math.min(1, Math.max(0, n)) : 0);
9
+ /**
10
+ * Pure reducer. Invalid transitions return the state unchanged (deterministic,
11
+ * never throws) so a late progress event after a failure cannot corrupt the UI.
12
+ */
13
+ export function uploadReducer(state, event) {
14
+ switch (event.type) {
15
+ case 'start':
16
+ if (state.phase !== 'idle')
17
+ return state;
18
+ return { phase: 'preparing', progress: 0, attempt: 1 };
19
+ case 'url-ready':
20
+ if (state.phase !== 'preparing')
21
+ return state;
22
+ return { ...state, phase: 'uploading', progress: 0 };
23
+ case 'progress':
24
+ if (state.phase !== 'uploading')
25
+ return state;
26
+ return { ...state, progress: clamp01(event.total > 0 ? event.loaded / event.total : 0) };
27
+ case 'transferred':
28
+ if (state.phase !== 'uploading' && state.phase !== 'preparing')
29
+ return state;
30
+ return { ...state, phase: 'confirming', progress: 1 };
31
+ case 'confirmed':
32
+ if (state.phase !== 'confirming')
33
+ return state;
34
+ return { ...state, phase: 'done', progress: 1, assetId: event.assetId };
35
+ case 'failed':
36
+ if (state.phase === 'done' || state.phase === 'idle')
37
+ return state;
38
+ return {
39
+ ...state,
40
+ phase: 'failed',
41
+ failure: {
42
+ stage: event.stage,
43
+ message: event.message,
44
+ retryable: event.retryable ?? true,
45
+ },
46
+ };
47
+ case 'retry':
48
+ if (state.phase !== 'failed' || state.failure?.retryable === false)
49
+ return state;
50
+ return { phase: 'preparing', progress: 0, attempt: state.attempt + 1 };
51
+ case 'reset':
52
+ return initialUploadState;
53
+ default: {
54
+ const never = event;
55
+ return never;
56
+ }
57
+ }
58
+ }
59
+ //# sourceMappingURL=upload-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-state.js","sourceRoot":"","sources":["../../../src/lib/assets/upload-state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkCH,MAAM,CAAC,MAAM,kBAAkB,GAAgB,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;AAEzF,MAAM,OAAO,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAE7F;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAkB,EAAE,KAAkB;IAClE,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,OAAO;YACV,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM;gBAAE,OAAO,KAAK,CAAA;YACxC,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;QACxD,KAAK,WAAW;YACd,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW;gBAAE,OAAO,KAAK,CAAA;YAC7C,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAA;QACtD,KAAK,UAAU;YACb,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW;gBAAE,OAAO,KAAK,CAAA;YAC7C,OAAO,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAC1F,KAAK,aAAa;YAChB,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW;gBAAE,OAAO,KAAK,CAAA;YAC5E,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAA;QACvD,KAAK,WAAW;YACd,IAAI,KAAK,CAAC,KAAK,KAAK,YAAY;gBAAE,OAAO,KAAK,CAAA;YAC9C,OAAO,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAA;QACzE,KAAK,QAAQ;YACX,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM;gBAAE,OAAO,KAAK,CAAA;YAClE,OAAO;gBACL,GAAG,KAAK;gBACR,KAAK,EAAE,QAAQ;gBACf,OAAO,EAAE;oBACP,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;iBACnC;aACF,CAAA;QACH,KAAK,OAAO;YACV,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,EAAE,SAAS,KAAK,KAAK;gBAAE,OAAO,KAAK,CAAA;YAChF,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,GAAG,CAAC,EAAE,CAAA;QACxE,KAAK,OAAO;YACV,OAAO,kBAAkB,CAAA;QAC3B,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,KAAK,GAAU,KAAK,CAAA;YAC1B,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,56 @@
1
+ import type { AssetRecord, AssetRepository, BlobStorageAdapter } from '@elytracms/persistence';
2
+ import type { ImageDimensions } from './image-dimensions';
3
+ import type { UploadFailure, UploadState } from './upload-state';
4
+ /**
5
+ * Upload orchestration (EC-151): request upload URL → transfer bytes →
6
+ * confirm by writing the EC-044 metadata record (dimensions, mime, serve URL).
7
+ * Storage is reached *only* through the {@link BlobStorageAdapter}; every
8
+ * effect is injectable so the whole flow unit-tests without a browser or a
9
+ * live Convex deployment.
10
+ */
11
+ /** The structural slice of a browser `File` the upload flow needs. */
12
+ export interface UploadableFile {
13
+ name: string;
14
+ type: string;
15
+ size: number;
16
+ arrayBuffer(): Promise<ArrayBuffer>;
17
+ }
18
+ /** Sends bytes to an upload URL, reporting progress; returns the assigned storage key. */
19
+ export type UploadTransport = (uploadUrl: string, file: UploadableFile, onProgress: (loaded: number, total: number) => void) => Promise<{
20
+ storageKey: string;
21
+ }>;
22
+ /**
23
+ * Default browser transport: XMLHttpRequest POST for real byte progress
24
+ * (fetch has no upload progress without streams support everywhere).
25
+ */
26
+ export declare const xhrUploadTransport: UploadTransport;
27
+ export interface UploadDeps {
28
+ blobs: BlobStorageAdapter;
29
+ assets: AssetRepository;
30
+ /** Client-direct transport; only used when `blobs.createUploadUrl` exists. */
31
+ transport?: UploadTransport;
32
+ /** Injectable dimension detection; defaults to `createImageBitmap`-based. */
33
+ detectDimensions?: (file: UploadableFile) => Promise<ImageDimensions | undefined>;
34
+ }
35
+ export interface UploadRequest {
36
+ projectId: string;
37
+ file: UploadableFile;
38
+ alt?: string;
39
+ /** Observe every state transition (drives progress UI). */
40
+ onState?: (state: UploadState) => void;
41
+ }
42
+ export type UploadResult = {
43
+ ok: true;
44
+ asset: AssetRecord;
45
+ state: UploadState;
46
+ } | {
47
+ ok: false;
48
+ failure: UploadFailure;
49
+ state: UploadState;
50
+ };
51
+ /**
52
+ * Run one upload attempt. Resolves with a discriminated result — it never
53
+ * throws, and a failed transfer leaves no metadata record behind. Pass the
54
+ * previous `state` to retry (the attempt counter carries over).
55
+ */
56
+ export declare function runUpload(deps: UploadDeps, request: UploadRequest, previous?: UploadState): Promise<UploadResult>;
@@ -0,0 +1,125 @@
1
+ import { detectImageDimensions } from './image-dimensions';
2
+ import { initialUploadState, uploadReducer } from './upload-state';
3
+ /**
4
+ * Default browser transport: XMLHttpRequest POST for real byte progress
5
+ * (fetch has no upload progress without streams support everywhere).
6
+ */
7
+ export const xhrUploadTransport = (uploadUrl, file, onProgress) => new Promise((resolve, reject) => {
8
+ const xhr = new XMLHttpRequest();
9
+ xhr.open('POST', uploadUrl);
10
+ if (file.type)
11
+ xhr.setRequestHeader('Content-Type', file.type);
12
+ xhr.upload.onprogress = (event) => {
13
+ if (event.lengthComputable)
14
+ onProgress(event.loaded, event.total);
15
+ };
16
+ xhr.onerror = () => reject(new Error('Network error while uploading bytes.'));
17
+ xhr.onabort = () => reject(new Error('Upload was aborted.'));
18
+ xhr.onload = () => {
19
+ if (xhr.status < 200 || xhr.status >= 300) {
20
+ reject(new Error(`Upload failed with HTTP ${xhr.status}.`));
21
+ return;
22
+ }
23
+ try {
24
+ const payload = JSON.parse(xhr.responseText);
25
+ if (typeof payload.storageId === 'string' && payload.storageId.length > 0) {
26
+ resolve({ storageKey: payload.storageId });
27
+ }
28
+ else {
29
+ reject(new Error('Upload response did not include a storageId.'));
30
+ }
31
+ }
32
+ catch {
33
+ reject(new Error('Upload response was not valid JSON.'));
34
+ }
35
+ };
36
+ void file.arrayBuffer().then((bytes) => xhr.send(bytes), () => reject(new Error('Could not read file bytes.')));
37
+ });
38
+ async function defaultDetectDimensions(file) {
39
+ if (typeof Blob === 'undefined' || !(file instanceof Blob))
40
+ return undefined;
41
+ return detectImageDimensions(file);
42
+ }
43
+ function failureOf(stage, error) {
44
+ return {
45
+ stage,
46
+ message: error instanceof Error ? error.message : String(error),
47
+ retryable: true,
48
+ };
49
+ }
50
+ /**
51
+ * Run one upload attempt. Resolves with a discriminated result — it never
52
+ * throws, and a failed transfer leaves no metadata record behind. Pass the
53
+ * previous `state` to retry (the attempt counter carries over).
54
+ */
55
+ export async function runUpload(deps, request, previous) {
56
+ let state = previous ?? initialUploadState;
57
+ const dispatch = (event) => {
58
+ state = uploadReducer(state, event);
59
+ request.onState?.(state);
60
+ };
61
+ dispatch(state.phase === 'failed' ? { type: 'retry' } : { type: 'start' });
62
+ const { blobs, assets } = deps;
63
+ const { projectId, file } = request;
64
+ // --- prepare + transfer ---------------------------------------------------
65
+ let storageKey;
66
+ try {
67
+ if (blobs.createUploadUrl && deps.transport) {
68
+ const uploadUrl = await blobs.createUploadUrl();
69
+ dispatch({ type: 'url-ready' });
70
+ try {
71
+ const sent = await deps.transport(uploadUrl, file, (loaded, total) => dispatch({ type: 'progress', loaded, total }));
72
+ storageKey = sent.storageKey;
73
+ }
74
+ catch (error) {
75
+ dispatch({ type: 'failed', ...failureOf('transfer', error) });
76
+ return { ok: false, failure: failureOf('transfer', error), state };
77
+ }
78
+ }
79
+ else {
80
+ // Backend without client-direct uploads: push bytes through the adapter.
81
+ dispatch({ type: 'url-ready' });
82
+ const bytes = new Uint8Array(await file.arrayBuffer());
83
+ try {
84
+ if (blobs.store) {
85
+ storageKey = await blobs.store(bytes, file.type);
86
+ }
87
+ else {
88
+ storageKey = `${projectId}/${file.name}`;
89
+ await blobs.put(storageKey, bytes, file.type);
90
+ }
91
+ }
92
+ catch (error) {
93
+ dispatch({ type: 'failed', ...failureOf('transfer', error) });
94
+ return { ok: false, failure: failureOf('transfer', error), state };
95
+ }
96
+ }
97
+ }
98
+ catch (error) {
99
+ dispatch({ type: 'failed', ...failureOf('prepare', error) });
100
+ return { ok: false, failure: failureOf('prepare', error), state };
101
+ }
102
+ dispatch({ type: 'transferred' });
103
+ // --- confirm: metadata record linked to the stored blob --------------------
104
+ try {
105
+ const detect = deps.detectDimensions ?? defaultDetectDimensions;
106
+ const dimensions = await detect(file);
107
+ const url = (await blobs.resolveUrl?.(storageKey)) ?? blobs.url(storageKey);
108
+ const asset = await assets.upsertAsset(projectId, {
109
+ filename: file.name,
110
+ contentType: file.type || 'application/octet-stream',
111
+ byteSize: file.size,
112
+ storageKey,
113
+ url,
114
+ ...(dimensions ? { width: dimensions.width, height: dimensions.height } : {}),
115
+ ...(request.alt !== undefined ? { alt: request.alt } : {}),
116
+ });
117
+ dispatch({ type: 'confirmed', assetId: asset.id });
118
+ return { ok: true, asset, state };
119
+ }
120
+ catch (error) {
121
+ dispatch({ type: 'failed', ...failureOf('confirm', error) });
122
+ return { ok: false, failure: failureOf('confirm', error), state };
123
+ }
124
+ }
125
+ //# sourceMappingURL=upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../src/lib/assets/upload.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Project-owned auth boundary (EC-150, vision AD-7). The studio talks to
3
+ * authentication ONLY through {@link AuthAdapter} — the Convex Auth
4
+ * implementation (`convex-auth-adapter.ts`) and the deterministic local
5
+ * implementation (`local-auth-adapter.ts`) both satisfy it, mirroring how
6
+ * `PersistenceAdapter` keeps Convex out of the app's type graph.
7
+ *
8
+ * Swapping providers (e.g. Convex Auth → Clerk) means writing one new
9
+ * implementation of this interface and teaching `selectAuthAdapter` to pick
10
+ * it; no UI or store code changes.
11
+ */
12
+ /** The signed-in user as the studio sees it. */
13
+ export interface AuthUser {
14
+ /** Stable user id — the key `projectMembers.userId` is matched against. */
15
+ readonly id: string;
16
+ readonly email: string;
17
+ readonly name?: string;
18
+ /**
19
+ * Global (workspace-level) capability flags forwarded onto the operations
20
+ * `Principal.roles`, e.g. `system` (internal tooling only). Per-project roles
21
+ * do NOT live here — they live in the members repository. Currently no
22
+ * browser-session flag is granted: project creation is config/CLI-owned
23
+ * (AD-11), so there is no `create-projects` capability.
24
+ */
25
+ readonly globalFlags?: readonly string[];
26
+ }
27
+ export interface AuthSession {
28
+ readonly user: AuthUser;
29
+ }
30
+ export interface SignInCredentials {
31
+ readonly email: string;
32
+ readonly password: string;
33
+ }
34
+ /** Structured sign-in outcome — invalid credentials are a state, not a throw. */
35
+ export type SignInResult = {
36
+ readonly ok: true;
37
+ readonly session: AuthSession;
38
+ } | {
39
+ readonly ok: false;
40
+ readonly reason: 'invalid-credentials' | 'account-exists' | 'unavailable';
41
+ readonly message: string;
42
+ };
43
+ export interface AuthAdapter {
44
+ /** Restore the current session, if any (page load / refresh). */
45
+ currentSession(): Promise<AuthSession | null>;
46
+ /** Password sign-in. Resolves a structured result; never throws for bad input. */
47
+ signIn(credentials: SignInCredentials): Promise<SignInResult>;
48
+ /**
49
+ * Create a password account and sign in (EC-179). One project per backend, so
50
+ * a freshly-provisioned deployment starts with no users — the first member
51
+ * registers here, then is granted a role. `account-exists` is a state, not a
52
+ * throw.
53
+ */
54
+ signUp(credentials: SignInCredentials): Promise<SignInResult>;
55
+ /** End the session (idempotent). */
56
+ signOut(): Promise<void>;
57
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Project-owned auth boundary (EC-150, vision AD-7). The studio talks to
3
+ * authentication ONLY through {@link AuthAdapter} — the Convex Auth
4
+ * implementation (`convex-auth-adapter.ts`) and the deterministic local
5
+ * implementation (`local-auth-adapter.ts`) both satisfy it, mirroring how
6
+ * `PersistenceAdapter` keeps Convex out of the app's type graph.
7
+ *
8
+ * Swapping providers (e.g. Convex Auth → Clerk) means writing one new
9
+ * implementation of this interface and teaching `selectAuthAdapter` to pick
10
+ * it; no UI or store code changes.
11
+ */
12
+ export {};
13
+ //# sourceMappingURL=auth-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-adapter.js","sourceRoot":"","sources":["../../../src/lib/auth/auth-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
@@ -0,0 +1,39 @@
1
+ import type { ConvexHttpClient } from 'convex/browser';
2
+ import type { AuthAdapter, AuthSession, SignInCredentials, SignInResult } from './auth-adapter';
3
+ import type { SessionStore } from './local-auth-adapter';
4
+ /**
5
+ * Per-deployment token key (EC-179, vision AD-8). One project per backend, so a
6
+ * session is scoped to its deployment: signing into Aurora's backend must not
7
+ * carry a JWT to Northwind's. Keying the stored token by the deployment URL
8
+ * makes each backend's session independent — switching to a project on a
9
+ * not-yet-authenticated backend reads no token and the guard asks for sign-in.
10
+ * (A future shared external IdP — WorkOS/Clerk — would issue one identity valid
11
+ * on every deployment, collapsing this back to a single session.)
12
+ */
13
+ export declare function tokenStorageKey(deploymentUrl?: string): string;
14
+ /**
15
+ * Best-effort "is there a session for this deployment?" — a synchronous token
16
+ * presence check used to label per-backend projects in the switcher/launcher
17
+ * (EC-179). It does not validate the token (an expired one still redirects to
18
+ * sign-in on entry); it just answers "has the user signed into this backend?".
19
+ */
20
+ export declare function hasStoredConvexSession(deploymentUrl: string, store?: SessionStore): boolean;
21
+ export declare class ConvexAuthAdapter implements AuthAdapter {
22
+ private readonly client;
23
+ private readonly store;
24
+ private readonly tokenKey;
25
+ constructor(client: ConvexHttpClient, store?: SessionStore,
26
+ /** Deployment URL the token is scoped to (per-backend sessions, EC-179). */
27
+ deploymentUrl?: string);
28
+ currentSession(): Promise<AuthSession | null>;
29
+ signIn(credentials: SignInCredentials): Promise<SignInResult>;
30
+ signUp(credentials: SignInCredentials): Promise<SignInResult>;
31
+ /**
32
+ * Shared password flow (EC-150/EC-179). `signIn` and `signUp` differ only by
33
+ * the Convex Auth `flow` param; both return a token + load `users:me`.
34
+ */
35
+ private authenticate;
36
+ signOut(): Promise<void>;
37
+ private toUser;
38
+ private clearToken;
39
+ }