@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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 finaldream
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # @elytracms/studio
2
+
3
+ Coming soon.
@@ -0,0 +1,107 @@
1
+ import { v } from 'convex/values'
2
+ import type { GenericId } from 'convex/values'
3
+ import { mutation, query } from './functions'
4
+ import { requireRole, requireUserId } from './guard'
5
+
6
+ /**
7
+ * Asset metadata persistence (EC-044) + byte storage (EC-151). Bytes live in
8
+ * Convex file storage; `storageKey` on a metadata record is the Convex storage
9
+ * id. These functions are reachable only through the app's
10
+ * `ConvexBlobStorage` / `ConvexAssetRepository` adapters — never from UI code.
11
+ */
12
+
13
+ /** Convex storage ids arrive as plain strings over the wire; rebrand for the typed API. */
14
+ const asStorageId = (storageKey: string) => storageKey as GenericId<'_storage'>
15
+
16
+ export const upsert = mutation({
17
+ args: {
18
+ assetId: v.string(),
19
+ filename: v.string(),
20
+ contentType: v.string(),
21
+ byteSize: v.number(),
22
+ width: v.optional(v.number()),
23
+ height: v.optional(v.number()),
24
+ alt: v.optional(v.string()),
25
+ title: v.optional(v.string()),
26
+ storageKey: v.string(),
27
+ url: v.optional(v.string()),
28
+ focalPoint: v.optional(v.object({ x: v.number(), y: v.number() })),
29
+ createdAt: v.string(),
30
+ updatedAt: v.string(),
31
+ },
32
+ handler: async (ctx, args) => {
33
+ await requireRole(ctx, 'editor') // EC-150
34
+ const existing = await ctx.db
35
+ .query('assets')
36
+ .withIndex('by_asset', (q) => q.eq('assetId', args.assetId))
37
+ .first()
38
+ if (existing) {
39
+ await ctx.db.patch(existing._id, { ...args, createdAt: existing.createdAt })
40
+ return ctx.db.get(existing._id)
41
+ }
42
+ const id = await ctx.db.insert('assets', args)
43
+ return ctx.db.get(id)
44
+ },
45
+ })
46
+
47
+ export const get = query({
48
+ args: { assetId: v.string() },
49
+ handler: async (ctx, args) => {
50
+ await requireRole(ctx, 'viewer') // EC-150
51
+ return ctx.db
52
+ .query('assets')
53
+ .withIndex('by_asset', (q) => q.eq('assetId', args.assetId))
54
+ .first()
55
+ },
56
+ })
57
+
58
+ export const list = query({
59
+ args: {},
60
+ handler: async (ctx) => {
61
+ await requireRole(ctx, 'viewer') // EC-150
62
+ return ctx.db.query('assets').withIndex('by_asset').collect()
63
+ },
64
+ })
65
+
66
+ export const remove = mutation({
67
+ args: { assetId: v.string() },
68
+ handler: async (ctx, args) => {
69
+ await requireRole(ctx, 'editor') // EC-150
70
+ const existing = await ctx.db
71
+ .query('assets')
72
+ .withIndex('by_asset', (q) => q.eq('assetId', args.assetId))
73
+ .first()
74
+ if (existing) await ctx.db.delete(existing._id)
75
+ },
76
+ })
77
+
78
+ // --- Byte storage (EC-151) — Convex file storage behind the blob adapter ----
79
+
80
+ /** Mint a short-lived URL the studio POSTs file bytes to (Convex upload flow). */
81
+ export const generateUploadUrl = mutation({
82
+ args: {},
83
+ handler: async (ctx) => {
84
+ // EC-150: any authenticated user may mint an upload URL; the metadata write
85
+ // (`assets:upsert`) is what enforces the deployment role.
86
+ await requireUserId(ctx)
87
+ return ctx.storage.generateUploadUrl()
88
+ },
89
+ })
90
+
91
+ /** Resolve the serve URL for a stored blob; `null` when the blob is gone. */
92
+ export const getServeUrl = query({
93
+ args: { storageKey: v.string() },
94
+ handler: async (ctx, { storageKey }) => {
95
+ await requireUserId(ctx) // EC-150: storage keys are unguessable; auth is the gate.
96
+ return ctx.storage.getUrl(asStorageId(storageKey))
97
+ },
98
+ })
99
+
100
+ /** Delete stored bytes. Metadata removal is a separate `assets:remove` call. */
101
+ export const deleteBlob = mutation({
102
+ args: { storageKey: v.string() },
103
+ handler: async (ctx, { storageKey }) => {
104
+ await requireUserId(ctx) // EC-150
105
+ await ctx.storage.delete(asStorageId(storageKey))
106
+ },
107
+ })
@@ -0,0 +1,15 @@
1
+ /**
2
+ * OIDC provider configuration for Convex Auth (EC-150): the Convex deployment itself
3
+ * issues the JWTs (`CONVEX_SITE_URL` is set automatically on every deployment), so no
4
+ * third-party identity provider is involved. Generic for every deployment — the
5
+ * consumer's `convex/auth.config.ts` is a one-line re-export shim (EC-252). See
6
+ * https://labs.convex.dev/auth/setup.
7
+ */
8
+ export default {
9
+ providers: [
10
+ {
11
+ domain: process.env.CONVEX_SITE_URL,
12
+ applicationID: 'convex',
13
+ },
14
+ ],
15
+ }
package/convex/auth.ts ADDED
@@ -0,0 +1,50 @@
1
+ import { convexAuth } from '@convex-dev/auth/server'
2
+ import { Password } from '@convex-dev/auth/providers/Password'
3
+
4
+ /** The provider list `convexAuth` accepts, derived from its own signature. */
5
+ type ConvexAuthProviders = Parameters<typeof convexAuth>[0]['providers']
6
+
7
+ /**
8
+ * EC-252 — the studio's Convex Auth (EC-150) as a **default + override seam**. Only the
9
+ * PROVIDER choice is legitimately consumer-specific; the first-principal admin bootstrap
10
+ * callback is engine logic and stays here, so consumers stop copying it. The consumer's
11
+ * `convex/auth.ts` is a one-liner that picks up the default:
12
+ *
13
+ * ```ts
14
+ * export const { auth, signIn, signOut, store, isAuthenticated } = defineStudioAuth()
15
+ * ```
16
+ *
17
+ * or composes its own providers (OAuth, etc.) while keeping the engine bootstrap:
18
+ *
19
+ * ```ts
20
+ * export const { auth, ... } = defineStudioAuth({ providers: [Password, GitHub] })
21
+ * ```
22
+ *
23
+ * Decision record (EC-150): Convex Auth over Clerk — self-contained on the Convex stack,
24
+ * sessions live in our own tables, and the studio only talks to it through the
25
+ * project-owned `AuthAdapter`, so swapping providers later is one factory call, not UI.
26
+ */
27
+ export function defineStudioAuth(options?: { providers?: ConvexAuthProviders }) {
28
+ return convexAuth({
29
+ providers: options?.providers ?? [Password],
30
+ callbacks: {
31
+ /**
32
+ * First-principal admin bootstrap (EC-182 follow-up). On a freshly-provisioned
33
+ * deployment the `members` table is empty, so no one can pass the role guard and
34
+ * the studio is unreachable. Rather than require a manual seed step, the **first
35
+ * user to authenticate while the deployment has no members** is auto-granted
36
+ * `admin`. Once any membership exists this is a no-op (one indexed read) — further
37
+ * roles are assigned by an admin via `members:set`. Single-tenant: one `members`
38
+ * table per deployment. `beforeSessionCreation` fires on every sign-in (not just
39
+ * account creation), so it also recovers a member-less account and never lets a
40
+ * deployment lock itself out.
41
+ */
42
+ async beforeSessionCreation(ctx, { userId }) {
43
+ const existing = await ctx.db.query('members').first()
44
+ if (existing) return
45
+ const now = new Date().toISOString()
46
+ await ctx.db.insert('members', { userId, role: 'admin', createdAt: now, updatedAt: now })
47
+ },
48
+ },
49
+ })
50
+ }
@@ -0,0 +1,63 @@
1
+ import { v } from 'convex/values'
2
+ import { mutation, query } from './functions'
3
+ import { requireRole } from './guard'
4
+
5
+ /**
6
+ * CLI token persistence (EC-150). Only SHA-256 hashes are stored — hashing and
7
+ * plaintext generation happen in `@elytracms/operations` (`tokens.issue`), and
8
+ * verification goes through `verifyCliToken`, which calls `byHash` below via
9
+ * the `ConvexCliTokenRepository`. All user-facing access is admin-only.
10
+ */
11
+
12
+ export const create = mutation({
13
+ args: {
14
+ tokenId: v.string(),
15
+ label: v.string(),
16
+ tokenHash: v.string(),
17
+ createdAt: v.string(),
18
+ },
19
+ handler: async (ctx, args) => {
20
+ await requireRole(ctx, 'admin')
21
+ const id = await ctx.db.insert('cliTokens', args)
22
+ return ctx.db.get(id)
23
+ },
24
+ })
25
+
26
+ export const list = query({
27
+ args: {},
28
+ handler: async (ctx) => {
29
+ await requireRole(ctx, 'admin')
30
+ const rows = await ctx.db.query('cliTokens').collect()
31
+ return rows.sort((a, b) => (a.tokenId < b.tokenId ? -1 : a.tokenId > b.tokenId ? 1 : 0))
32
+ },
33
+ })
34
+
35
+ export const revoke = mutation({
36
+ args: { tokenId: v.string(), revokedAt: v.string() },
37
+ handler: async (ctx, { tokenId, revokedAt }) => {
38
+ await requireRole(ctx, 'admin')
39
+ const existing = await ctx.db
40
+ .query('cliTokens')
41
+ .withIndex('by_token', (q) => q.eq('tokenId', tokenId))
42
+ .first()
43
+ if (!existing) throw new Error(`not-found: cli-token "${tokenId}"`)
44
+ if (!existing.revokedAt) await ctx.db.patch(existing._id, { revokedAt })
45
+ return ctx.db.get(existing._id)
46
+ },
47
+ })
48
+
49
+ /**
50
+ * Hash lookup for Bearer-token verification. Deliberately *unauthenticated*:
51
+ * the future registry-sync HTTP endpoint (EC-156) calls it with the hash of a
52
+ * presented token, and knowing a hash's preimage IS the credential. No token
53
+ * material beyond what the caller already holds is revealed.
54
+ */
55
+ export const byHash = query({
56
+ args: { tokenHash: v.string() },
57
+ handler: async (ctx, { tokenHash }) => {
58
+ return ctx.db
59
+ .query('cliTokens')
60
+ .withIndex('by_hash', (q) => q.eq('tokenHash', tokenHash))
61
+ .first()
62
+ },
63
+ })
package/convex/cms.ts ADDED
@@ -0,0 +1,174 @@
1
+ import { v } from 'convex/values'
2
+ import { mutation, query } from './functions'
3
+ import { requireRole } from './guard'
4
+
5
+ /**
6
+ * CMS document persistence (EC-043). The backend stores **documents only**
7
+ * (AD-11, EC-183): CMS collection schemas are config-owned — they live in
8
+ * `elytra.config.ts`, read by the studio + host — so there is no `cmsSchemas`
9
+ * table and no schema read/write function here. Collection-membership
10
+ * validation lives in `@elytracms/cms-core` `validateDocument` (the studio runs it
11
+ * pre-dispatch); this layer is a pure document store.
12
+ */
13
+
14
+ export const upsertDocument = mutation({
15
+ args: {
16
+ collection: v.string(),
17
+ docId: v.string(),
18
+ document: v.any(),
19
+ createdAt: v.string(),
20
+ updatedAt: v.string(),
21
+ },
22
+ handler: async (ctx, args) => {
23
+ await requireRole(ctx, 'editor') // EC-150
24
+ const existing = await ctx.db
25
+ .query('cmsDocuments')
26
+ .withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
27
+ .first()
28
+ if (existing) {
29
+ // EC-153 parity: updates preserve `createdAt`, exactly like in-memory.
30
+ await ctx.db.patch(existing._id, { ...args, createdAt: existing.createdAt })
31
+ return ctx.db.get(existing._id)
32
+ }
33
+ const id = await ctx.db.insert('cmsDocuments', args)
34
+ return ctx.db.get(id)
35
+ },
36
+ })
37
+
38
+ export const getDocument = query({
39
+ args: { collection: v.string(), docId: v.string() },
40
+ handler: async (ctx, args) => {
41
+ await requireRole(ctx, 'viewer') // EC-150
42
+ return ctx.db
43
+ .query('cmsDocuments')
44
+ .withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
45
+ .first()
46
+ },
47
+ })
48
+
49
+ export const listDocuments = query({
50
+ args: { collection: v.optional(v.string()) },
51
+ handler: async (ctx, args) => {
52
+ await requireRole(ctx, 'viewer') // EC-150
53
+ if (args.collection) {
54
+ const collection = args.collection
55
+ return ctx.db
56
+ .query('cmsDocuments')
57
+ .withIndex('by_collection', (q) => q.eq('collection', collection))
58
+ .collect()
59
+ }
60
+ return ctx.db.query('cmsDocuments').collect()
61
+ },
62
+ })
63
+
64
+ export const deleteDocument = mutation({
65
+ args: { collection: v.string(), docId: v.string() },
66
+ handler: async (ctx, args) => {
67
+ await requireRole(ctx, 'editor') // EC-150
68
+ const existing = await ctx.db
69
+ .query('cmsDocuments')
70
+ .withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
71
+ .first()
72
+ if (existing) await ctx.db.delete(existing._id)
73
+ // Cascade the version history (EC-224) — no orphaned snapshots survive a delete.
74
+ const versions = await ctx.db
75
+ .query('documentVersions')
76
+ .withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
77
+ .collect()
78
+ for (const row of versions) await ctx.db.delete(row._id)
79
+ },
80
+ })
81
+
82
+ /**
83
+ * Document version history (EC-224) — the document analogue of `graphs:*`.
84
+ * Append-only snapshots in `documentVersions`; the live one is pinned by
85
+ * `cmsDocuments.publishedVersion`. Version numbers are 1-based, monotonic per
86
+ * document, computed atomically inside the mutation.
87
+ */
88
+ export const saveDocumentVersion = mutation({
89
+ args: {
90
+ collection: v.string(),
91
+ docId: v.string(),
92
+ snapshot: v.any(),
93
+ label: v.optional(v.string()),
94
+ createdAt: v.string(),
95
+ },
96
+ handler: async (ctx, args) => {
97
+ await requireRole(ctx, 'editor') // EC-150
98
+ const existing = await ctx.db
99
+ .query('documentVersions')
100
+ .withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
101
+ .collect()
102
+ const version = existing.reduce((max, r) => Math.max(max, r.version), 0) + 1
103
+ const id = await ctx.db.insert('documentVersions', { ...args, version })
104
+ return ctx.db.get(id)
105
+ },
106
+ })
107
+
108
+ export const listDocumentVersions = query({
109
+ args: { collection: v.string(), docId: v.string() },
110
+ handler: async (ctx, args) => {
111
+ await requireRole(ctx, 'viewer') // EC-150
112
+ const rows = await ctx.db
113
+ .query('documentVersions')
114
+ .withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
115
+ .collect()
116
+ // Newest first (parity with the in-memory `listDocumentVersions`).
117
+ return rows.sort((a, b) => b.version - a.version)
118
+ },
119
+ })
120
+
121
+ export const getDocumentVersion = query({
122
+ args: { collection: v.string(), docId: v.string(), version: v.number() },
123
+ handler: async (ctx, args) => {
124
+ await requireRole(ctx, 'viewer') // EC-150
125
+ const rows = await ctx.db
126
+ .query('documentVersions')
127
+ .withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
128
+ .collect()
129
+ return rows.find((r) => r.version === args.version) ?? null
130
+ },
131
+ })
132
+
133
+ /** Every version across all documents (EC-224) — backs the delivery feeders. */
134
+ export const listAllDocumentVersions = query({
135
+ args: {},
136
+ handler: async (ctx) => {
137
+ await requireRole(ctx, 'viewer') // EC-150
138
+ return ctx.db.query('documentVersions').collect()
139
+ },
140
+ })
141
+
142
+ export const publishDocumentVersion = mutation({
143
+ args: {
144
+ collection: v.string(),
145
+ docId: v.string(),
146
+ version: v.number(),
147
+ updatedAt: v.string(),
148
+ },
149
+ handler: async (ctx, args) => {
150
+ await requireRole(ctx, 'editor') // EC-150
151
+ const doc = await ctx.db
152
+ .query('cmsDocuments')
153
+ .withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
154
+ .first()
155
+ if (!doc) return null
156
+ await ctx.db.patch(doc._id, { publishedVersion: args.version, updatedAt: args.updatedAt })
157
+ return ctx.db.get(doc._id)
158
+ },
159
+ })
160
+
161
+ export const unpublishDocument = mutation({
162
+ args: { collection: v.string(), docId: v.string(), updatedAt: v.string() },
163
+ handler: async (ctx, args) => {
164
+ await requireRole(ctx, 'editor') // EC-150
165
+ const doc = await ctx.db
166
+ .query('cmsDocuments')
167
+ .withIndex('by_doc', (q) => q.eq('collection', args.collection).eq('docId', args.docId))
168
+ .first()
169
+ if (!doc) return null
170
+ // Convex patch removes a field set to `undefined` — clears the live pin.
171
+ await ctx.db.patch(doc._id, { publishedVersion: undefined, updatedAt: args.updatedAt })
172
+ return ctx.db.get(doc._id)
173
+ },
174
+ })