@elytracms/studio 0.0.86 → 0.0.88

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 (248) hide show
  1. package/convex/asset-revalidate.test.ts +186 -0
  2. package/convex/assets.ts +53 -19
  3. package/convex/cms.ts +22 -0
  4. package/convex/delivery.ts +33 -116
  5. package/convex/functions.ts +3 -3
  6. package/convex/rail-write-parity.test.ts +180 -0
  7. package/convex/redirects.ts +33 -11
  8. package/convex/revalidate.ts +7 -5
  9. package/convex/triggers.ts +53 -3
  10. package/dist/components/ai/ai-chat-panel.js +8 -1
  11. package/dist/components/ai/ai-chat-panel.js.map +1 -1
  12. package/dist/components/app-views/default-modules.d.ts +20 -20
  13. package/dist/components/app-views/default-modules.js +27 -48
  14. package/dist/components/app-views/default-modules.js.map +1 -1
  15. package/dist/components/app-views/studio-config.d.ts +5 -6
  16. package/dist/components/app-views/studio-config.js.map +1 -1
  17. package/dist/components/assets/asset-metadata.d.ts +28 -19
  18. package/dist/components/assets/asset-metadata.js +24 -31
  19. package/dist/components/assets/asset-metadata.js.map +1 -1
  20. package/dist/components/assets/asset-selection.d.ts +24 -5
  21. package/dist/components/assets/asset-selection.js +39 -9
  22. package/dist/components/assets/asset-selection.js.map +1 -1
  23. package/dist/components/assets/assets-collection-view-source.d.ts +17 -14
  24. package/dist/components/assets/assets-collection-view-source.js +25 -31
  25. package/dist/components/assets/assets-collection-view-source.js.map +1 -1
  26. package/dist/components/assets/assets-store.d.ts +11 -1
  27. package/dist/components/assets/assets-store.js +10 -0
  28. package/dist/components/assets/assets-store.js.map +1 -1
  29. package/dist/components/assets/focal-point.d.ts +0 -7
  30. package/dist/components/assets/focal-point.js +0 -10
  31. package/dist/components/assets/focal-point.js.map +1 -1
  32. package/dist/components/builder/blocks-panel.js +3 -3
  33. package/dist/components/builder/blocks-panel.js.map +1 -1
  34. package/dist/components/builder/builder-store.d.ts +25 -1
  35. package/dist/components/builder/builder-store.js +3 -2
  36. package/dist/components/builder/builder-store.js.map +1 -1
  37. package/dist/components/builder/canvas-chrome-css.js +0 -17
  38. package/dist/components/builder/canvas-chrome-css.js.map +1 -1
  39. package/dist/components/builder/canvas-chrome.d.ts +10 -12
  40. package/dist/components/builder/canvas-chrome.js +12 -13
  41. package/dist/components/builder/canvas-chrome.js.map +1 -1
  42. package/dist/components/builder/canvas-dnd.d.ts +8 -0
  43. package/dist/components/builder/canvas-dnd.js +5 -3
  44. package/dist/components/builder/canvas-dnd.js.map +1 -1
  45. package/dist/components/builder/canvas-render-context.d.ts +23 -24
  46. package/dist/components/builder/canvas-render-context.js +35 -60
  47. package/dist/components/builder/canvas-render-context.js.map +1 -1
  48. package/dist/components/builder/canvas.js +5 -11
  49. package/dist/components/builder/canvas.js.map +1 -1
  50. package/dist/components/builder/clipboard-actions.d.ts +14 -6
  51. package/dist/components/builder/clipboard-actions.js +29 -20
  52. package/dist/components/builder/clipboard-actions.js.map +1 -1
  53. package/dist/components/builder/composition-field-editor.d.ts +19 -26
  54. package/dist/components/builder/composition-field-editor.js +30 -52
  55. package/dist/components/builder/composition-field-editor.js.map +1 -1
  56. package/dist/components/builder/insert-context.d.ts +3 -1
  57. package/dist/components/builder/insert-context.js +15 -10
  58. package/dist/components/builder/insert-context.js.map +1 -1
  59. package/dist/components/builder/page-tree.d.ts +29 -0
  60. package/dist/components/builder/page-tree.js +56 -58
  61. package/dist/components/builder/page-tree.js.map +1 -1
  62. package/dist/components/builder/reuse.js +5 -2
  63. package/dist/components/builder/reuse.js.map +1 -1
  64. package/dist/components/cms/asset-field.d.ts +2 -1
  65. package/dist/components/cms/asset-field.js +39 -83
  66. package/dist/components/cms/asset-field.js.map +1 -1
  67. package/dist/components/cms/asset-picker-core.d.ts +77 -40
  68. package/dist/components/cms/asset-picker-core.js +73 -46
  69. package/dist/components/cms/asset-picker-core.js.map +1 -1
  70. package/dist/components/cms/asset-picker.d.ts +48 -19
  71. package/dist/components/cms/asset-picker.js +69 -30
  72. package/dist/components/cms/asset-picker.js.map +1 -1
  73. package/dist/components/cms/cell-edit.d.ts +3 -1
  74. package/dist/components/cms/cell-edit.js +2 -2
  75. package/dist/components/cms/cell-edit.js.map +1 -1
  76. package/dist/components/cms/cms-composition-validators.js +11 -2
  77. package/dist/components/cms/cms-composition-validators.js.map +1 -1
  78. package/dist/components/cms/cms-store.js +15 -23
  79. package/dist/components/cms/cms-store.js.map +1 -1
  80. package/dist/components/cms/editable-cell.js +3 -3
  81. package/dist/components/cms/editable-cell.js.map +1 -1
  82. package/dist/components/cms/gate-validation.d.ts +27 -2
  83. package/dist/components/cms/gate-validation.js +19 -1
  84. package/dist/components/cms/gate-validation.js.map +1 -1
  85. package/dist/components/cms/rich-text/editor.js +2 -2
  86. package/dist/components/cms/rich-text/editor.js.map +1 -1
  87. package/dist/components/cms/rich-text/insert.d.ts +7 -0
  88. package/dist/components/cms/rich-text/insert.js +7 -0
  89. package/dist/components/cms/rich-text/insert.js.map +1 -1
  90. package/dist/components/cms/use-document-versions.js +1 -0
  91. package/dist/components/cms/use-document-versions.js.map +1 -1
  92. package/dist/components/cms/versions-model.d.ts +0 -12
  93. package/dist/components/cms/versions-model.js +3 -15
  94. package/dist/components/cms/versions-model.js.map +1 -1
  95. package/dist/components/components/component-detail.js +1 -1
  96. package/dist/components/components/component-detail.js.map +1 -1
  97. package/dist/components/components/transfer-dialog.js +2 -4
  98. package/dist/components/components/transfer-dialog.js.map +1 -1
  99. package/dist/components/components/transfer.d.ts +13 -10
  100. package/dist/components/components/transfer.js +21 -19
  101. package/dist/components/components/transfer.js.map +1 -1
  102. package/dist/components/nav-issues.d.ts +23 -3
  103. package/dist/components/nav-issues.js +38 -2
  104. package/dist/components/nav-issues.js.map +1 -1
  105. package/dist/components/project-session.d.ts +9 -0
  106. package/dist/components/project-session.js +1 -1
  107. package/dist/components/project-session.js.map +1 -1
  108. package/dist/components/redirects/redirects-collection-view-source.d.ts +17 -2
  109. package/dist/components/redirects/redirects-collection-view-source.js +20 -6
  110. package/dist/components/redirects/redirects-collection-view-source.js.map +1 -1
  111. package/dist/components/section-nav.js +26 -2
  112. package/dist/components/section-nav.js.map +1 -1
  113. package/dist/components/section-surface.js +3 -2
  114. package/dist/components/section-surface.js.map +1 -1
  115. package/dist/components/settings-form.js +1 -2
  116. package/dist/components/settings-form.js.map +1 -1
  117. package/dist/components/studio-context.js +1 -18
  118. package/dist/components/studio-context.js.map +1 -1
  119. package/dist/components/studio-project-screen.js +3 -5
  120. package/dist/components/studio-project-screen.js.map +1 -1
  121. package/dist/lib/ai/apply-content.js +73 -29
  122. package/dist/lib/ai/apply-content.js.map +1 -1
  123. package/dist/lib/ai/constraints.d.ts +35 -0
  124. package/dist/lib/ai/constraints.js +104 -4
  125. package/dist/lib/ai/constraints.js.map +1 -1
  126. package/dist/lib/ai/route.js +4 -1
  127. package/dist/lib/ai/route.js.map +1 -1
  128. package/dist/lib/ai/shape.d.ts +3 -2
  129. package/dist/lib/ai/shape.js +16 -24
  130. package/dist/lib/ai/shape.js.map +1 -1
  131. package/dist/lib/ai/tools.d.ts +10 -4
  132. package/dist/lib/ai/tools.js +12 -4
  133. package/dist/lib/ai/tools.js.map +1 -1
  134. package/dist/lib/ai/types.d.ts +8 -0
  135. package/dist/lib/ai/types.js.map +1 -1
  136. package/dist/lib/ai/update-fields.js +33 -12
  137. package/dist/lib/ai/update-fields.js.map +1 -1
  138. package/dist/lib/assets/asset-placements.d.ts +35 -0
  139. package/dist/lib/assets/asset-placements.js +74 -0
  140. package/dist/lib/assets/asset-placements.js.map +1 -0
  141. package/dist/lib/assets/backfill-thumbs.d.ts +9 -8
  142. package/dist/lib/assets/backfill-thumbs.js +13 -25
  143. package/dist/lib/assets/backfill-thumbs.js.map +1 -1
  144. package/dist/lib/clipboard/paste-issues.d.ts +17 -15
  145. package/dist/lib/clipboard/paste-issues.js +8 -45
  146. package/dist/lib/clipboard/paste-issues.js.map +1 -1
  147. package/dist/lib/clipboard/paste-target.d.ts +25 -1
  148. package/dist/lib/clipboard/paste-target.js +13 -6
  149. package/dist/lib/clipboard/paste-target.js.map +1 -1
  150. package/dist/lib/cms/published-documents.js +1 -0
  151. package/dist/lib/cms/published-documents.js.map +1 -1
  152. package/dist/lib/cms-views/view-model.d.ts +3 -3
  153. package/dist/lib/data/collection-content.d.ts +22 -1
  154. package/dist/lib/data/collection-content.js +15 -0
  155. package/dist/lib/data/collection-content.js.map +1 -1
  156. package/dist/lib/data/index.d.ts +0 -3
  157. package/dist/lib/data/index.js +4 -6
  158. package/dist/lib/data/index.js.map +1 -1
  159. package/dist/lib/dnd/drop-rules.d.ts +45 -2
  160. package/dist/lib/dnd/drop-rules.js +64 -9
  161. package/dist/lib/dnd/drop-rules.js.map +1 -1
  162. package/dist/lib/engine-version.d.ts +3 -3
  163. package/dist/lib/engine-version.js +3 -3
  164. package/dist/lib/engine-version.js.map +1 -1
  165. package/dist/lib/i18n/messages.de.js +9 -56
  166. package/dist/lib/i18n/messages.de.js.map +1 -1
  167. package/dist/lib/i18n/messages.en.d.ts +8 -53
  168. package/dist/lib/i18n/messages.en.js +14 -57
  169. package/dist/lib/i18n/messages.en.js.map +1 -1
  170. package/dist/lib/locale/fallback.js +8 -2
  171. package/dist/lib/locale/fallback.js.map +1 -1
  172. package/dist/lib/locale/index.d.ts +0 -1
  173. package/dist/lib/locale/index.js +0 -1
  174. package/dist/lib/locale/index.js.map +1 -1
  175. package/dist/lib/locale/locale-store.d.ts +10 -3
  176. package/dist/lib/locale/locale-store.js +12 -5
  177. package/dist/lib/locale/locale-store.js.map +1 -1
  178. package/dist/lib/operations/session-hydration.d.ts +24 -22
  179. package/dist/lib/operations/session-hydration.js +15 -53
  180. package/dist/lib/operations/session-hydration.js.map +1 -1
  181. package/dist/lib/persistence/convex-adapter.js +63 -75
  182. package/dist/lib/persistence/convex-adapter.js.map +1 -1
  183. package/dist/lib/persona/labels.d.ts +0 -2
  184. package/dist/lib/persona/labels.js +1 -7
  185. package/dist/lib/persona/labels.js.map +1 -1
  186. package/dist/lib/registry/index.d.ts +4 -2
  187. package/dist/lib/registry/index.js +26 -21
  188. package/dist/lib/registry/index.js.map +1 -1
  189. package/dist/lib/registry/project-components.js +0 -3
  190. package/dist/lib/registry/project-components.js.map +1 -1
  191. package/dist/lib/routes/route-issues.js +4 -5
  192. package/dist/lib/routes/route-issues.js.map +1 -1
  193. package/dist/lib/theme.js +3 -2
  194. package/dist/lib/theme.js.map +1 -1
  195. package/dist/lib/webhooks/tags.js +11 -14
  196. package/dist/lib/webhooks/tags.js.map +1 -1
  197. package/dist/lib/workspace/config-issues.d.ts +6 -0
  198. package/dist/lib/workspace/config-issues.js +8 -4
  199. package/dist/lib/workspace/config-issues.js.map +1 -1
  200. package/dist/lib/workspace/index.d.ts +2 -2
  201. package/dist/lib/workspace/index.js +2 -2
  202. package/dist/lib/workspace/index.js.map +1 -1
  203. package/dist/previews/enumerate.d.ts +27 -9
  204. package/dist/previews/enumerate.js +27 -6
  205. package/dist/previews/enumerate.js.map +1 -1
  206. package/dist/previews/manifest-format.d.ts +9 -0
  207. package/dist/previews/manifest-format.js.map +1 -1
  208. package/dist/router/match.d.ts +0 -2
  209. package/dist/router/match.js +0 -2
  210. package/dist/router/match.js.map +1 -1
  211. package/dist/router/navigate-once.d.ts +19 -4
  212. package/dist/router/navigate-once.js +22 -5
  213. package/dist/router/navigate-once.js.map +1 -1
  214. package/dist/ui/badge.d.ts +1 -1
  215. package/package.json +3 -3
  216. package/src/styles/studio.css +5 -4
  217. package/src/styles/tokens.css +72 -55
  218. package/convex/content.ts +0 -291
  219. package/dist/components/collab/collab-context.d.ts +0 -27
  220. package/dist/components/collab/collab-context.js +0 -39
  221. package/dist/components/collab/collab-context.js.map +0 -1
  222. package/dist/components/collab/collab-seed.d.ts +0 -15
  223. package/dist/components/collab/collab-seed.js +0 -20
  224. package/dist/components/collab/collab-seed.js.map +0 -1
  225. package/dist/components/extensions/extensions-view.d.ts +0 -7
  226. package/dist/components/extensions/extensions-view.js +0 -127
  227. package/dist/components/extensions/extensions-view.js.map +0 -1
  228. package/dist/lib/bindings/section-bindings.d.ts +0 -24
  229. package/dist/lib/bindings/section-bindings.js +0 -9
  230. package/dist/lib/bindings/section-bindings.js.map +0 -1
  231. package/dist/lib/data/data-store.d.ts +0 -98
  232. package/dist/lib/data/data-store.js +0 -211
  233. package/dist/lib/data/data-store.js.map +0 -1
  234. package/dist/lib/data/providers.d.ts +0 -143
  235. package/dist/lib/data/providers.js +0 -255
  236. package/dist/lib/data/providers.js.map +0 -1
  237. package/dist/lib/data/sample-capture.d.ts +0 -30
  238. package/dist/lib/data/sample-capture.js +0 -70
  239. package/dist/lib/data/sample-capture.js.map +0 -1
  240. package/dist/lib/data/sources-store.d.ts +0 -42
  241. package/dist/lib/data/sources-store.js +0 -120
  242. package/dist/lib/data/sources-store.js.map +0 -1
  243. package/dist/lib/locale/binding-fallback.d.ts +0 -35
  244. package/dist/lib/locale/binding-fallback.js +0 -73
  245. package/dist/lib/locale/binding-fallback.js.map +0 -1
  246. package/dist/lib/starters/kit-session.d.ts +0 -5
  247. package/dist/lib/starters/kit-session.js +0 -17
  248. package/dist/lib/starters/kit-session.js.map +0 -1
