@elytracms/studio 0.0.52 → 0.0.54
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.
- package/dist/components/account/account-settings.js +4 -4
- package/dist/components/account/credential-panel.js +1 -1
- package/dist/components/account/self-account-view-source.js +3 -3
- package/dist/components/ai/ai-chat-panel-lazy.js +1 -1
- package/dist/components/ai/ai-chat-panel.js +4 -4
- package/dist/components/ai/ai-cms-panel.js +1 -1
- package/dist/components/ai/proposal-card.js +4 -4
- package/dist/components/ai/translate-document-action.js +1 -1
- package/dist/components/ai/translate-document-dialog.d.ts +1 -1
- package/dist/components/app-views/default-modules.d.ts +3 -3
- package/dist/components/app-views/default-modules.js +20 -20
- package/dist/components/app-views/sidebar.d.ts +1 -1
- package/dist/components/app-views/sidebar.js +2 -2
- package/dist/components/app-views/studio-config.d.ts +1 -1
- package/dist/components/assets/asset-detail.js +9 -9
- package/dist/components/assets/asset-grid.js +7 -7
- package/dist/components/assets/asset-thumb.d.ts +1 -1
- package/dist/components/assets/asset-thumb.js +2 -2
- package/dist/components/assets/assets-collection-view-source.js +3 -3
- package/dist/components/assets/assets-module.js +8 -8
- package/dist/components/assets/assets-store.d.ts +1 -1
- package/dist/components/assets/assets-store.js +1 -1
- package/dist/components/builder/blocks-model.js +1 -1
- package/dist/components/builder/blocks-panel.d.ts +1 -1
- package/dist/components/builder/blocks-panel.js +6 -6
- package/dist/components/builder/canvas.js +11 -11
- package/dist/components/builder/clipboard-actions.js +2 -2
- package/dist/components/builder/composition-field-editor-lazy.d.ts +1 -1
- package/dist/components/builder/composition-field-editor-lazy.js +1 -1
- package/dist/components/builder/composition-field-editor.d.ts +1 -1
- package/dist/components/builder/composition-field-editor.js +9 -9
- package/dist/components/builder/insert-context.d.ts +2 -2
- package/dist/components/builder/insert-context.js +2 -2
- package/dist/components/builder/insert-menu.d.ts +2 -2
- package/dist/components/builder/insert-menu.js +1 -1
- package/dist/components/builder/layout-inspector.js +1 -1
- package/dist/components/builder/page-tree.js +5 -5
- package/dist/components/builder/property-inspector.js +3 -3
- package/dist/components/builder/reuse-context.d.ts +1 -1
- package/dist/components/builder/reuse-context.js +3 -3
- package/dist/components/builder/spacing-handles.js +2 -2
- package/dist/components/cms/asset-picker.js +4 -4
- package/dist/components/cms/bulk-actions.js +1 -1
- package/dist/components/cms/bulk-bar.d.ts +1 -1
- package/dist/components/cms/bulk-bar.js +3 -3
- package/dist/components/cms/cell-edit.js +1 -1
- package/dist/components/cms/cell.js +2 -2
- package/dist/components/cms/cms-index.js +1 -1
- package/dist/components/cms/cms-store.d.ts +2 -2
- package/dist/components/cms/cms-store.js +6 -6
- package/dist/components/cms/collection-table.js +17 -17
- package/dist/components/cms/detail-editor.js +31 -31
- package/dist/components/cms/document-diff-view.js +4 -4
- package/dist/components/cms/editable-cell.d.ts +1 -1
- package/dist/components/cms/editable-cell.js +6 -6
- package/dist/components/cms/field-control.js +15 -15
- package/dist/components/cms/field-renderer.d.ts +2 -2
- package/dist/components/cms/filter-builder.js +3 -3
- package/dist/components/cms/import-export.js +1 -1
- package/dist/components/cms/issues-pane.js +1 -1
- package/dist/components/cms/prop-fields.js +3 -3
- package/dist/components/cms/reference-confirm.js +1 -1
- package/dist/components/cms/relation-picker.js +1 -1
- package/dist/components/cms/rich-text/block-commands.d.ts +1 -1
- package/dist/components/cms/rich-text/component-embed.js +2 -2
- package/dist/components/cms/rich-text/editor.js +8 -8
- package/dist/components/cms/rich-text/embed-inspector.d.ts +1 -1
- package/dist/components/cms/rich-text/embed-inspector.js +2 -2
- package/dist/components/cms/rich-text/embed-picker.js +1 -1
- package/dist/components/cms/rich-text/embed-props.js +1 -1
- package/dist/components/cms/rich-text/extensions.d.ts +1 -1
- package/dist/components/cms/rich-text/extensions.js +4 -4
- package/dist/components/cms/rich-text/index.d.ts +1 -1
- package/dist/components/cms/rich-text/index.js +1 -1
- package/dist/components/cms/rich-text/insert.d.ts +1 -1
- package/dist/components/cms/rich-text/lazy.d.ts +1 -1
- package/dist/components/cms/rich-text/lazy.js +1 -1
- package/dist/components/cms/rich-text/slash-command.js +1 -1
- package/dist/components/cms/rich-text/toolbar.d.ts +1 -1
- package/dist/components/cms/rich-text/toolbar.js +4 -4
- package/dist/components/cms/use-cell-edit.d.ts +1 -1
- package/dist/components/cms/use-cell-edit.js +2 -2
- package/dist/components/cms/use-compare-selection.d.ts +1 -1
- package/dist/components/cms/use-discard-controller.d.ts +1 -1
- package/dist/components/cms/use-discard-controller.js +2 -2
- package/dist/components/cms/use-document-versions.d.ts +1 -1
- package/dist/components/cms/use-document-versions.js +1 -1
- package/dist/components/cms/use-embed-inspector-host.d.ts +1 -1
- package/dist/components/cms/use-published-perspective.d.ts +2 -2
- package/dist/components/cms/use-published-perspective.js +2 -2
- package/dist/components/cms/use-restore-version.js +1 -1
- package/dist/components/cms/version-compare-lazy.js +1 -1
- package/dist/components/cms/version-compare.js +6 -6
- package/dist/components/cms/versions-model.d.ts +1 -1
- package/dist/components/cms/versions-pane.js +5 -5
- package/dist/components/cms/view-bar.js +2 -2
- package/dist/components/collab/collab-context.js +1 -1
- package/dist/components/collection-view/cms-collection-view-source.js +2 -2
- package/dist/components/components/component-preview.js +3 -3
- package/dist/components/components/components-index.js +2 -2
- package/dist/components/components/registry-browser.js +2 -2
- package/dist/components/components/transfer-dialog.js +5 -5
- package/dist/components/components/transfer.js +4 -4
- package/dist/components/current-user-menu.js +2 -2
- package/dist/components/delivery-health-banner.js +2 -2
- package/dist/components/operation-error.js +1 -1
- package/dist/components/project-list.js +5 -5
- package/dist/components/project-session.js +1 -1
- package/dist/components/project-switcher.js +3 -3
- package/dist/components/rail-store-status.js +1 -1
- package/dist/components/redirects/redirects-collection-view-source.js +3 -3
- package/dist/components/redirects/redirects-module.js +6 -6
- package/dist/components/section-nav.js +3 -3
- package/dist/components/section-surface.js +1 -1
- package/dist/components/studio-project-screen.js +7 -7
- package/dist/components/studio-shell.js +9 -9
- package/dist/components/use-hydration-phase.js +1 -1
- package/dist/components/users/users-collection-view-source.js +4 -4
- package/dist/components/users/users-module.js +9 -9
- package/dist/components/workspace-projects.js +1 -1
- package/dist/customization.d.ts +9 -9
- package/dist/customization.js +5 -5
- package/dist/lib/ai/anthropic-provider.d.ts +1 -1
- package/dist/lib/ai/apply-content.d.ts +1 -1
- package/dist/lib/ai/apply-content.js +3 -3
- package/dist/lib/ai/chat-state.d.ts +2 -2
- package/dist/lib/ai/config.d.ts +1 -1
- package/dist/lib/ai/convex-session-headers.d.ts +68 -0
- package/dist/lib/ai/convex-session-headers.js +79 -0
- package/dist/lib/ai/convex-session-headers.js.map +1 -0
- package/dist/lib/ai/convex-session.d.ts +82 -0
- package/dist/lib/ai/convex-session.js +92 -0
- package/dist/lib/ai/convex-session.js.map +1 -0
- package/dist/lib/ai/create-flow.d.ts +2 -2
- package/dist/lib/ai/create-flow.js +3 -3
- package/dist/lib/ai/fake-provider.d.ts +1 -1
- package/dist/lib/ai/index.d.ts +27 -16
- package/dist/lib/ai/index.js +27 -16
- package/dist/lib/ai/index.js.map +1 -1
- package/dist/lib/ai/knowledge.d.ts +1 -1
- package/dist/lib/ai/node-handler.d.ts +29 -0
- package/dist/lib/ai/node-handler.js +48 -0
- package/dist/lib/ai/node-handler.js.map +1 -0
- package/dist/lib/ai/provenance.d.ts +1 -1
- package/dist/lib/ai/route-provider.d.ts +1 -1
- package/dist/lib/ai/route.d.ts +1 -1
- package/dist/lib/ai/shape.d.ts +1 -1
- package/dist/lib/ai/translate-document.d.ts +1 -1
- package/dist/lib/ai/translate-document.js +3 -3
- package/dist/lib/ai/vite.d.ts +32 -0
- package/dist/lib/ai/vite.js +97 -0
- package/dist/lib/ai/vite.js.map +1 -0
- package/dist/lib/ai-panel.js +1 -1
- package/dist/lib/assets/index.d.ts +4 -4
- package/dist/lib/assets/index.js +4 -4
- package/dist/lib/assets/upload.d.ts +2 -2
- package/dist/lib/assets/upload.js +2 -2
- package/dist/lib/auth/convex-auth-adapter.d.ts +2 -2
- package/dist/lib/auth/convex-auth-adapter.js +1 -1
- package/dist/lib/auth/dev-auto-login-adapter.d.ts +1 -1
- package/dist/lib/auth/index.d.ts +9 -9
- package/dist/lib/auth/index.js +10 -10
- package/dist/lib/auth/local-auth-adapter.d.ts +1 -1
- package/dist/lib/auth/route-guard.d.ts +1 -1
- package/dist/lib/auth-errors.d.ts +1 -1
- package/dist/lib/clipboard/index.d.ts +3 -3
- package/dist/lib/clipboard/index.js +3 -3
- package/dist/lib/cms/published-documents.d.ts +1 -1
- package/dist/lib/cms-views/index.d.ts +2 -2
- package/dist/lib/cms-views/index.js +2 -2
- package/dist/lib/collection-view/collection-view-source.d.ts +4 -4
- package/dist/lib/data/collection-content.js +1 -1
- package/dist/lib/data/data-store.js +6 -6
- package/dist/lib/data/index.d.ts +4 -4
- package/dist/lib/data/index.js +4 -4
- package/dist/lib/data/sample-capture.js +4 -4
- package/dist/lib/data/sources-store.d.ts +1 -1
- package/dist/lib/diff-view-preference.js +1 -1
- package/dist/lib/dnd/gap-drag.d.ts +1 -1
- package/dist/lib/i18n/i18n.d.ts +1 -1
- package/dist/lib/i18n/i18n.js +1 -1
- package/dist/lib/i18n/index.d.ts +4 -4
- package/dist/lib/i18n/index.js +3 -3
- package/dist/lib/i18n/messages.en.d.ts +1 -1
- package/dist/lib/i18n/messages.en.js +1 -1
- package/dist/lib/locale/binding-fallback.d.ts +1 -1
- package/dist/lib/locale/binding-fallback.js +2 -2
- package/dist/lib/locale/index.d.ts +6 -6
- package/dist/lib/locale/index.js +6 -6
- package/dist/lib/locale/locale-switcher.js +3 -3
- package/dist/lib/locale/use-studio-locale.js +1 -1
- package/dist/lib/operations/asset-repository.d.ts +1 -1
- package/dist/lib/operations/cms-persistence.d.ts +1 -1
- package/dist/lib/operations/cms-persistence.js +1 -1
- package/dist/lib/operations/index.d.ts +6 -6
- package/dist/lib/operations/index.js +6 -6
- package/dist/lib/operations/session-hydration.d.ts +1 -1
- package/dist/lib/operations/session-hydration.js +1 -1
- package/dist/lib/operations/studio-operations.d.ts +1 -1
- package/dist/lib/operations/studio-operations.js +3 -3
- package/dist/lib/persistence/convex-adapter.js +2 -2
- package/dist/lib/persistence/convex-blob-storage.d.ts +1 -1
- package/dist/lib/persistence/convex-blob-storage.js +1 -1
- package/dist/lib/persistence/deployment-readiness.d.ts +2 -2
- package/dist/lib/persistence/index.d.ts +6 -6
- package/dist/lib/persistence/index.js +7 -7
- package/dist/lib/persona/labels.js +1 -1
- package/dist/lib/query/index.d.ts +2 -2
- package/dist/lib/query/index.js +1 -1
- package/dist/lib/rail.js +1 -1
- package/dist/lib/references/impact.d.ts +1 -1
- package/dist/lib/references/impact.js +1 -1
- package/dist/lib/references/index.d.ts +3 -3
- package/dist/lib/references/index.js +3 -3
- package/dist/lib/references/references-store.d.ts +2 -2
- package/dist/lib/references/references-store.js +3 -3
- package/dist/lib/registry/index.js +2 -2
- package/dist/lib/theme.js +1 -1
- package/dist/lib/webhooks/config.d.ts +1 -1
- package/dist/lib/webhooks/config.js +2 -2
- package/dist/lib/webhooks/dispatcher.js +2 -2
- package/dist/lib/webhooks/index.d.ts +6 -6
- package/dist/lib/webhooks/index.js +4 -4
- package/dist/lib/workspace/index.d.ts +7 -7
- package/dist/lib/workspace/index.js +3 -3
- package/dist/lib/workspace/switcher-source.d.ts +1 -1
- package/dist/router/index.d.ts +1 -1
- package/dist/router/index.js +1 -1
- package/dist/ui/avatar.js +1 -1
- package/dist/ui/badge.js +1 -1
- package/dist/ui/button.js +1 -1
- package/dist/ui/card.js +1 -1
- package/dist/ui/collapsible-section.js +2 -2
- package/dist/ui/dialog.js +1 -1
- package/dist/ui/dropdown-menu.js +1 -1
- package/dist/ui/field.js +1 -1
- package/dist/ui/index.d.ts +19 -19
- package/dist/ui/index.js +19 -19
- package/dist/ui/input.js +1 -1
- package/dist/ui/inspector.js +1 -1
- package/dist/ui/layout.js +1 -1
- package/dist/ui/panel.js +2 -2
- package/dist/ui/popover.js +1 -1
- package/dist/ui/row-item.js +2 -2
- package/dist/ui/segmented-control.js +1 -1
- package/dist/ui/separator.js +1 -1
- package/dist/ui/toolbar.js +2 -2
- package/dist/ui/typography.js +1 -1
- package/package.json +13 -5
- package/dist/components/assets/asset-library.d.ts +0 -14
- package/dist/components/assets/asset-library.js +0 -202
- package/dist/components/assets/asset-library.js.map +0 -1
- package/dist/components/backend-gate.d.ts +0 -19
- package/dist/components/backend-gate.js +0 -64
- package/dist/components/backend-gate.js.map +0 -1
- package/dist/components/builder/composition-scope.d.ts +0 -16
- package/dist/components/builder/composition-scope.js +0 -7
- package/dist/components/builder/composition-scope.js.map +0 -1
- package/dist/components/cms/alias-selector.d.ts +0 -20
- package/dist/components/cms/alias-selector.js +0 -34
- package/dist/components/cms/alias-selector.js.map +0 -1
- package/dist/components/cms/collections-sidebar.d.ts +0 -18
- package/dist/components/cms/collections-sidebar.js +0 -36
- package/dist/components/cms/collections-sidebar.js.map +0 -1
- package/dist/components/cms/new-page-dialog.d.ts +0 -22
- package/dist/components/cms/new-page-dialog.js +0 -42
- package/dist/components/cms/new-page-dialog.js.map +0 -1
- package/dist/components/cms/rich-text/embed-control.d.ts +0 -17
- package/dist/components/cms/rich-text/embed-control.js +0 -62
- package/dist/components/cms/rich-text/embed-control.js.map +0 -1
- package/dist/components/cms/rich-text/image-control.d.ts +0 -16
- package/dist/components/cms/rich-text/image-control.js +0 -36
- package/dist/components/cms/rich-text/image-control.js.map +0 -1
- package/dist/components/components/fixture-runner.d.ts +0 -10
- package/dist/components/components/fixture-runner.js +0 -27
- package/dist/components/components/fixture-runner.js.map +0 -1
- package/dist/components/references/builder-deep-link.d.ts +0 -12
- package/dist/components/references/builder-deep-link.js +0 -53
- package/dist/components/references/builder-deep-link.js.map +0 -1
- package/dist/components/routes/redirect-chain.d.ts +0 -9
- package/dist/components/routes/redirect-chain.js +0 -16
- package/dist/components/routes/redirect-chain.js.map +0 -1
- package/dist/components/routes/redirect-manager.d.ts +0 -13
- package/dist/components/routes/redirect-manager.js +0 -24
- package/dist/components/routes/redirect-manager.js.map +0 -1
- package/dist/components/routes/route-list.d.ts +0 -35
- package/dist/components/routes/route-list.js +0 -69
- package/dist/components/routes/route-list.js.map +0 -1
- package/dist/components/routes/routes-shell.d.ts +0 -14
- package/dist/components/routes/routes-shell.js +0 -68
- package/dist/components/routes/routes-shell.js.map +0 -1
- package/dist/components/sections.d.ts +0 -37
- package/dist/components/sections.js +0 -62
- package/dist/components/sections.js.map +0 -1
- package/dist/components/users/user-search.d.ts +0 -8
- package/dist/components/users/user-search.js +0 -13
- package/dist/components/users/user-search.js.map +0 -1
- package/dist/components/workspace-gate.d.ts +0 -12
- package/dist/components/workspace-gate.js +0 -28
- package/dist/components/workspace-gate.js.map +0 -1
- package/dist/lib/cms-views/views-store.d.ts +0 -70
- package/dist/lib/cms-views/views-store.js +0 -129
- package/dist/lib/cms-views/views-store.js.map +0 -1
- package/dist/lib/operations/graph-commands.d.ts +0 -136
- package/dist/lib/operations/graph-commands.js +0 -85
- package/dist/lib/operations/graph-commands.js.map +0 -1
- package/dist/lib/operations/graph-persistence.d.ts +0 -27
- package/dist/lib/operations/graph-persistence.js +0 -35
- package/dist/lib/operations/graph-persistence.js.map +0 -1
- package/dist/lib/routing/index.d.ts +0 -10
- package/dist/lib/routing/index.js +0 -11
- package/dist/lib/routing/index.js.map +0 -1
- package/dist/lib/routing/routing-analysis.d.ts +0 -26
- package/dist/lib/routing/routing-analysis.js +0 -37
- package/dist/lib/routing/routing-analysis.js.map +0 -1
- package/dist/lib/routing/routing-store.d.ts +0 -50
- package/dist/lib/routing/routing-store.js +0 -72
- package/dist/lib/routing/routing-store.js.map +0 -1
- package/dist/lib/working-graph.d.ts +0 -82
- package/dist/lib/working-graph.js +0 -113
- package/dist/lib/working-graph.js.map +0 -1
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const encoder = new TextEncoder();
|
|
2
|
+
function concatBytes(chunks) {
|
|
3
|
+
let total = 0;
|
|
4
|
+
for (const chunk of chunks)
|
|
5
|
+
total += chunk.byteLength;
|
|
6
|
+
const out = new Uint8Array(total);
|
|
7
|
+
let offset = 0;
|
|
8
|
+
for (const chunk of chunks) {
|
|
9
|
+
out.set(chunk, offset);
|
|
10
|
+
offset += chunk.byteLength;
|
|
11
|
+
}
|
|
12
|
+
return out;
|
|
13
|
+
}
|
|
14
|
+
/** Reconstruct a Web `Request` from a Node request (headers, method, buffered body). */
|
|
15
|
+
async function toWebRequest(req) {
|
|
16
|
+
const chunks = [];
|
|
17
|
+
for await (const chunk of req) {
|
|
18
|
+
chunks.push(typeof chunk === 'string' ? encoder.encode(chunk) : chunk);
|
|
19
|
+
}
|
|
20
|
+
const headers = new Headers();
|
|
21
|
+
for (const [key, value] of Object.entries(req.headers)) {
|
|
22
|
+
if (typeof value === 'string')
|
|
23
|
+
headers.set(key, value);
|
|
24
|
+
else if (Array.isArray(value))
|
|
25
|
+
headers.set(key, value.join(', '));
|
|
26
|
+
}
|
|
27
|
+
const forwardedProto = req.headers['x-forwarded-proto'];
|
|
28
|
+
const proto = (typeof forwardedProto === 'string' && forwardedProto.split(',')[0]?.trim()) || 'http';
|
|
29
|
+
return new Request(`${proto}://${req.headers.host ?? 'localhost'}${req.url ?? '/'}`, {
|
|
30
|
+
method: req.method,
|
|
31
|
+
headers,
|
|
32
|
+
body: req.method === 'GET' || req.method === 'HEAD' ? undefined : concatBytes(chunks),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Wrap an {@link AiRouteHandler} as a Node `(req, res)` handler: buffer the body,
|
|
37
|
+
* bridge headers both directions, copy status + payload back.
|
|
38
|
+
*/
|
|
39
|
+
export function toNodeHandler(handler) {
|
|
40
|
+
return async (req, res) => {
|
|
41
|
+
const request = await toWebRequest(req);
|
|
42
|
+
const response = await handler(request);
|
|
43
|
+
res.statusCode = response.status;
|
|
44
|
+
response.headers.forEach((value, key) => res.setHeader(key, value));
|
|
45
|
+
res.end(new Uint8Array(await response.arrayBuffer()));
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=node-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-handler.js","sourceRoot":"","sources":["../../../src/lib/ai/node-handler.ts"],"names":[],"mappings":"AA0BA,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;AAEjC,SAAS,WAAW,CAAC,MAAoB;IACvC,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,MAAM,KAAK,IAAI,MAAM;QAAE,KAAK,IAAI,KAAK,CAAC,UAAU,CAAA;IACrD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAA;IACjC,IAAI,MAAM,GAAG,CAAC,CAAA;IACd,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QACtB,MAAM,IAAI,KAAK,CAAC,UAAU,CAAA;IAC5B,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,wFAAwF;AACxF,KAAK,UAAU,YAAY,CAAC,GAAoB;IAC9C,MAAM,MAAM,GAAiB,EAAE,CAAA;IAC/B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,KAAoB,CAAC,CAAA;IACxF,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;IAC7B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QACvD,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;aACjD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IACnE,CAAC;IACD,MAAM,cAAc,GAAG,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAA;IACvD,MAAM,KAAK,GACT,CAAC,OAAO,cAAc,KAAK,QAAQ,IAAI,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,IAAI,MAAM,CAAA;IACxF,OAAO,IAAI,OAAO,CAAC,GAAG,KAAK,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,EAAE;QACnF,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,OAAO;QACP,IAAI,EAAE,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC;KACtF,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAAuB;IACnD,OAAO,KAAK,EAAE,GAAoB,EAAE,GAAmB,EAAiB,EAAE;QACxE,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAA;QACvC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;QACvC,GAAG,CAAC,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAA;QAChC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;QACnE,GAAG,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;IACvD,CAAC,CAAA;AACH,CAAC","sourcesContent":["/**\n * `toNodeHandler` — bridge the framework-agnostic Web `Request → Response`\n * {@link AiRouteHandler} to Node's `(req, res)` signature (EC-371; closes EC-369\n * finding #2, where the identical ~25-line bridge was hand-copied four times across\n * consumers). This is the PROD half of the mounting kit: a Vercel Node function (or\n * any Node server) mounts the route as\n *\n * ```ts\n * // api/ai.ts (Vercel filesystem routing beats the SPA catch-all rewrite)\n * import { toNodeHandler } from '@elytracms/studio/lib/ai'\n * import { aiRouteHandler } from '../src/server/ai-handler.js'\n * export default toNodeHandler(aiRouteHandler)\n * ```\n *\n * The DEV half (`createAiDevPlugin`, Vite middleware + `ssrLoadModule`) reuses this\n * same bridge — one implementation, both mounts. No platform dependency: the classic\n * `(IncomingMessage, ServerResponse)` signature works on every @vercel/node version\n * and on plain `node:http`. Note it buffers the response body (including the chat\n * stream) — the proven Konditorei behavior; native streaming is EC-334's scope.\n */\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { AiRouteHandler } from './types'\n\n/** A Node-mountable request handler (Vercel Node function / `node:http` compatible). */\nexport type NodeAiRouteHandler = (req: IncomingMessage, res: ServerResponse) => Promise<void>\n\nconst encoder = new TextEncoder()\n\nfunction concatBytes(chunks: Uint8Array[]): Uint8Array<ArrayBuffer> {\n let total = 0\n for (const chunk of chunks) total += chunk.byteLength\n const out = new Uint8Array(total)\n let offset = 0\n for (const chunk of chunks) {\n out.set(chunk, offset)\n offset += chunk.byteLength\n }\n return out\n}\n\n/** Reconstruct a Web `Request` from a Node request (headers, method, buffered body). */\nasync function toWebRequest(req: IncomingMessage): Promise<Request> {\n const chunks: Uint8Array[] = []\n for await (const chunk of req) {\n chunks.push(typeof chunk === 'string' ? encoder.encode(chunk) : (chunk as Uint8Array))\n }\n const headers = new Headers()\n for (const [key, value] of Object.entries(req.headers)) {\n if (typeof value === 'string') headers.set(key, value)\n else if (Array.isArray(value)) headers.set(key, value.join(', '))\n }\n const forwardedProto = req.headers['x-forwarded-proto']\n const proto =\n (typeof forwardedProto === 'string' && forwardedProto.split(',')[0]?.trim()) || 'http'\n return new Request(`${proto}://${req.headers.host ?? 'localhost'}${req.url ?? '/'}`, {\n method: req.method,\n headers,\n body: req.method === 'GET' || req.method === 'HEAD' ? undefined : concatBytes(chunks),\n })\n}\n\n/**\n * Wrap an {@link AiRouteHandler} as a Node `(req, res)` handler: buffer the body,\n * bridge headers both directions, copy status + payload back.\n */\nexport function toNodeHandler(handler: AiRouteHandler): NodeAiRouteHandler {\n return async (req: IncomingMessage, res: ServerResponse): Promise<void> => {\n const request = await toWebRequest(req)\n const response = await handler(request)\n res.statusCode = response.status\n response.headers.forEach((value, key) => res.setHeader(key, value))\n res.end(new Uint8Array(await response.arrayBuffer()))\n }\n}\n"]}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* this marker to its result; wiring it into `documents.upsert` /
|
|
11
11
|
* `DocumentVersionRecord` (and any UI) is deferred to EC-199. No behaviour here.
|
|
12
12
|
*/
|
|
13
|
-
import type { AiProvenance, AiProvider } from './types';
|
|
13
|
+
import type { AiProvenance, AiProvider } from './types.js';
|
|
14
14
|
/** The origin discriminator for assistant-authored writes. */
|
|
15
15
|
export declare const AI_ORIGIN: "assistant";
|
|
16
16
|
/**
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* SDK. The capability gate passes: the route only ever fronts a gate-checked provider
|
|
17
17
|
* (validated at the server mount), so the proxy declares both required capabilities.
|
|
18
18
|
*/
|
|
19
|
-
import type { AiProvider } from './types';
|
|
19
|
+
import type { AiProvider } from './types.js';
|
|
20
20
|
/** How extra request headers are supplied — a static set or a (possibly async) thunk. */
|
|
21
21
|
export type RouteHeaders = HeadersInit | (() => HeadersInit | undefined | Promise<HeadersInit | undefined>);
|
|
22
22
|
export interface RouteProviderOptions {
|
package/dist/lib/ai/route.d.ts
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* execute in the client with the user's own session. A body with `messages` and no
|
|
25
25
|
* `kind` is still treated as a chat request (back-compat with the phase-1 contract).
|
|
26
26
|
*/
|
|
27
|
-
import type { AiRouteHandler, AiRouteHandlerOptions } from './types';
|
|
27
|
+
import type { AiRouteHandler, AiRouteHandlerOptions } from './types.js';
|
|
28
28
|
/** The wire discriminator selecting which model operation the route proxies. */
|
|
29
29
|
export type AiRouteKind = 'chat' | 'generate';
|
|
30
30
|
/**
|
package/dist/lib/ai/shape.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CollectionDef, JsonSchema } from '@elytracms/core/cms-core';
|
|
2
|
-
import type { RelationCandidates } from './types';
|
|
2
|
+
import type { RelationCandidates } from './types.js';
|
|
3
3
|
/** A relation field's resolved candidate set — how the engine maps ids → reference envelopes. */
|
|
4
4
|
export interface TargetRelationField {
|
|
5
5
|
fieldName: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CmsDocument, CollectionDef, Locale, LocaleConfig } from '@elytracms/core/cms-core';
|
|
2
|
-
import type { AiProvenance, AiProvider, ResolvedKnowledge } from './types';
|
|
2
|
+
import type { AiProvenance, AiProvider, ResolvedKnowledge } from './types.js';
|
|
3
3
|
/** Default translatable units per `generate` call. */
|
|
4
4
|
export declare const DEFAULT_TRANSLATE_BATCH_SIZE = 12;
|
|
5
5
|
/** Default number of `generate` calls in flight at once (mirrors the precedent's limiter of 6). */
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
*/
|
|
30
30
|
import { autoDeriveSlug, documentDefaultLocale, isFieldLocalized } from '@elytracms/core/cms-core';
|
|
31
31
|
import { activeLocaleValues, fieldConnection, hasLocaleVariant, setFieldValue, } from '@elytracms/studio/lib/locale';
|
|
32
|
-
import { assembleKnowledgeBlock } from './knowledge';
|
|
33
|
-
import { aiProvenance } from './provenance';
|
|
34
|
-
import { extractRichTextUnits, rebuildRichText } from './rich-text-translate';
|
|
32
|
+
import { assembleKnowledgeBlock } from './knowledge.js';
|
|
33
|
+
import { aiProvenance } from './provenance.js';
|
|
34
|
+
import { extractRichTextUnits, rebuildRichText } from './rich-text-translate.js';
|
|
35
35
|
/** Default translatable units per `generate` call. */
|
|
36
36
|
export const DEFAULT_TRANSLATE_BATCH_SIZE = 12;
|
|
37
37
|
/** Default number of `generate` calls in flight at once (mirrors the precedent's limiter of 6). */
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
/** Env keys the plugin surfaces from `.env*` files into `process.env` for the handler. */
|
|
3
|
+
export declare const DEFAULT_AI_DEV_ENV_KEYS: readonly ["ANTHROPIC_API_KEY", "VITE_CONVEX_SITE_URL", "VITE_CONVEX_URL"];
|
|
4
|
+
export interface AiDevPluginOptions {
|
|
5
|
+
/** The handler module (Vite root-relative), default `/src/server/ai-handler.ts`. */
|
|
6
|
+
handlerModulePath?: string;
|
|
7
|
+
/** The mounted route path (default {@link DEFAULT_AI_ENDPOINT}, `/api/ai`). */
|
|
8
|
+
route?: string;
|
|
9
|
+
/** The handler module's export name (default `aiRouteHandler`). */
|
|
10
|
+
exportName?: string;
|
|
11
|
+
/** Extra env keys to surface into `process.env` (merged over the defaults). */
|
|
12
|
+
envKeys?: readonly string[];
|
|
13
|
+
/**
|
|
14
|
+
* INSECURE, dev-only: let requests presenting NO credential pass the session gate.
|
|
15
|
+
* A playground studio has no Convex session, so without this the assistant panel
|
|
16
|
+
* answers 401 there. `'playground-mode'` scopes the bypass to dev servers booted
|
|
17
|
+
* with `VITE_ELYTRA_MODE=playground` (the recommended setting); `true` applies it
|
|
18
|
+
* to every dev boot. Defaults OFF. It cannot reach production: the plugin is
|
|
19
|
+
* `apply: 'serve'`, the handshake env var is set only in `configureServer`, and
|
|
20
|
+
* the resolver additionally refuses it under `NODE_ENV=production`. A PRESENTED
|
|
21
|
+
* token must still verify for real — the bypass never masks a bad credential.
|
|
22
|
+
*/
|
|
23
|
+
insecureAllowAnonymousSessions?: boolean | 'playground-mode';
|
|
24
|
+
}
|
|
25
|
+
/** Resolve the anonymous-bypass opt-in against the loaded env (pure; unit-pinned). */
|
|
26
|
+
export declare function resolveInsecureAnonymousOptIn(optIn: boolean | 'playground-mode' | undefined, env: Record<string, string | undefined>): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Mount the AI route in the Vite dev server. Dev-only by construction
|
|
29
|
+
* (`apply: 'serve'`); a production deploy mounts the same handler module via
|
|
30
|
+
* `toNodeHandler` in its serverless entry instead.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createAiDevPlugin(options?: AiDevPluginOptions): Plugin;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@elytracms/studio/lib/ai/vite` — `createAiDevPlugin`, the DEV half of the AI
|
|
3
|
+
* route mounting kit (EC-371; closes EC-369 finding #2). A studio app is a client
|
|
4
|
+
* SPA with no server build, so in dev the host route lives as a Vite dev-server
|
|
5
|
+
* middleware: this plugin loads the framework-agnostic `Request → Response` handler
|
|
6
|
+
* module through Vite's SSR pipeline (so its `@elytracms/*` imports resolve like the
|
|
7
|
+
* rest of the app) and bridges Node req/res via the shared {@link toNodeHandler}.
|
|
8
|
+
*
|
|
9
|
+
* It also owns the env bridge the resolver needs (the piece the template had
|
|
10
|
+
* drifted on): `loadEnv` surfaces `ANTHROPIC_API_KEY` / `VITE_CONVEX_SITE_URL` /
|
|
11
|
+
* `VITE_CONVEX_URL` from `.env`/`.env.local` into `process.env` for the SSR-loaded
|
|
12
|
+
* handler — Vite only exposes `VITE_`-prefixed vars via `import.meta.env`, and a
|
|
13
|
+
* `VITE_` prefix on the provider key would leak it into the client bundle.
|
|
14
|
+
*
|
|
15
|
+
* SEPARATE ENTRY on purpose: this module statically imports `vite`, which is a
|
|
16
|
+
* dev-only tool. It is NOT re-exported from the `lib/ai` barrel (pinned in
|
|
17
|
+
* `bundle.test.ts`), and the plugin is `apply: 'serve'` — no production build or
|
|
18
|
+
* serverless mount ever includes it. Production mounts use `toNodeHandler` from
|
|
19
|
+
* `@elytracms/studio/lib/ai` directly.
|
|
20
|
+
*/
|
|
21
|
+
import { loadEnv } from 'vite';
|
|
22
|
+
import { INSECURE_ANONYMOUS_SESSION_ENV_VALUE, INSECURE_ANONYMOUS_SESSION_ENV_VAR, } from './convex-session.js';
|
|
23
|
+
import { toNodeHandler } from './node-handler.js';
|
|
24
|
+
import { DEFAULT_AI_ENDPOINT } from './route-provider.js';
|
|
25
|
+
/** Env keys the plugin surfaces from `.env*` files into `process.env` for the handler. */
|
|
26
|
+
export const DEFAULT_AI_DEV_ENV_KEYS = [
|
|
27
|
+
'ANTHROPIC_API_KEY',
|
|
28
|
+
'VITE_CONVEX_SITE_URL',
|
|
29
|
+
'VITE_CONVEX_URL',
|
|
30
|
+
];
|
|
31
|
+
/** Resolve the anonymous-bypass opt-in against the loaded env (pure; unit-pinned). */
|
|
32
|
+
export function resolveInsecureAnonymousOptIn(optIn, env) {
|
|
33
|
+
if (optIn === true)
|
|
34
|
+
return true;
|
|
35
|
+
if (optIn === 'playground-mode')
|
|
36
|
+
return env.VITE_ELYTRA_MODE === 'playground';
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
function jsonError(code, status) {
|
|
40
|
+
return new Response(JSON.stringify({ error: code }), {
|
|
41
|
+
status,
|
|
42
|
+
headers: { 'content-type': 'application/json' },
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Mount the AI route in the Vite dev server. Dev-only by construction
|
|
47
|
+
* (`apply: 'serve'`); a production deploy mounts the same handler module via
|
|
48
|
+
* `toNodeHandler` in its serverless entry instead.
|
|
49
|
+
*/
|
|
50
|
+
export function createAiDevPlugin(options = {}) {
|
|
51
|
+
const handlerModulePath = options.handlerModulePath ?? '/src/server/ai-handler.ts';
|
|
52
|
+
const route = options.route ?? DEFAULT_AI_ENDPOINT;
|
|
53
|
+
const exportName = options.exportName ?? 'aiRouteHandler';
|
|
54
|
+
let env = {};
|
|
55
|
+
return {
|
|
56
|
+
name: 'elytra-ai-route',
|
|
57
|
+
apply: 'serve',
|
|
58
|
+
configResolved(config) {
|
|
59
|
+
env = loadEnv(config.mode, config.root, '');
|
|
60
|
+
for (const key of [...DEFAULT_AI_DEV_ENV_KEYS, ...(options.envKeys ?? [])]) {
|
|
61
|
+
if (env[key] && !process.env[key])
|
|
62
|
+
process.env[key] = env[key];
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
configureServer(server) {
|
|
66
|
+
if (resolveInsecureAnonymousOptIn(options.insecureAllowAnonymousSessions, env)) {
|
|
67
|
+
process.env[INSECURE_ANONYMOUS_SESSION_ENV_VAR] = INSECURE_ANONYMOUS_SESSION_ENV_VALUE;
|
|
68
|
+
server.config.logger.warn(`[elytra-ai] insecureAllowAnonymousSessions is ON for this dev server: ${route} ` +
|
|
69
|
+
'accepts requests without a session token (requests presenting a token are still verified).');
|
|
70
|
+
}
|
|
71
|
+
// Per request: SSR-load the handler (picks up its @elytracms/* imports through
|
|
72
|
+
// Vite) and run it; a load/handler failure is a structured 500, never a crash.
|
|
73
|
+
const bridge = toNodeHandler(async (request) => {
|
|
74
|
+
try {
|
|
75
|
+
const mod = (await server.ssrLoadModule(handlerModulePath));
|
|
76
|
+
const handler = mod[exportName];
|
|
77
|
+
if (typeof handler !== 'function')
|
|
78
|
+
return jsonError('route-handler-missing', 500);
|
|
79
|
+
return await handler(request);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return jsonError('route-error', 500);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
server.middlewares.use((req, res, next) => {
|
|
86
|
+
if (!req.url || !req.url.startsWith(route))
|
|
87
|
+
return next();
|
|
88
|
+
void bridge(req, res).catch(() => {
|
|
89
|
+
if (!res.headersSent)
|
|
90
|
+
res.statusCode = 500;
|
|
91
|
+
res.end();
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=vite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite.js","sourceRoot":"","sources":["../../../src/lib/ai/vite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAE9B,OAAO,EACL,oCAAoC,EACpC,kCAAkC,GACnC,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAGtD,0FAA0F;AAC1F,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,mBAAmB;IACnB,sBAAsB;IACtB,iBAAiB;CACT,CAAA;AAwBV,sFAAsF;AACtF,MAAM,UAAU,6BAA6B,CAC3C,KAA8C,EAC9C,GAAuC;IAEvC,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IAC/B,IAAI,KAAK,KAAK,iBAAiB;QAAE,OAAO,GAAG,CAAC,gBAAgB,KAAK,YAAY,CAAA;IAC7E,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,SAAS,CAAC,IAAY,EAAE,MAAc;IAC7C,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE;QACnD,MAAM;QACN,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC,CAAA;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAA8B,EAAE;IAChE,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,IAAI,2BAA2B,CAAA;IAClF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,mBAAmB,CAAA;IAClD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,gBAAgB,CAAA;IACzD,IAAI,GAAG,GAAuC,EAAE,CAAA;IAEhD,OAAO;QACL,IAAI,EAAE,iBAAiB;QACvB,KAAK,EAAE,OAAO;QACd,cAAc,CAAC,MAAM;YACnB,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;YAC3C,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,uBAAuB,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;gBAC3E,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;oBAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;YAChE,CAAC;QACH,CAAC;QACD,eAAe,CAAC,MAAqB;YACnC,IAAI,6BAA6B,CAAC,OAAO,CAAC,8BAA8B,EAAE,GAAG,CAAC,EAAE,CAAC;gBAC/E,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,GAAG,oCAAoC,CAAA;gBACtF,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CACvB,yEAAyE,KAAK,GAAG;oBAC/E,4FAA4F,CAC/F,CAAA;YACH,CAAC;YAED,+EAA+E;YAC/E,+EAA+E;YAC/E,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,OAAgB,EAAqB,EAAE;gBACzE,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAA4B,CAAA;oBACtF,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,CAAC,CAAA;oBAC/B,IAAI,OAAO,OAAO,KAAK,UAAU;wBAAE,OAAO,SAAS,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAA;oBACjF,OAAO,MAAO,OAA0B,CAAC,OAAO,CAAC,CAAA;gBACnD,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,SAAS,CAAC,aAAa,EAAE,GAAG,CAAC,CAAA;gBACtC,CAAC;YACH,CAAC,CAAC,CAAA;YAEF,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;gBACxC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC;oBAAE,OAAO,IAAI,EAAE,CAAA;gBACzD,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;oBAC/B,IAAI,CAAC,GAAG,CAAC,WAAW;wBAAE,GAAG,CAAC,UAAU,GAAG,GAAG,CAAA;oBAC1C,GAAG,CAAC,GAAG,EAAE,CAAA;gBACX,CAAC,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC;KACF,CAAA;AACH,CAAC","sourcesContent":["/**\n * `@elytracms/studio/lib/ai/vite` — `createAiDevPlugin`, the DEV half of the AI\n * route mounting kit (EC-371; closes EC-369 finding #2). A studio app is a client\n * SPA with no server build, so in dev the host route lives as a Vite dev-server\n * middleware: this plugin loads the framework-agnostic `Request → Response` handler\n * module through Vite's SSR pipeline (so its `@elytracms/*` imports resolve like the\n * rest of the app) and bridges Node req/res via the shared {@link toNodeHandler}.\n *\n * It also owns the env bridge the resolver needs (the piece the template had\n * drifted on): `loadEnv` surfaces `ANTHROPIC_API_KEY` / `VITE_CONVEX_SITE_URL` /\n * `VITE_CONVEX_URL` from `.env`/`.env.local` into `process.env` for the SSR-loaded\n * handler — Vite only exposes `VITE_`-prefixed vars via `import.meta.env`, and a\n * `VITE_` prefix on the provider key would leak it into the client bundle.\n *\n * SEPARATE ENTRY on purpose: this module statically imports `vite`, which is a\n * dev-only tool. It is NOT re-exported from the `lib/ai` barrel (pinned in\n * `bundle.test.ts`), and the plugin is `apply: 'serve'` — no production build or\n * serverless mount ever includes it. Production mounts use `toNodeHandler` from\n * `@elytracms/studio/lib/ai` directly.\n */\nimport { loadEnv } from 'vite'\nimport type { Plugin, ViteDevServer } from 'vite'\nimport {\n INSECURE_ANONYMOUS_SESSION_ENV_VALUE,\n INSECURE_ANONYMOUS_SESSION_ENV_VAR,\n} from './convex-session'\nimport { toNodeHandler } from './node-handler'\nimport { DEFAULT_AI_ENDPOINT } from './route-provider'\nimport type { AiRouteHandler } from './types'\n\n/** Env keys the plugin surfaces from `.env*` files into `process.env` for the handler. */\nexport const DEFAULT_AI_DEV_ENV_KEYS = [\n 'ANTHROPIC_API_KEY',\n 'VITE_CONVEX_SITE_URL',\n 'VITE_CONVEX_URL',\n] as const\n\nexport interface AiDevPluginOptions {\n /** The handler module (Vite root-relative), default `/src/server/ai-handler.ts`. */\n handlerModulePath?: string\n /** The mounted route path (default {@link DEFAULT_AI_ENDPOINT}, `/api/ai`). */\n route?: string\n /** The handler module's export name (default `aiRouteHandler`). */\n exportName?: string\n /** Extra env keys to surface into `process.env` (merged over the defaults). */\n envKeys?: readonly string[]\n /**\n * INSECURE, dev-only: let requests presenting NO credential pass the session gate.\n * A playground studio has no Convex session, so without this the assistant panel\n * answers 401 there. `'playground-mode'` scopes the bypass to dev servers booted\n * with `VITE_ELYTRA_MODE=playground` (the recommended setting); `true` applies it\n * to every dev boot. Defaults OFF. It cannot reach production: the plugin is\n * `apply: 'serve'`, the handshake env var is set only in `configureServer`, and\n * the resolver additionally refuses it under `NODE_ENV=production`. A PRESENTED\n * token must still verify for real — the bypass never masks a bad credential.\n */\n insecureAllowAnonymousSessions?: boolean | 'playground-mode'\n}\n\n/** Resolve the anonymous-bypass opt-in against the loaded env (pure; unit-pinned). */\nexport function resolveInsecureAnonymousOptIn(\n optIn: boolean | 'playground-mode' | undefined,\n env: Record<string, string | undefined>,\n): boolean {\n if (optIn === true) return true\n if (optIn === 'playground-mode') return env.VITE_ELYTRA_MODE === 'playground'\n return false\n}\n\nfunction jsonError(code: string, status: number): Response {\n return new Response(JSON.stringify({ error: code }), {\n status,\n headers: { 'content-type': 'application/json' },\n })\n}\n\n/**\n * Mount the AI route in the Vite dev server. Dev-only by construction\n * (`apply: 'serve'`); a production deploy mounts the same handler module via\n * `toNodeHandler` in its serverless entry instead.\n */\nexport function createAiDevPlugin(options: AiDevPluginOptions = {}): Plugin {\n const handlerModulePath = options.handlerModulePath ?? '/src/server/ai-handler.ts'\n const route = options.route ?? DEFAULT_AI_ENDPOINT\n const exportName = options.exportName ?? 'aiRouteHandler'\n let env: Record<string, string | undefined> = {}\n\n return {\n name: 'elytra-ai-route',\n apply: 'serve',\n configResolved(config) {\n env = loadEnv(config.mode, config.root, '')\n for (const key of [...DEFAULT_AI_DEV_ENV_KEYS, ...(options.envKeys ?? [])]) {\n if (env[key] && !process.env[key]) process.env[key] = env[key]\n }\n },\n configureServer(server: ViteDevServer) {\n if (resolveInsecureAnonymousOptIn(options.insecureAllowAnonymousSessions, env)) {\n process.env[INSECURE_ANONYMOUS_SESSION_ENV_VAR] = INSECURE_ANONYMOUS_SESSION_ENV_VALUE\n server.config.logger.warn(\n `[elytra-ai] insecureAllowAnonymousSessions is ON for this dev server: ${route} ` +\n 'accepts requests without a session token (requests presenting a token are still verified).',\n )\n }\n\n // Per request: SSR-load the handler (picks up its @elytracms/* imports through\n // Vite) and run it; a load/handler failure is a structured 500, never a crash.\n const bridge = toNodeHandler(async (request: Request): Promise<Response> => {\n try {\n const mod = (await server.ssrLoadModule(handlerModulePath)) as Record<string, unknown>\n const handler = mod[exportName]\n if (typeof handler !== 'function') return jsonError('route-handler-missing', 500)\n return await (handler as AiRouteHandler)(request)\n } catch {\n return jsonError('route-error', 500)\n }\n })\n\n server.middlewares.use((req, res, next) => {\n if (!req.url || !req.url.startsWith(route)) return next()\n void bridge(req, res).catch(() => {\n if (!res.headersSent) res.statusCode = 500\n res.end()\n })\n })\n },\n }\n}\n"]}
|
package/dist/lib/ai-panel.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useSyncExternalStore } from 'react';
|
|
2
|
-
import { createBooleanPreference } from './local-preference';
|
|
2
|
+
import { createBooleanPreference } from './local-preference.js';
|
|
3
3
|
/**
|
|
4
4
|
* The AI assistant panel's open/closed state (EC-199) — a framework-free module
|
|
5
5
|
* store, like the ambient locale (`lib/locale`). Module-level on purpose: the toggle
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* the studio UI consumes these; storage is reached only through the
|
|
4
4
|
* `BlobStorageAdapter` boundary.
|
|
5
5
|
*/
|
|
6
|
-
export * from './upload-state';
|
|
7
|
-
export * from './image-dimensions';
|
|
8
|
-
export * from './upload';
|
|
9
|
-
export * from './delete-asset';
|
|
6
|
+
export * from './upload-state.js';
|
|
7
|
+
export * from './image-dimensions.js';
|
|
8
|
+
export * from './upload.js';
|
|
9
|
+
export * from './delete-asset.js';
|
package/dist/lib/assets/index.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* the studio UI consumes these; storage is reached only through the
|
|
4
4
|
* `BlobStorageAdapter` boundary.
|
|
5
5
|
*/
|
|
6
|
-
export * from './upload-state';
|
|
7
|
-
export * from './image-dimensions';
|
|
8
|
-
export * from './upload';
|
|
9
|
-
export * from './delete-asset';
|
|
6
|
+
export * from './upload-state.js';
|
|
7
|
+
export * from './image-dimensions.js';
|
|
8
|
+
export * from './upload.js';
|
|
9
|
+
export * from './delete-asset.js';
|
|
10
10
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AssetRecord, AssetRepository, BlobStorageAdapter } from '@elytracms/core/persistence';
|
|
2
|
-
import type { ImageDimensions } from './image-dimensions';
|
|
3
|
-
import type { UploadFailure, UploadState } from './upload-state';
|
|
2
|
+
import type { ImageDimensions } from './image-dimensions.js';
|
|
3
|
+
import type { UploadFailure, UploadState } from './upload-state.js';
|
|
4
4
|
/**
|
|
5
5
|
* Upload orchestration (EC-151): request upload URL → transfer bytes →
|
|
6
6
|
* confirm by writing the EC-044 metadata record (dimensions, mime, serve URL).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { detectImageDimensions } from './image-dimensions';
|
|
2
|
-
import { initialUploadState, uploadReducer } from './upload-state';
|
|
1
|
+
import { detectImageDimensions } from './image-dimensions.js';
|
|
2
|
+
import { initialUploadState, uploadReducer } from './upload-state.js';
|
|
3
3
|
/**
|
|
4
4
|
* Default browser transport: XMLHttpRequest POST for real byte progress
|
|
5
5
|
* (fetch has no upload progress without streams support everywhere).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ConvexHttpClient } from 'convex/browser';
|
|
2
|
-
import type { AuthAdapter, AuthSession, ChangePasswordInput, ChangePasswordResult, SignInCredentials, SignInResult, UpdateProfileInput, UpdateProfileResult } from './auth-adapter';
|
|
3
|
-
import type { SessionStore } from './local-auth-adapter';
|
|
2
|
+
import type { AuthAdapter, AuthSession, ChangePasswordInput, ChangePasswordResult, SignInCredentials, SignInResult, UpdateProfileInput, UpdateProfileResult } from './auth-adapter.js';
|
|
3
|
+
import type { SessionStore } from './local-auth-adapter.js';
|
|
4
4
|
/**
|
|
5
5
|
* Classify a thrown sign-in error as a DEPLOYMENT-setup failure rather than a
|
|
6
6
|
* credential problem (EC-257). Matches the Convex Auth signing-path throws:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { actionRef, mutationRef, queryRef } from '../persistence/convex-client';
|
|
1
|
+
import { actionRef, mutationRef, queryRef } from '../persistence/convex-client.js';
|
|
2
2
|
/**
|
|
3
3
|
* Convex Auth implementation of the project-owned {@link AuthAdapter}
|
|
4
4
|
* (EC-150). Decision record (also in `convex/auth.ts`): **Convex Auth** over
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AuthAdapter, AuthSession, ChangePasswordInput, ChangePasswordResult, SignInCredentials, SignInResult, UpdateProfileInput, UpdateProfileResult } from './auth-adapter';
|
|
1
|
+
import type { AuthAdapter, AuthSession, ChangePasswordInput, ChangePasswordResult, SignInCredentials, SignInResult, UpdateProfileInput, UpdateProfileResult } from './auth-adapter.js';
|
|
2
2
|
/**
|
|
3
3
|
* Dev-only unattended-auth decorator (testing de-friction). Wraps any
|
|
4
4
|
* {@link AuthAdapter}: when no session can be restored, it transparently signs
|
package/dist/lib/auth/index.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type { StudioBackendMode } from '../persistence/backend-mode';
|
|
2
|
-
import type { AuthAdapter } from './auth-adapter';
|
|
3
|
-
export type { AuthAdapter, AuthSession, AuthUser, ChangePasswordInput, ChangePasswordResult, SignInCredentials, SignInResult, UpdateProfileInput, UpdateProfileResult, } from './auth-adapter';
|
|
4
|
-
export { LocalAuthAdapter, LOCAL_DEV_CREDENTIALS } from './local-auth-adapter';
|
|
5
|
-
export type { SessionStore } from './local-auth-adapter';
|
|
6
|
-
export { ConvexAuthAdapter } from './convex-auth-adapter';
|
|
7
|
-
export { DevAutoLoginAdapter } from './dev-auto-login-adapter';
|
|
8
|
-
export { SIGN_IN_PATH, isPublicPath, postSignInTarget, resolveRouteGuard, sessionPrincipal, } from './route-guard';
|
|
9
|
-
export type { AuthStatus, RouteGuardDecision } from './route-guard';
|
|
1
|
+
import type { StudioBackendMode } from '../persistence/backend-mode.js';
|
|
2
|
+
import type { AuthAdapter } from './auth-adapter.js';
|
|
3
|
+
export type { AuthAdapter, AuthSession, AuthUser, ChangePasswordInput, ChangePasswordResult, SignInCredentials, SignInResult, UpdateProfileInput, UpdateProfileResult, } from './auth-adapter.js';
|
|
4
|
+
export { LocalAuthAdapter, LOCAL_DEV_CREDENTIALS } from './local-auth-adapter.js';
|
|
5
|
+
export type { SessionStore } from './local-auth-adapter.js';
|
|
6
|
+
export { ConvexAuthAdapter } from './convex-auth-adapter.js';
|
|
7
|
+
export { DevAutoLoginAdapter } from './dev-auto-login-adapter.js';
|
|
8
|
+
export { SIGN_IN_PATH, isPublicPath, postSignInTarget, resolveRouteGuard, sessionPrincipal, } from './route-guard.js';
|
|
9
|
+
export type { AuthStatus, RouteGuardDecision } from './route-guard.js';
|
|
10
10
|
/**
|
|
11
11
|
* Select the auth backend (EC-150/EC-153), mirroring `selectPersistenceAdapter`
|
|
12
12
|
* exactly: Convex mode means Convex Auth (over the same shared client the
|
package/dist/lib/auth/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { getConvexClient } from '../persistence/convex-client';
|
|
2
|
-
import { resolveBackendConfig, resolveDevAutoLogin } from '../persistence/backend-mode';
|
|
3
|
-
import { deploymentUrlForSlug, resolveDeploymentUrl } from '../workspace';
|
|
4
|
-
import { ConvexAuthAdapter, hasStoredConvexSession } from './convex-auth-adapter';
|
|
5
|
-
import { DevAutoLoginAdapter } from './dev-auto-login-adapter';
|
|
6
|
-
import { LocalAuthAdapter } from './local-auth-adapter';
|
|
7
|
-
export { LocalAuthAdapter, LOCAL_DEV_CREDENTIALS } from './local-auth-adapter';
|
|
8
|
-
export { ConvexAuthAdapter } from './convex-auth-adapter';
|
|
9
|
-
export { DevAutoLoginAdapter } from './dev-auto-login-adapter';
|
|
10
|
-
export { SIGN_IN_PATH, isPublicPath, postSignInTarget, resolveRouteGuard, sessionPrincipal, } from './route-guard';
|
|
1
|
+
import { getConvexClient } from '../persistence/convex-client.js';
|
|
2
|
+
import { resolveBackendConfig, resolveDevAutoLogin } from '../persistence/backend-mode.js';
|
|
3
|
+
import { deploymentUrlForSlug, resolveDeploymentUrl } from '../workspace/index.js';
|
|
4
|
+
import { ConvexAuthAdapter, hasStoredConvexSession } from './convex-auth-adapter.js';
|
|
5
|
+
import { DevAutoLoginAdapter } from './dev-auto-login-adapter.js';
|
|
6
|
+
import { LocalAuthAdapter } from './local-auth-adapter.js';
|
|
7
|
+
export { LocalAuthAdapter, LOCAL_DEV_CREDENTIALS } from './local-auth-adapter.js';
|
|
8
|
+
export { ConvexAuthAdapter } from './convex-auth-adapter.js';
|
|
9
|
+
export { DevAutoLoginAdapter } from './dev-auto-login-adapter.js';
|
|
10
|
+
export { SIGN_IN_PATH, isPublicPath, postSignInTarget, resolveRouteGuard, sessionPrincipal, } from './route-guard.js';
|
|
11
11
|
/**
|
|
12
12
|
* Select the auth backend (EC-150/EC-153), mirroring `selectPersistenceAdapter`
|
|
13
13
|
* exactly: Convex mode means Convex Auth (over the same shared client the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AuthAdapter, AuthSession, ChangePasswordResult, SignInCredentials, SignInResult, UpdateProfileResult } from './auth-adapter';
|
|
1
|
+
import type { AuthAdapter, AuthSession, ChangePasswordResult, SignInCredentials, SignInResult, UpdateProfileResult } from './auth-adapter.js';
|
|
2
2
|
/**
|
|
3
3
|
* Deterministic local auth (EC-150) for the in-memory persistence mode: the
|
|
4
4
|
* whole sign-in → role-enforcement → sign-out flow works offline, in tests,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Principal } from '@elytracms/core/operations';
|
|
2
|
-
import type { AuthSession } from './auth-adapter';
|
|
2
|
+
import type { AuthSession } from './auth-adapter.js';
|
|
3
3
|
/**
|
|
4
4
|
* Pure route-guard + principal-mapping logic (EC-150), kept free of React and
|
|
5
5
|
* router types so it is unit-testable and deterministic. The `__root` layout
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
* Studio clipboard helpers (EC-175): paste-target resolution, permissive-paste
|
|
3
3
|
* diffing, and the OS-clipboard transport over the EC-174 fragment format.
|
|
4
4
|
*/
|
|
5
|
-
export * from './paste-target';
|
|
6
|
-
export * from './paste-issues';
|
|
7
|
-
export * from './os-clipboard';
|
|
5
|
+
export * from './paste-target.js';
|
|
6
|
+
export * from './paste-issues.js';
|
|
7
|
+
export * from './os-clipboard.js';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Studio clipboard helpers (EC-175): paste-target resolution, permissive-paste
|
|
3
3
|
* diffing, and the OS-clipboard transport over the EC-174 fragment format.
|
|
4
4
|
*/
|
|
5
|
-
export * from './paste-target';
|
|
6
|
-
export * from './paste-issues';
|
|
7
|
-
export * from './os-clipboard';
|
|
5
|
+
export * from './paste-target.js';
|
|
6
|
+
export * from './paste-issues.js';
|
|
7
|
+
export * from './os-clipboard.js';
|
|
8
8
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CmsDocument } from '@elytracms/core/cms-core';
|
|
2
|
-
import type { OperationsClient } from '../operations';
|
|
2
|
+
import type { OperationsClient } from '../operations/index.js';
|
|
3
3
|
/**
|
|
4
4
|
* The PUBLISHED-perspective documents of a collection (EC-205, "live = published")
|
|
5
5
|
* — the pinned published snapshot of each currently-published document, keyed by
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
* (EC-246b) — the DB saved-view store is retired; `view-model.configViewsFor`
|
|
5
5
|
* resolves the named views a collection declares in `cms/`.
|
|
6
6
|
*/
|
|
7
|
-
export * from './view-model';
|
|
8
|
-
export * from './selection';
|
|
7
|
+
export * from './view-model.js';
|
|
8
|
+
export * from './selection.js';
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
* (EC-246b) — the DB saved-view store is retired; `view-model.configViewsFor`
|
|
5
5
|
* resolves the named views a collection declares in `cms/`.
|
|
6
6
|
*/
|
|
7
|
-
export * from './view-model';
|
|
8
|
-
export * from './selection';
|
|
7
|
+
export * from './view-model.js';
|
|
8
|
+
export * from './selection.js';
|
|
9
9
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { CmsDocument, CollectionDef, DocumentRef, DocumentUrl, FieldDef, Locale, LocaleConfig, LocalizedString, RestoreScope } from '@elytracms/core/cms-core';
|
|
2
2
|
import type { CmsValidationIssue } from '@elytracms/core/cms-core';
|
|
3
3
|
import type { OperationError } from '@elytracms/core/operations';
|
|
4
|
-
import type { TableViewState } from '../cms-views/view-model';
|
|
5
|
-
import type { CellCommitInput, CellCommitOutcome } from '../../components/cms/cell-edit';
|
|
6
|
-
import type { BulkAction, BulkReport, BulkSetField } from '../../components/cms/bulk-actions';
|
|
7
|
-
import type { DocumentVersionsView, ImportReport } from '../../components/cms/cms-store';
|
|
4
|
+
import type { TableViewState } from '../cms-views/view-model.js';
|
|
5
|
+
import type { CellCommitInput, CellCommitOutcome } from '../../components/cms/cell-edit.js';
|
|
6
|
+
import type { BulkAction, BulkReport, BulkSetField } from '../../components/cms/bulk-actions.js';
|
|
7
|
+
import type { DocumentVersionsView, ImportReport } from '../../components/cms/cms-store.js';
|
|
8
8
|
/**
|
|
9
9
|
* `CollectionViewSource` — the studio's UNIVERSAL interaction seam (EC-240,
|
|
10
10
|
* vision AD-19).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createContentClient, createContentContext, } from '@elytracms/core/content';
|
|
2
2
|
import { documentKey, resolveDocumentTitle, sampleLocaleConfig } from '@elytracms/core/cms-core';
|
|
3
|
-
import { getStudioLocale } from '../locale/locale-store';
|
|
3
|
+
import { getStudioLocale } from '../locale/locale-store.js';
|
|
4
4
|
/**
|
|
5
5
|
* Default (no-session) collection schema: EMPTY. The studio ships no demo content
|
|
6
6
|
* (Oli, 2026-06-19) — with no backend/content session configured, there is nothing
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useEffect, useMemo, useReducer, useState } from 'react';
|
|
3
3
|
import { SourceRegistry, captureSample, inferSchema, resolveBinding, resolveCondition, tokensForSchema, } from '@elytracms/core/data-binding';
|
|
4
|
-
import { getStudioOperations } from '../operations';
|
|
4
|
+
import { getStudioOperations } from '../operations/index.js';
|
|
5
5
|
import { useOperationCache, useOperationQuery } from '@elytracms/studio/lib/query';
|
|
6
6
|
import { createRequiredContext } from '@elytracms/studio/lib/required-context';
|
|
7
|
-
import { STUDIO_SYSTEM_COLLECTION_IDS } from '../operations/session-hydration';
|
|
8
|
-
import { resolveDeploymentCollections } from '../workspace';
|
|
9
|
-
import { hasContentSession } from './collection-content';
|
|
10
|
-
import { captureSourceSample, cmsSourceForCollection } from './sample-capture';
|
|
11
|
-
import { deleteDataSource, loadDataSources, saveDataSource } from './sources-store';
|
|
7
|
+
import { STUDIO_SYSTEM_COLLECTION_IDS } from '../operations/session-hydration.js';
|
|
8
|
+
import { resolveDeploymentCollections } from '../workspace/index.js';
|
|
9
|
+
import { hasContentSession } from './collection-content.js';
|
|
10
|
+
import { captureSourceSample, cmsSourceForCollection } from './sample-capture.js';
|
|
11
|
+
import { deleteDataSource, loadDataSources, saveDataSource } from './sources-store.js';
|
|
12
12
|
function upsert(sources, source) {
|
|
13
13
|
const exists = sources.some((s) => s.id === source.id);
|
|
14
14
|
return exists ? sources.map((s) => (s.id === source.id ? source : s)) : [...sources, source];
|
package/dist/lib/data/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from './data-store';
|
|
2
|
-
export * from './sample-capture';
|
|
3
|
-
export * from './sources-store';
|
|
4
|
-
export * from './collection-content';
|
|
1
|
+
export * from './data-store.js';
|
|
2
|
+
export * from './sample-capture.js';
|
|
3
|
+
export * from './sources-store.js';
|
|
4
|
+
export * from './collection-content.js';
|
package/dist/lib/data/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export * from './data-store';
|
|
2
|
-
export * from './sample-capture';
|
|
3
|
-
export * from './sources-store';
|
|
4
|
-
export * from './collection-content';
|
|
1
|
+
export * from './data-store.js';
|
|
2
|
+
export * from './sample-capture.js';
|
|
3
|
+
export * from './sources-store.js';
|
|
4
|
+
export * from './collection-content.js';
|
|
5
5
|
// Data providers (EC-167) are imported from './providers' directly: the module
|
|
6
6
|
// exports a `DataProvider` domain type that would collide with the store's
|
|
7
7
|
// `<DataProvider>` React provider in a wildcard barrel.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { captureSample } from '@elytracms/core/data-binding';
|
|
2
|
-
import { humanizeName } from '../utils';
|
|
3
|
-
import { listQueryOfConfig } from '../bindings/section-bindings';
|
|
4
|
-
import { getCollectionDocument, hasContentSession, playgroundCollection, runCollectionListQuery, } from './collection-content';
|
|
5
|
-
import { providerIdOfSource, providerPayload } from './providers';
|
|
2
|
+
import { humanizeName } from '../utils.js';
|
|
3
|
+
import { listQueryOfConfig } from '../bindings/section-bindings.js';
|
|
4
|
+
import { getCollectionDocument, hasContentSession, playgroundCollection, runCollectionListQuery, } from './collection-content.js';
|
|
5
|
+
import { providerIdOfSource, providerPayload } from './providers.js';
|
|
6
6
|
/**
|
|
7
7
|
* Data-source sample capture (EC-083/EC-166/EC-167). The hosted builder is
|
|
8
8
|
* separate from the site it exports: actually performing a REST fetch / external
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DataSource } from '@elytracms/core/data-binding';
|
|
2
2
|
import type { CmsDocument, CollectionDef } from '@elytracms/core/cms-core';
|
|
3
|
-
import type { OperationResult, OperationsClient } from '../operations';
|
|
3
|
+
import type { OperationResult, OperationsClient } from '../operations/index.js';
|
|
4
4
|
/**
|
|
5
5
|
* Data-source persistence for the Builder's data layer (LIVE-mode gap fix).
|
|
6
6
|
*
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* best-effort instead of a new persistence mechanism. Unavailable storage (SSR,
|
|
7
7
|
* privacy mode) degrades to the default every session — never a crash.
|
|
8
8
|
*/
|
|
9
|
-
import { createEnumPreference } from './local-preference';
|
|
9
|
+
import { createEnumPreference } from './local-preference.js';
|
|
10
10
|
export const DIFF_VIEW_STORAGE_KEY = 'elytra-version-diff-view';
|
|
11
11
|
export const DEFAULT_DIFF_VIEW_MODE = 'sideBySide';
|
|
12
12
|
const preference = createEnumPreference(DIFF_VIEW_STORAGE_KEY, ['sideBySide', 'unified'], DEFAULT_DIFF_VIEW_MODE);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ComponentNode, SpacingTokenName } from '@elytracms/core/project-graph';
|
|
2
|
-
import type { FlowAxis } from './drop-rules';
|
|
2
|
+
import type { FlowAxis } from './drop-rules.js';
|
|
3
3
|
/**
|
|
4
4
|
* Tokenized gap-drag math (EC-163, vision §3.1 / AD-10) — pure functions with
|
|
5
5
|
* no DOM dependencies, shared by the canvas spacing handles. The drag model is
|
package/dist/lib/i18n/i18n.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { LocalizedString } from '@elytracms/core/cms-core';
|
|
2
|
-
import type { MessageCatalog, SourceCatalog } from './types';
|
|
2
|
+
import type { MessageCatalog, SourceCatalog } from './types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Pick the best available locale for the browser's ordered language preferences
|
|
5
5
|
* (EC-241): an exact tag match wins, else the base language (`de-DE` → `de`), else
|
package/dist/lib/i18n/i18n.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
2
|
import { resolveLabel } from '@elytracms/core/cms-core';
|
|
3
3
|
import { resolveDeploymentI18n } from '@elytracms/studio/lib/workspace';
|
|
4
|
-
import { EN_MESSAGES } from './messages.en';
|
|
4
|
+
import { EN_MESSAGES } from './messages.en.js';
|
|
5
5
|
/**
|
|
6
6
|
* Studio-UI localization runtime (EC-241). Resolves the active UI locale from the
|
|
7
7
|
* **browser's preferred locale** (no persisted selector in v1 — that rides EC-240's
|