@@ -1,120 +0,0 @@
1
- import { dataSourceSchema } from '@elytracms/core/data-binding';
2
- /**
3
- * Data-source persistence for the Builder's data layer (LIVE-mode gap fix).
4
- *
5
- * EC-166/EC-167 made the builder provision per-section (`cms.section.<nodeId>`)
6
- * and per-template (`cms.template.<pageId>`) CMS sources, but only as session
7
- * state — the live delivery chain (`convex/delivery.ts` →
8
- * `apps/example-site/lib/live-content.ts`) had nothing to carry. Following the
9
- * EC-170 routing-store / EC-169 views-store pattern, sources persist as
10
- * documents in ONE system collection, one document per source, and every
11
- * mutation goes through the *existing* `@elytracms/core/operations` commands
12
- * (`schema.upsertCollection`, `documents.upsert`, `documents.delete`) — no new
13
- * operations surface, no direct repository access.
14
- *
15
- * The record round-trips the FULL canonical `DataSource` shape (including the
16
- * captured `sample` + inferred `schema` envelope and the cms config's `sort`):
17
- * `@elytracms/core/data-binding`'s `dataSourceSchema` is the source of truth, applied
18
- * on both write and read, so a malformed stored record is dropped on load —
19
- * never a crash, never a half-parsed source.
20
- */
21
- export const DATA_SOURCES_COLLECTION = 'cms-data-sources';
22
- /** System collection holding one document per persisted {@link DataSource}. */
23
- export const dataSourcesCollectionDef = {
24
- id: DATA_SOURCES_COLLECTION,
25
- kind: 'document',
26
- titleField: 'label',
27
- form: {
28
- label: 'Data sources',
29
- labelSingular: 'Data source',
30
- description: "System collection managed by the Builder's data layer.",
31
- },
32
- fields: [
33
- { name: 'label', type: 'text', validation: { required: true } },
34
- /** The source kind (`rest` | `cms` | `convex`), denormalized for table views. */
35
- { name: 'kind', type: 'text', validation: { required: true } },
36
- /** The FULL canonical DataSource, JSON-serialized (validated by Zod on read). */
37
- { name: 'config', type: 'text', validation: { required: true } },
38
- ],
39
- };
40
- // ---- Source ⇄ document mapping ----
41
- export function sourceToDocument(source) {
42
- const parsed = dataSourceSchema.parse(source);
43
- return {
44
- collection: DATA_SOURCES_COLLECTION,
45
- id: parsed.id,
46
- values: {
47
- label: parsed.label,
48
- kind: parsed.kind,
49
- config: JSON.stringify(parsed),
50
- },
51
- };
52
- }
53
- export function documentToSource(document) {
54
- const raw = document.values.config;
55
- let value;
56
- try {
57
- value = typeof raw === 'string' ? JSON.parse(raw) : undefined;
58
- }
59
- catch {
60
- return undefined;
61
- }
62
- const parsed = dataSourceSchema.safeParse(value);
63
- if (!parsed.success)
64
- return undefined;
65
- // The document id is the source id — a record whose payload disagrees with
66
- // its own key is malformed and never loads.
67
- return parsed.data.id === document.id ? parsed.data : undefined;
68
- }
69
- // ---- Reads & writes through @elytracms/operations ----
70
- /** Load every persisted data source of a project (malformed records dropped). */
71
- export async function loadDataSources(operations, projectId) {
72
- const result = await operations.documents.list({
73
- projectId,
74
- collection: DATA_SOURCES_COLLECTION,
75
- });
76
- if (!result.ok)
77
- return result;
78
- return {
79
- ok: true,
80
- value: result.value
81
- .map((record) => documentToSource(record.document))
82
- .filter((source) => source !== undefined),
83
- };
84
- }
85
- /**
86
- * Make sure the system collection exists in the project's CMS schema so
87
- * `documents.upsert` accepts source documents. Idempotent.
88
- */
89
- export async function ensureDataSourcesCollection(_operations, _projectId) {
90
- // No-op (EC-183, AD-11): the data-sources system collection is config-owned and
91
- // the backend stores documents without a schema-membership check — nothing to
92
- // register. `dataSourcesCollectionDef` remains the canonical document shape.
93
- return { ok: true, value: undefined };
94
- }
95
- /** Create or update a persisted data source (operations command). */
96
- export async function saveDataSource(operations, projectId, source) {
97
- const ensured = await ensureDataSourcesCollection(operations, projectId);
98
- if (!ensured.ok)
99
- return ensured;
100
- const result = await operations.documents.upsert({
101
- projectId,
102
- document: sourceToDocument(source),
103
- });
104
- return result.ok ? { ok: true, value: undefined } : result;
105
- }
106
- /**
107
- * Delete a persisted data source. A source that was never persisted (pure
108
- * session state, e.g. a seed) deletes as a no-op — `not-found` is success
109
- * here, since the goal state ("no persisted record") already holds.
110
- */
111
- export async function deleteDataSource(operations, projectId, sourceId) {
112
- const result = await operations.documents.delete({
113
- projectId,
114
- ref: { collection: DATA_SOURCES_COLLECTION, id: sourceId },
115
- });
116
- if (!result.ok && result.error.code === 'not-found')
117
- return { ok: true, value: undefined };
118
- return result.ok ? { ok: true, value: undefined } : result;
119
- }
120
- //# sourceMappingURL=sources-store.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sources-store.js","sourceRoot":"","sources":["../../../src/lib/data/sources-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { dataSourceSchema } from '@elytracms/core/data-binding'\nimport type { DataSource } from '@elytracms/core/data-binding'\nimport type { CmsDocument, CollectionDef } from '@elytracms/core/cms-core'\nimport type { OperationResult, OperationsClient } from '../operations'\n\n/**\n * Data-source persistence for the Builder's data layer (LIVE-mode gap fix).\n *\n * EC-166/EC-167 made the builder provision per-section (`cms.section.<nodeId>`)\n * and per-template (`cms.template.<pageId>`) CMS sources, but only as session\n * state — the live delivery chain (`convex/delivery.ts` →\n * `apps/example-site/lib/live-content.ts`) had nothing to carry. Following the\n * EC-170 routing-store / EC-169 views-store pattern, sources persist as\n * documents in ONE system collection, one document per source, and every\n * mutation goes through the *existing* `@elytracms/core/operations` commands\n * (`schema.upsertCollection`, `documents.upsert`, `documents.delete`) — no new\n * operations surface, no direct repository access.\n *\n * The record round-trips the FULL canonical `DataSource` shape (including the\n * captured `sample` + inferred `schema` envelope and the cms config's `sort`):\n * `@elytracms/core/data-binding`'s `dataSourceSchema` is the source of truth, applied\n * on both write and read, so a malformed stored record is dropped on load —\n * never a crash, never a half-parsed source.\n */\n\nexport const DATA_SOURCES_COLLECTION = 'cms-data-sources'\n\n/** System collection holding one document per persisted {@link DataSource}. */\nexport const dataSourcesCollectionDef: CollectionDef = {\n id: DATA_SOURCES_COLLECTION,\n kind: 'document',\n titleField: 'label',\n form: {\n label: 'Data sources',\n labelSingular: 'Data source',\n description: \"System collection managed by the Builder's data layer.\",\n },\n fields: [\n { name: 'label', type: 'text', validation: { required: true } },\n /** The source kind (`rest` | `cms` | `convex`), denormalized for table views. */\n { name: 'kind', type: 'text', validation: { required: true } },\n /** The FULL canonical DataSource, JSON-serialized (validated by Zod on read). */\n { name: 'config', type: 'text', validation: { required: true } },\n ],\n}\n\n// ---- Source ⇄ document mapping ----\n\nexport function sourceToDocument(source: DataSource): CmsDocument {\n const parsed = dataSourceSchema.parse(source)\n return {\n collection: DATA_SOURCES_COLLECTION,\n id: parsed.id,\n values: {\n label: parsed.label,\n kind: parsed.kind,\n config: JSON.stringify(parsed),\n },\n }\n}\n\nexport function documentToSource(document: CmsDocument): DataSource | undefined {\n const raw = document.values.config\n let value: unknown\n try {\n value = typeof raw === 'string' ? JSON.parse(raw) : undefined\n } catch {\n return undefined\n }\n const parsed = dataSourceSchema.safeParse(value)\n if (!parsed.success) return undefined\n // The document id is the source id — a record whose payload disagrees with\n // its own key is malformed and never loads.\n return parsed.data.id === document.id ? parsed.data : undefined\n}\n\n// ---- Reads & writes through @elytracms/operations ----\n\n/** Load every persisted data source of a project (malformed records dropped). */\nexport async function loadDataSources(\n operations: OperationsClient,\n projectId: string,\n): Promise<OperationResult<DataSource[]>> {\n const result = await operations.documents.list({\n projectId,\n collection: DATA_SOURCES_COLLECTION,\n })\n if (!result.ok) return result\n return {\n ok: true,\n value: result.value\n .map((record) => documentToSource(record.document))\n .filter((source): source is DataSource => source !== undefined),\n }\n}\n\n/**\n * Make sure the system collection exists in the project's CMS schema so\n * `documents.upsert` accepts source documents. Idempotent.\n */\nexport async function ensureDataSourcesCollection(\n _operations: OperationsClient,\n _projectId: string,\n): Promise<OperationResult<void>> {\n // No-op (EC-183, AD-11): the data-sources system collection is config-owned and\n // the backend stores documents without a schema-membership check — nothing to\n // register. `dataSourcesCollectionDef` remains the canonical document shape.\n return { ok: true, value: undefined }\n}\n\n/** Create or update a persisted data source (operations command). */\nexport async function saveDataSource(\n operations: OperationsClient,\n projectId: string,\n source: DataSource,\n): Promise<OperationResult<void>> {\n const ensured = await ensureDataSourcesCollection(operations, projectId)\n if (!ensured.ok) return ensured\n const result = await operations.documents.upsert({\n projectId,\n document: sourceToDocument(source),\n })\n return result.ok ? { ok: true, value: undefined } : result\n}\n\n/**\n * Delete a persisted data source. A source that was never persisted (pure\n * session state, e.g. a seed) deletes as a no-op — `not-found` is success\n * here, since the goal state (\"no persisted record\") already holds.\n */\nexport async function deleteDataSource(\n operations: OperationsClient,\n projectId: string,\n sourceId: string,\n): Promise<OperationResult<void>> {\n const result = await operations.documents.delete({\n projectId,\n ref: { collection: DATA_SOURCES_COLLECTION, id: sourceId },\n })\n if (!result.ok && result.error.code === 'not-found') return { ok: true, value: undefined }\n return result.ok ? { ok: true, value: undefined } : result\n}\n"]}
@@ -1,35 +0,0 @@
1
- import type { Locale } from '@elytracms/core/cms-core';
2
- import type { BindingReference } from '@elytracms/core/project-graph';
3
- import type { DataSource } from '@elytracms/core/data-binding';
4
- import type { DisplayedFallback } from './fallback.js';
5
- /**
6
- * Fallback visibility for BOUND content (EC-176): given a stored content
7
- * binding and its CMS source, decide whether the value the canvas currently
8
- * previews for the active locale is served via EC-018 locale fallback. Used
9
- * by the inspector's Content tab — the surface that explains what a bound
10
- * field shows (the canvas overlay itself is out of this wave's reach; see
11
- * EC-176 notes).
12
- *
13
- * Deterministic over the playground delivery engine: the same
14
- * `@elytracms/core/content` resolution that produced the previewed value reports
15
- * which fields fell back (`ResolutionInfo.localeFallbacks`), so the label can
16
- * never disagree with the displayed value.
17
- */
18
- /** A previewed bound value that fell back, plus which field it came from. */
19
- export interface BoundValueFallback extends DisplayedFallback {
20
- field: string;
21
- }
22
- /**
23
- * Whether the bound field's previewed value (first entry for list/repeater
24
- * bindings, the bound document otherwise) is a locale fallback in `locale`.
25
- * `null` when the binding is not CMS-shaped, points at no field, or the value
26
- * is a real translation.
27
- */
28
- export declare function cmsBindingFallback(binding: BindingReference, source: DataSource | undefined,
29
- /**
30
- * The locale to judge fallback in. Optional (EC-479): the ambient studio locale
31
- * is `null` until a project's locale config is installed, and the content engine
32
- * then resolves in the session's own default — so a caller that has no locale
33
- * omits it rather than substituting one.
34
- */
35
- locale?: Locale): BoundValueFallback | null;
@@ -1,73 +0,0 @@
1
- import { listQueryOfConfig } from '../bindings/section-bindings.js';
2
- import { getCollectionDocument, runCollectionListQuery } from '../data/collection-content.js';
3
- function isCmsSource(source) {
4
- return source.kind === 'cms';
5
- }
6
- /** JSON-pointer-ish token → path segments ('/0/title' → ['0', 'title']). */
7
- function pathOfToken(token) {
8
- return token
9
- .split('/')
10
- .filter((segment) => segment.length > 0)
11
- .map((segment) => segment.replaceAll('~1', '/').replaceAll('~0', '~'));
12
- }
13
- /**
14
- * Whether the bound field's previewed value (first entry for list/repeater
15
- * bindings, the bound document otherwise) is a locale fallback in `locale`.
16
- * `null` when the binding is not CMS-shaped, points at no field, or the value
17
- * is a real translation.
18
- */
19
- export function cmsBindingFallback(binding, source,
20
- /**
21
- * The locale to judge fallback in. Optional (EC-479): the ambient studio locale
22
- * is `null` until a project's locale config is installed, and the content engine
23
- * then resolves in the session's own default — so a caller that has no locale
24
- * omits it rather than substituting one.
25
- */
26
- locale) {
27
- if (source === undefined || !isCmsSource(source))
28
- return null;
29
- if (binding.mode !== 'value' && binding.mode !== 'repeaterItem')
30
- return null;
31
- const config = source.config;
32
- let path = pathOfToken(binding.token);
33
- if (path.length === 0)
34
- return null;
35
- // List-shaped value bindings carry a leading entry index; repeater-item
36
- // bindings preview the first entry (the same convention as ContentPreview).
37
- let entryIndex = 0;
38
- const listShaped = config.documentId === undefined;
39
- if (binding.mode === 'value' && listShaped) {
40
- const head = path[0];
41
- if (!/^\d+$/.test(head))
42
- return null;
43
- entryIndex = Number(head);
44
- path = path.slice(1);
45
- }
46
- const field = path[0];
47
- if (field === undefined)
48
- return null;
49
- // Resolve the previewed document's id, then ask the delivery engine which
50
- // fields fell back for it in the active locale.
51
- let documentId = config.documentId;
52
- if (documentId === undefined) {
53
- const list = runCollectionListQuery(config.collectionId, listQueryOfConfig(config), locale);
54
- if (!list.ok)
55
- return null;
56
- const entry = list.documents[entryIndex];
57
- if (entry === undefined)
58
- return null;
59
- documentId = entry.id;
60
- }
61
- const { info } = getCollectionDocument(config.collectionId, documentId, locale);
62
- if (info === null)
63
- return null;
64
- const fellBack = info.localeFallbacks.find((entry) => entry.path[0] === field);
65
- if (fellBack === undefined)
66
- return null;
67
- return {
68
- field,
69
- sourceLocale: fellBack.sourceLocale,
70
- requestedLocale: fellBack.requestedLocale,
71
- };
72
- }
73
- //# sourceMappingURL=binding-fallback.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"binding-fallback.js","sourceRoot":"","sources":["../../../src/lib/locale/binding-fallback.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Locale } from '@elytracms/core/cms-core'\nimport type { BindingReference } from '@elytracms/core/project-graph'\nimport type { CmsSource, DataSource } from '@elytracms/core/data-binding'\nimport { listQueryOfConfig } from '../bindings/section-bindings'\nimport type { QueryCmsConfig } from '../bindings/section-bindings'\nimport { getCollectionDocument, runCollectionListQuery } from '../data/collection-content'\nimport type { DisplayedFallback } from './fallback'\n\n/**\n * Fallback visibility for BOUND content (EC-176): given a stored content\n * binding and its CMS source, decide whether the value the canvas currently\n * previews for the active locale is served via EC-018 locale fallback. Used\n * by the inspector's Content tab — the surface that explains what a bound\n * field shows (the canvas overlay itself is out of this wave's reach; see\n * EC-176 notes).\n *\n * Deterministic over the playground delivery engine: the same\n * `@elytracms/core/content` resolution that produced the previewed value reports\n * which fields fell back (`ResolutionInfo.localeFallbacks`), so the label can\n * never disagree with the displayed value.\n */\n\n/** A previewed bound value that fell back, plus which field it came from. */\nexport interface BoundValueFallback extends DisplayedFallback {\n field: string\n}\n\nfunction isCmsSource(source: DataSource): source is CmsSource {\n return source.kind === 'cms'\n}\n\n/** JSON-pointer-ish token → path segments ('/0/title' → ['0', 'title']). */\nfunction pathOfToken(token: string): string[] {\n return token\n .split('/')\n .filter((segment) => segment.length > 0)\n .map((segment) => segment.replaceAll('~1', '/').replaceAll('~0', '~'))\n}\n\n/**\n * Whether the bound field's previewed value (first entry for list/repeater\n * bindings, the bound document otherwise) is a locale fallback in `locale`.\n * `null` when the binding is not CMS-shaped, points at no field, or the value\n * is a real translation.\n */\nexport function cmsBindingFallback(\n binding: BindingReference,\n source: DataSource | undefined,\n /**\n * The locale to judge fallback in. Optional (EC-479): the ambient studio locale\n * is `null` until a project's locale config is installed, and the content engine\n * then resolves in the session's own default — so a caller that has no locale\n * omits it rather than substituting one.\n */\n locale?: Locale,\n): BoundValueFallback | null {\n if (source === undefined || !isCmsSource(source)) return null\n if (binding.mode !== 'value' && binding.mode !== 'repeaterItem') return null\n\n const config = source.config as QueryCmsConfig\n let path = pathOfToken(binding.token)\n if (path.length === 0) return null\n\n // List-shaped value bindings carry a leading entry index; repeater-item\n // bindings preview the first entry (the same convention as ContentPreview).\n let entryIndex = 0\n const listShaped = config.documentId === undefined\n if (binding.mode === 'value' && listShaped) {\n const head = path[0]!\n if (!/^\\d+$/.test(head)) return null\n entryIndex = Number(head)\n path = path.slice(1)\n }\n const field = path[0]\n if (field === undefined) return null\n\n // Resolve the previewed document's id, then ask the delivery engine which\n // fields fell back for it in the active locale.\n let documentId = config.documentId\n if (documentId === undefined) {\n const list = runCollectionListQuery(config.collectionId, listQueryOfConfig(config), locale)\n if (!list.ok) return null\n const entry = list.documents[entryIndex]\n if (entry === undefined) return null\n documentId = entry.id\n }\n\n const { info } = getCollectionDocument(config.collectionId, documentId, locale)\n if (info === null) return null\n const fellBack = info.localeFallbacks.find((entry) => entry.path[0] === field)\n if (fellBack === undefined) return null\n return {\n field,\n sourceLocale: fellBack.sourceLocale,\n requestedLocale: fellBack.requestedLocale,\n }\n}\n"]}
@@ -1,5 +0,0 @@
1
- import type { InstantiatedKit } from '@elytracms/core/starter-kits';
2
- /** Record a kit instantiation for a freshly-created project. */
3
- export declare function setInstantiatedKit(projectId: string, kit: InstantiatedKit): void;
4
- /** The instantiated kit for a project, if it was created from one. */
5
- export declare function getInstantiatedKit(projectId: string): InstantiatedKit | undefined;
@@ -1,17 +0,0 @@
1
- /**
2
- * Session store for instantiated starter kits (EC-119). When a kit is imported into a new
3
- * project, its instantiated parts (graph, collections, documents, tokens) are stashed here keyed
4
- * by the new project id, so the project shell can seed the Builder graph and the CMS collections
5
- * /documents from the kit instead of the default sample fixtures. Module-scoped (per session) —
6
- * a Convex deployment would persist these instead.
7
- */
8
- const byProjectId = new Map();
9
- /** Record a kit instantiation for a freshly-created project. */
10
- export function setInstantiatedKit(projectId, kit) {
11
- byProjectId.set(projectId, kit);
12
- }
13
- /** The instantiated kit for a project, if it was created from one. */
14
- export function getInstantiatedKit(projectId) {
15
- return byProjectId.get(projectId);
16
- }
17
- //# sourceMappingURL=kit-session.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"kit-session.js","sourceRoot":"","sources":["../../../src/lib/starters/kit-session.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,WAAW,GAAG,IAAI,GAAG,EAA2B,CAAA;AAEtD,gEAAgE;AAChE,MAAM,UAAU,kBAAkB,CAAC,SAAiB,EAAE,GAAoB;IACxE,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;AACjC,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,OAAO,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;AACnC,CAAC","sourcesContent":["import type { InstantiatedKit } from '@elytracms/core/starter-kits'\n\n/**\n * Session store for instantiated starter kits (EC-119). When a kit is imported into a new\n * project, its instantiated parts (graph, collections, documents, tokens) are stashed here keyed\n * by the new project id, so the project shell can seed the Builder graph and the CMS collections\n * /documents from the kit instead of the default sample fixtures. Module-scoped (per session) —\n * a Convex deployment would persist these instead.\n */\nconst byProjectId = new Map<string, InstantiatedKit>()\n\n/** Record a kit instantiation for a freshly-created project. */\nexport function setInstantiatedKit(projectId: string, kit: InstantiatedKit): void {\n byProjectId.set(projectId, kit)\n}\n\n/** The instantiated kit for a project, if it was created from one. */\nexport function getInstantiatedKit(projectId: string): InstantiatedKit | undefined {\n return byProjectId.get(projectId)\n}\n"]}