@krantho/api 0.0.0-stage → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/active-locales.d.ts +11 -0
- package/dist/active-locales.d.ts.map +1 -0
- package/dist/active-locales.js +31 -0
- package/dist/active-locales.js.map +1 -0
- package/dist/assistant/access.d.ts +25 -0
- package/dist/assistant/access.d.ts.map +1 -0
- package/dist/assistant/access.js +35 -0
- package/dist/assistant/access.js.map +1 -0
- package/dist/assistant/agent-loop.d.ts +31 -0
- package/dist/assistant/agent-loop.d.ts.map +1 -0
- package/dist/assistant/agent-loop.js +183 -0
- package/dist/assistant/agent-loop.js.map +1 -0
- package/dist/assistant/call-handler.d.ts +15 -0
- package/dist/assistant/call-handler.d.ts.map +1 -0
- package/dist/assistant/call-handler.js +24 -0
- package/dist/assistant/call-handler.js.map +1 -0
- package/dist/assistant/chat-handler.d.ts +8 -0
- package/dist/assistant/chat-handler.d.ts.map +1 -0
- package/dist/assistant/chat-handler.js +79 -0
- package/dist/assistant/chat-handler.js.map +1 -0
- package/dist/assistant/chat-request.d.ts +16 -0
- package/dist/assistant/chat-request.d.ts.map +1 -0
- package/dist/assistant/chat-request.js +59 -0
- package/dist/assistant/chat-request.js.map +1 -0
- package/dist/assistant/confirm-handler.d.ts +3 -0
- package/dist/assistant/confirm-handler.d.ts.map +1 -0
- package/dist/assistant/confirm-handler.js +39 -0
- package/dist/assistant/confirm-handler.js.map +1 -0
- package/dist/assistant/document-change.d.ts +22 -0
- package/dist/assistant/document-change.d.ts.map +1 -0
- package/dist/assistant/document-change.js +74 -0
- package/dist/assistant/document-change.js.map +1 -0
- package/dist/assistant/document-lock.d.ts +12 -0
- package/dist/assistant/document-lock.d.ts.map +1 -0
- package/dist/assistant/document-lock.js +14 -0
- package/dist/assistant/document-lock.js.map +1 -0
- package/dist/assistant/execute-action.d.ts +19 -0
- package/dist/assistant/execute-action.d.ts.map +1 -0
- package/dist/assistant/execute-action.js +167 -0
- package/dist/assistant/execute-action.js.map +1 -0
- package/dist/assistant/pending-action.d.ts +86 -0
- package/dist/assistant/pending-action.d.ts.map +1 -0
- package/dist/assistant/pending-action.js +104 -0
- package/dist/assistant/pending-action.js.map +1 -0
- package/dist/assistant/protocol.d.ts +120 -0
- package/dist/assistant/protocol.d.ts.map +1 -0
- package/dist/assistant/protocol.js +2 -0
- package/dist/assistant/protocol.js.map +1 -0
- package/dist/assistant/routes.d.ts +4 -0
- package/dist/assistant/routes.d.ts.map +1 -0
- package/dist/assistant/routes.js +10 -0
- package/dist/assistant/routes.js.map +1 -0
- package/dist/assistant/sse-stream.d.ts +15 -0
- package/dist/assistant/sse-stream.d.ts.map +1 -0
- package/dist/assistant/sse-stream.js +61 -0
- package/dist/assistant/sse-stream.js.map +1 -0
- package/dist/assistant/status-handler.d.ts +8 -0
- package/dist/assistant/status-handler.d.ts.map +1 -0
- package/dist/assistant/status-handler.js +39 -0
- package/dist/assistant/status-handler.js.map +1 -0
- package/dist/assistant/system-prompt.d.ts +18 -0
- package/dist/assistant/system-prompt.d.ts.map +1 -0
- package/dist/assistant/system-prompt.js +48 -0
- package/dist/assistant/system-prompt.js.map +1 -0
- package/dist/assistant/tool-registry.d.ts +19 -0
- package/dist/assistant/tool-registry.d.ts.map +1 -0
- package/dist/assistant/tool-registry.js +69 -0
- package/dist/assistant/tool-registry.js.map +1 -0
- package/dist/assistant/tools/action-tools.d.ts +4 -0
- package/dist/assistant/tools/action-tools.d.ts.map +1 -0
- package/dist/assistant/tools/action-tools.js +132 -0
- package/dist/assistant/tools/action-tools.js.map +1 -0
- package/dist/assistant/tools/aeo-tools.d.ts +4 -0
- package/dist/assistant/tools/aeo-tools.d.ts.map +1 -0
- package/dist/assistant/tools/aeo-tools.js +162 -0
- package/dist/assistant/tools/aeo-tools.js.map +1 -0
- package/dist/assistant/tools/define-tool.d.ts +55 -0
- package/dist/assistant/tools/define-tool.d.ts.map +1 -0
- package/dist/assistant/tools/define-tool.js +5 -0
- package/dist/assistant/tools/define-tool.js.map +1 -0
- package/dist/assistant/tools/draft-tools.d.ts +7 -0
- package/dist/assistant/tools/draft-tools.d.ts.map +1 -0
- package/dist/assistant/tools/draft-tools.js +105 -0
- package/dist/assistant/tools/draft-tools.js.map +1 -0
- package/dist/assistant/tools/draft-write.d.ts +49 -0
- package/dist/assistant/tools/draft-write.d.ts.map +1 -0
- package/dist/assistant/tools/draft-write.js +122 -0
- package/dist/assistant/tools/draft-write.js.map +1 -0
- package/dist/assistant/tools/faq-fit.d.ts +32 -0
- package/dist/assistant/tools/faq-fit.d.ts.map +1 -0
- package/dist/assistant/tools/faq-fit.js +96 -0
- package/dist/assistant/tools/faq-fit.js.map +1 -0
- package/dist/assistant/tools/read-tools.d.ts +13 -0
- package/dist/assistant/tools/read-tools.d.ts.map +1 -0
- package/dist/assistant/tools/read-tools.js +242 -0
- package/dist/assistant/tools/read-tools.js.map +1 -0
- package/dist/assistant/tools/seo-tools.d.ts +4 -0
- package/dist/assistant/tools/seo-tools.d.ts.map +1 -0
- package/dist/assistant/tools/seo-tools.js +152 -0
- package/dist/assistant/tools/seo-tools.js.map +1 -0
- package/dist/assistant/tools/support.d.ts +35 -0
- package/dist/assistant/tools/support.d.ts.map +1 -0
- package/dist/assistant/tools/support.js +63 -0
- package/dist/assistant/tools/support.js.map +1 -0
- package/dist/assistant/untrusted.d.ts +15 -0
- package/dist/assistant/untrusted.d.ts.map +1 -0
- package/dist/assistant/untrusted.js +27 -0
- package/dist/assistant/untrusted.js.map +1 -0
- package/dist/assistant/write-policy.d.ts +20 -0
- package/dist/assistant/write-policy.d.ts.map +1 -0
- package/dist/assistant/write-policy.js +32 -0
- package/dist/assistant/write-policy.js.map +1 -0
- package/dist/auth-tokens.d.ts +31 -0
- package/dist/auth-tokens.d.ts.map +1 -0
- package/dist/auth-tokens.js +35 -0
- package/dist/auth-tokens.js.map +1 -0
- package/dist/content-change.d.ts +16 -0
- package/dist/content-change.d.ts.map +1 -0
- package/dist/content-change.js +34 -0
- package/dist/content-change.js.map +1 -0
- package/dist/content-locks.d.ts +27 -0
- package/dist/content-locks.d.ts.map +1 -0
- package/dist/content-locks.js +40 -0
- package/dist/content-locks.js.map +1 -0
- package/dist/cookies.d.ts +19 -0
- package/dist/cookies.d.ts.map +1 -0
- package/dist/cookies.js +52 -0
- package/dist/cookies.js.map +1 -0
- package/dist/create-api-handlers.d.ts +128 -0
- package/dist/create-api-handlers.d.ts.map +1 -0
- package/dist/create-api-handlers.js +384 -0
- package/dist/create-api-handlers.js.map +1 -0
- package/dist/document-actions.d.ts +25 -0
- package/dist/document-actions.d.ts.map +1 -0
- package/dist/document-actions.js +157 -0
- package/dist/document-actions.js.map +1 -0
- package/dist/document-seo.d.ts +15 -0
- package/dist/document-seo.d.ts.map +1 -0
- package/dist/document-seo.js +41 -0
- package/dist/document-seo.js.map +1 -0
- package/dist/group-by-collection.d.ts +6 -0
- package/dist/group-by-collection.d.ts.map +1 -0
- package/dist/group-by-collection.js +11 -0
- package/dist/group-by-collection.js.map +1 -0
- package/dist/handlers/apply-metadata-defaults.d.ts +4 -0
- package/dist/handlers/apply-metadata-defaults.d.ts.map +1 -0
- package/dist/handlers/apply-metadata-defaults.js +108 -0
- package/dist/handlers/apply-metadata-defaults.js.map +1 -0
- package/dist/handlers/auth-callback.d.ts +4 -0
- package/dist/handlers/auth-callback.d.ts.map +1 -0
- package/dist/handlers/auth-callback.js +217 -0
- package/dist/handlers/auth-callback.js.map +1 -0
- package/dist/handlers/auth-capabilities.d.ts +4 -0
- package/dist/handlers/auth-capabilities.d.ts.map +1 -0
- package/dist/handlers/auth-capabilities.js +19 -0
- package/dist/handlers/auth-capabilities.js.map +1 -0
- package/dist/handlers/auth-login.d.ts +4 -0
- package/dist/handlers/auth-login.d.ts.map +1 -0
- package/dist/handlers/auth-login.js +60 -0
- package/dist/handlers/auth-login.js.map +1 -0
- package/dist/handlers/auth-logout.d.ts +4 -0
- package/dist/handlers/auth-logout.d.ts.map +1 -0
- package/dist/handlers/auth-logout.js +40 -0
- package/dist/handlers/auth-logout.js.map +1 -0
- package/dist/handlers/auth-me.d.ts +4 -0
- package/dist/handlers/auth-me.d.ts.map +1 -0
- package/dist/handlers/auth-me.js +54 -0
- package/dist/handlers/auth-me.js.map +1 -0
- package/dist/handlers/auth-oidc-login.d.ts +4 -0
- package/dist/handlers/auth-oidc-login.d.ts.map +1 -0
- package/dist/handlers/auth-oidc-login.js +51 -0
- package/dist/handlers/auth-oidc-login.js.map +1 -0
- package/dist/handlers/auth-refresh.d.ts +15 -0
- package/dist/handlers/auth-refresh.d.ts.map +1 -0
- package/dist/handlers/auth-refresh.js +82 -0
- package/dist/handlers/auth-refresh.js.map +1 -0
- package/dist/handlers/bulk-delete.d.ts +8 -0
- package/dist/handlers/bulk-delete.d.ts.map +1 -0
- package/dist/handlers/bulk-delete.js +72 -0
- package/dist/handlers/bulk-delete.js.map +1 -0
- package/dist/handlers/bulk-publish.d.ts +8 -0
- package/dist/handlers/bulk-publish.d.ts.map +1 -0
- package/dist/handlers/bulk-publish.js +48 -0
- package/dist/handlers/bulk-publish.js.map +1 -0
- package/dist/handlers/capabilities.d.ts +4 -0
- package/dist/handlers/capabilities.d.ts.map +1 -0
- package/dist/handlers/capabilities.js +44 -0
- package/dist/handlers/capabilities.js.map +1 -0
- package/dist/handlers/content-changes.d.ts +28 -0
- package/dist/handlers/content-changes.d.ts.map +1 -0
- package/dist/handlers/content-changes.js +160 -0
- package/dist/handlers/content-changes.js.map +1 -0
- package/dist/handlers/content-lock.d.ts +13 -0
- package/dist/handlers/content-lock.d.ts.map +1 -0
- package/dist/handlers/content-lock.js +109 -0
- package/dist/handlers/content-lock.js.map +1 -0
- package/dist/handlers/content-tree.d.ts +11 -0
- package/dist/handlers/content-tree.d.ts.map +1 -0
- package/dist/handlers/content-tree.js +28 -0
- package/dist/handlers/content-tree.js.map +1 -0
- package/dist/handlers/create-content.d.ts +4 -0
- package/dist/handlers/create-content.d.ts.map +1 -0
- package/dist/handlers/create-content.js +49 -0
- package/dist/handlers/create-content.js.map +1 -0
- package/dist/handlers/delete-content.d.ts +4 -0
- package/dist/handlers/delete-content.d.ts.map +1 -0
- package/dist/handlers/delete-content.js +17 -0
- package/dist/handlers/delete-content.js.map +1 -0
- package/dist/handlers/delete-runtime-field.d.ts +4 -0
- package/dist/handlers/delete-runtime-field.d.ts.map +1 -0
- package/dist/handlers/delete-runtime-field.js +43 -0
- package/dist/handlers/delete-runtime-field.js.map +1 -0
- package/dist/handlers/export-bundle.d.ts +13 -0
- package/dist/handlers/export-bundle.d.ts.map +1 -0
- package/dist/handlers/export-bundle.js +99 -0
- package/dist/handlers/export-bundle.js.map +1 -0
- package/dist/handlers/export-content.d.ts +7 -0
- package/dist/handlers/export-content.d.ts.map +1 -0
- package/dist/handlers/export-content.js +69 -0
- package/dist/handlers/export-content.js.map +1 -0
- package/dist/handlers/export-schema.d.ts +4 -0
- package/dist/handlers/export-schema.d.ts.map +1 -0
- package/dist/handlers/export-schema.js +13 -0
- package/dist/handlers/export-schema.js.map +1 -0
- package/dist/handlers/get-content.d.ts +4 -0
- package/dist/handlers/get-content.d.ts.map +1 -0
- package/dist/handlers/get-content.js +65 -0
- package/dist/handlers/get-content.js.map +1 -0
- package/dist/handlers/get-runtime-schema.d.ts +4 -0
- package/dist/handlers/get-runtime-schema.d.ts.map +1 -0
- package/dist/handlers/get-runtime-schema.js +17 -0
- package/dist/handlers/get-runtime-schema.js.map +1 -0
- package/dist/handlers/get-schema.d.ts +4 -0
- package/dist/handlers/get-schema.d.ts.map +1 -0
- package/dist/handlers/get-schema.js +87 -0
- package/dist/handlers/get-schema.js.map +1 -0
- package/dist/handlers/get-version.d.ts +4 -0
- package/dist/handlers/get-version.d.ts.map +1 -0
- package/dist/handlers/get-version.js +26 -0
- package/dist/handlers/get-version.js.map +1 -0
- package/dist/handlers/import-bundle.d.ts +4 -0
- package/dist/handlers/import-bundle.d.ts.map +1 -0
- package/dist/handlers/import-bundle.js +55 -0
- package/dist/handlers/import-bundle.js.map +1 -0
- package/dist/handlers/import-content.d.ts +4 -0
- package/dist/handlers/import-content.d.ts.map +1 -0
- package/dist/handlers/import-content.js +152 -0
- package/dist/handlers/import-content.js.map +1 -0
- package/dist/handlers/index.d.ts +87 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/handlers/index.js +87 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/handlers/list-collection.d.ts +8 -0
- package/dist/handlers/list-collection.d.ts.map +1 -0
- package/dist/handlers/list-collection.js +14 -0
- package/dist/handlers/list-collection.js.map +1 -0
- package/dist/handlers/list-collections.d.ts +4 -0
- package/dist/handlers/list-collections.d.ts.map +1 -0
- package/dist/handlers/list-collections.js +17 -0
- package/dist/handlers/list-collections.js.map +1 -0
- package/dist/handlers/list-content.d.ts +8 -0
- package/dist/handlers/list-content.d.ts.map +1 -0
- package/dist/handlers/list-content.js +22 -0
- package/dist/handlers/list-content.js.map +1 -0
- package/dist/handlers/list-query.d.ts +7 -0
- package/dist/handlers/list-query.d.ts.map +1 -0
- package/dist/handlers/list-query.js +36 -0
- package/dist/handlers/list-query.js.map +1 -0
- package/dist/handlers/list-versions.d.ts +4 -0
- package/dist/handlers/list-versions.d.ts.map +1 -0
- package/dist/handlers/list-versions.js +19 -0
- package/dist/handlers/list-versions.js.map +1 -0
- package/dist/handlers/llm-credential.d.ts +46 -0
- package/dist/handlers/llm-credential.d.ts.map +1 -0
- package/dist/handlers/llm-credential.js +68 -0
- package/dist/handlers/llm-credential.js.map +1 -0
- package/dist/handlers/llm-resolve.d.ts +45 -0
- package/dist/handlers/llm-resolve.d.ts.map +1 -0
- package/dist/handlers/llm-resolve.js +126 -0
- package/dist/handlers/llm-resolve.js.map +1 -0
- package/dist/handlers/llm-settings.d.ts +19 -0
- package/dist/handlers/llm-settings.d.ts.map +1 -0
- package/dist/handlers/llm-settings.js +209 -0
- package/dist/handlers/llm-settings.js.map +1 -0
- package/dist/handlers/media-bulk-delete.d.ts +4 -0
- package/dist/handlers/media-bulk-delete.d.ts.map +1 -0
- package/dist/handlers/media-bulk-delete.js +19 -0
- package/dist/handlers/media-bulk-delete.js.map +1 -0
- package/dist/handlers/media-bulk-update.d.ts +4 -0
- package/dist/handlers/media-bulk-update.d.ts.map +1 -0
- package/dist/handlers/media-bulk-update.js +25 -0
- package/dist/handlers/media-bulk-update.js.map +1 -0
- package/dist/handlers/media-delete.d.ts +4 -0
- package/dist/handlers/media-delete.d.ts.map +1 -0
- package/dist/handlers/media-delete.js +27 -0
- package/dist/handlers/media-delete.js.map +1 -0
- package/dist/handlers/media-duplicate.d.ts +4 -0
- package/dist/handlers/media-duplicate.d.ts.map +1 -0
- package/dist/handlers/media-duplicate.js +20 -0
- package/dist/handlers/media-duplicate.js.map +1 -0
- package/dist/handlers/media-folders.d.ts +12 -0
- package/dist/handlers/media-folders.d.ts.map +1 -0
- package/dist/handlers/media-folders.js +119 -0
- package/dist/handlers/media-folders.js.map +1 -0
- package/dist/handlers/media-get.d.ts +4 -0
- package/dist/handlers/media-get.d.ts.map +1 -0
- package/dist/handlers/media-get.js +16 -0
- package/dist/handlers/media-get.js.map +1 -0
- package/dist/handlers/media-image-info.d.ts +4 -0
- package/dist/handlers/media-image-info.d.ts.map +1 -0
- package/dist/handlers/media-image-info.js +32 -0
- package/dist/handlers/media-image-info.js.map +1 -0
- package/dist/handlers/media-image.d.ts +11 -0
- package/dist/handlers/media-image.d.ts.map +1 -0
- package/dist/handlers/media-image.js +116 -0
- package/dist/handlers/media-image.js.map +1 -0
- package/dist/handlers/media-info.d.ts +4 -0
- package/dist/handlers/media-info.d.ts.map +1 -0
- package/dist/handlers/media-info.js +18 -0
- package/dist/handlers/media-info.js.map +1 -0
- package/dist/handlers/media-list.d.ts +4 -0
- package/dist/handlers/media-list.d.ts.map +1 -0
- package/dist/handlers/media-list.js +14 -0
- package/dist/handlers/media-list.js.map +1 -0
- package/dist/handlers/media-register.d.ts +4 -0
- package/dist/handlers/media-register.d.ts.map +1 -0
- package/dist/handlers/media-register.js +57 -0
- package/dist/handlers/media-register.js.map +1 -0
- package/dist/handlers/media-replace.d.ts +9 -0
- package/dist/handlers/media-replace.d.ts.map +1 -0
- package/dist/handlers/media-replace.js +53 -0
- package/dist/handlers/media-replace.js.map +1 -0
- package/dist/handlers/media-tags.d.ts +4 -0
- package/dist/handlers/media-tags.d.ts.map +1 -0
- package/dist/handlers/media-tags.js +9 -0
- package/dist/handlers/media-tags.js.map +1 -0
- package/dist/handlers/media-update.d.ts +4 -0
- package/dist/handlers/media-update.d.ts.map +1 -0
- package/dist/handlers/media-update.js +64 -0
- package/dist/handlers/media-update.js.map +1 -0
- package/dist/handlers/media-upload.d.ts +4 -0
- package/dist/handlers/media-upload.d.ts.map +1 -0
- package/dist/handlers/media-upload.js +26 -0
- package/dist/handlers/media-upload.js.map +1 -0
- package/dist/handlers/media-usage.d.ts +9 -0
- package/dist/handlers/media-usage.d.ts.map +1 -0
- package/dist/handlers/media-usage.js +36 -0
- package/dist/handlers/media-usage.js.map +1 -0
- package/dist/handlers/migration-conflicts.d.ts +13 -0
- package/dist/handlers/migration-conflicts.d.ts.map +1 -0
- package/dist/handlers/migration-conflicts.js +55 -0
- package/dist/handlers/migration-conflicts.js.map +1 -0
- package/dist/handlers/migration-status.d.ts +4 -0
- package/dist/handlers/migration-status.d.ts.map +1 -0
- package/dist/handlers/migration-status.js +34 -0
- package/dist/handlers/migration-status.js.map +1 -0
- package/dist/handlers/publish-content.d.ts +9 -0
- package/dist/handlers/publish-content.d.ts.map +1 -0
- package/dist/handlers/publish-content.js +47 -0
- package/dist/handlers/publish-content.js.map +1 -0
- package/dist/handlers/publish-impact.d.ts +11 -0
- package/dist/handlers/publish-impact.d.ts.map +1 -0
- package/dist/handlers/publish-impact.js +44 -0
- package/dist/handlers/publish-impact.js.map +1 -0
- package/dist/handlers/resolve-page.d.ts +9 -0
- package/dist/handlers/resolve-page.d.ts.map +1 -0
- package/dist/handlers/resolve-page.js +105 -0
- package/dist/handlers/resolve-page.js.map +1 -0
- package/dist/handlers/restore-version.d.ts +4 -0
- package/dist/handlers/restore-version.d.ts.map +1 -0
- package/dist/handlers/restore-version.js +69 -0
- package/dist/handlers/restore-version.js.map +1 -0
- package/dist/handlers/runtime-metadata.d.ts +6 -0
- package/dist/handlers/runtime-metadata.d.ts.map +1 -0
- package/dist/handlers/runtime-metadata.js +82 -0
- package/dist/handlers/runtime-metadata.js.map +1 -0
- package/dist/handlers/save-runtime-field.d.ts +4 -0
- package/dist/handlers/save-runtime-field.d.ts.map +1 -0
- package/dist/handlers/save-runtime-field.js +108 -0
- package/dist/handlers/save-runtime-field.js.map +1 -0
- package/dist/handlers/search-content.d.ts +9 -0
- package/dist/handlers/search-content.d.ts.map +1 -0
- package/dist/handlers/search-content.js +40 -0
- package/dist/handlers/search-content.js.map +1 -0
- package/dist/handlers/seo-config.d.ts +16 -0
- package/dist/handlers/seo-config.d.ts.map +1 -0
- package/dist/handlers/seo-config.js +250 -0
- package/dist/handlers/seo-config.js.map +1 -0
- package/dist/handlers/seo-document.d.ts +24 -0
- package/dist/handlers/seo-document.d.ts.map +1 -0
- package/dist/handlers/seo-document.js +119 -0
- package/dist/handlers/seo-document.js.map +1 -0
- package/dist/handlers/seo-enrich-archetype.d.ts +71 -0
- package/dist/handlers/seo-enrich-archetype.d.ts.map +1 -0
- package/dist/handlers/seo-enrich-archetype.js +250 -0
- package/dist/handlers/seo-enrich-archetype.js.map +1 -0
- package/dist/handlers/seo-enrich-meta.d.ts +40 -0
- package/dist/handlers/seo-enrich-meta.d.ts.map +1 -0
- package/dist/handlers/seo-enrich-meta.js +121 -0
- package/dist/handlers/seo-enrich-meta.js.map +1 -0
- package/dist/handlers/seo-enrich-runner.d.ts +65 -0
- package/dist/handlers/seo-enrich-runner.d.ts.map +1 -0
- package/dist/handlers/seo-enrich-runner.js +192 -0
- package/dist/handlers/seo-enrich-runner.js.map +1 -0
- package/dist/handlers/seo-enrich.d.ts +10 -0
- package/dist/handlers/seo-enrich.d.ts.map +1 -0
- package/dist/handlers/seo-enrich.js +166 -0
- package/dist/handlers/seo-enrich.js.map +1 -0
- package/dist/handlers/seo-generate.d.ts +4 -0
- package/dist/handlers/seo-generate.d.ts.map +1 -0
- package/dist/handlers/seo-generate.js +31 -0
- package/dist/handlers/seo-generate.js.map +1 -0
- package/dist/handlers/seo-impact.d.ts +36 -0
- package/dist/handlers/seo-impact.d.ts.map +1 -0
- package/dist/handlers/seo-impact.js +137 -0
- package/dist/handlers/seo-impact.js.map +1 -0
- package/dist/handlers/seo-indexnow.d.ts +11 -0
- package/dist/handlers/seo-indexnow.d.ts.map +1 -0
- package/dist/handlers/seo-indexnow.js +15 -0
- package/dist/handlers/seo-indexnow.js.map +1 -0
- package/dist/handlers/seo-llms-txt.d.ts +26 -0
- package/dist/handlers/seo-llms-txt.d.ts.map +1 -0
- package/dist/handlers/seo-llms-txt.js +99 -0
- package/dist/handlers/seo-llms-txt.js.map +1 -0
- package/dist/handlers/seo-preview.d.ts +8 -0
- package/dist/handlers/seo-preview.d.ts.map +1 -0
- package/dist/handlers/seo-preview.js +49 -0
- package/dist/handlers/seo-preview.js.map +1 -0
- package/dist/handlers/seo-robots.d.ts +22 -0
- package/dist/handlers/seo-robots.d.ts.map +1 -0
- package/dist/handlers/seo-robots.js +48 -0
- package/dist/handlers/seo-robots.js.map +1 -0
- package/dist/handlers/seo-sitemap.d.ts +68 -0
- package/dist/handlers/seo-sitemap.d.ts.map +1 -0
- package/dist/handlers/seo-sitemap.js +178 -0
- package/dist/handlers/seo-sitemap.js.map +1 -0
- package/dist/handlers/seo-status.d.ts +4 -0
- package/dist/handlers/seo-status.d.ts.map +1 -0
- package/dist/handlers/seo-status.js +61 -0
- package/dist/handlers/seo-status.js.map +1 -0
- package/dist/handlers/seo-structured-data.d.ts +4 -0
- package/dist/handlers/seo-structured-data.d.ts.map +1 -0
- package/dist/handlers/seo-structured-data.js +18 -0
- package/dist/handlers/seo-structured-data.js.map +1 -0
- package/dist/handlers/site-config.d.ts +8 -0
- package/dist/handlers/site-config.d.ts.map +1 -0
- package/dist/handlers/site-config.js +26 -0
- package/dist/handlers/site-config.js.map +1 -0
- package/dist/handlers/site-preview.d.ts +10 -0
- package/dist/handlers/site-preview.d.ts.map +1 -0
- package/dist/handlers/site-preview.js +54 -0
- package/dist/handlers/site-preview.js.map +1 -0
- package/dist/handlers/site-settings.d.ts +17 -0
- package/dist/handlers/site-settings.d.ts.map +1 -0
- package/dist/handlers/site-settings.js +75 -0
- package/dist/handlers/site-settings.js.map +1 -0
- package/dist/handlers/snapshot-create.d.ts +4 -0
- package/dist/handlers/snapshot-create.d.ts.map +1 -0
- package/dist/handlers/snapshot-create.js +15 -0
- package/dist/handlers/snapshot-create.js.map +1 -0
- package/dist/handlers/snapshot-delete.d.ts +4 -0
- package/dist/handlers/snapshot-delete.d.ts.map +1 -0
- package/dist/handlers/snapshot-delete.js +21 -0
- package/dist/handlers/snapshot-delete.js.map +1 -0
- package/dist/handlers/snapshot-get.d.ts +4 -0
- package/dist/handlers/snapshot-get.d.ts.map +1 -0
- package/dist/handlers/snapshot-get.js +17 -0
- package/dist/handlers/snapshot-get.js.map +1 -0
- package/dist/handlers/snapshot-list.d.ts +4 -0
- package/dist/handlers/snapshot-list.d.ts.map +1 -0
- package/dist/handlers/snapshot-list.js +9 -0
- package/dist/handlers/snapshot-list.js.map +1 -0
- package/dist/handlers/snapshot-restore.d.ts +4 -0
- package/dist/handlers/snapshot-restore.d.ts.map +1 -0
- package/dist/handlers/snapshot-restore.js +27 -0
- package/dist/handlers/snapshot-restore.js.map +1 -0
- package/dist/handlers/translation-status.d.ts +9 -0
- package/dist/handlers/translation-status.d.ts.map +1 -0
- package/dist/handlers/translation-status.js +68 -0
- package/dist/handlers/translation-status.js.map +1 -0
- package/dist/handlers/update-content.d.ts +4 -0
- package/dist/handlers/update-content.d.ts.map +1 -0
- package/dist/handlers/update-content.js +66 -0
- package/dist/handlers/update-content.js.map +1 -0
- package/dist/handlers/user-create.d.ts +4 -0
- package/dist/handlers/user-create.d.ts.map +1 -0
- package/dist/handlers/user-create.js +38 -0
- package/dist/handlers/user-create.js.map +1 -0
- package/dist/handlers/user-delete.d.ts +4 -0
- package/dist/handlers/user-delete.d.ts.map +1 -0
- package/dist/handlers/user-delete.js +25 -0
- package/dist/handlers/user-delete.js.map +1 -0
- package/dist/handlers/user-get.d.ts +4 -0
- package/dist/handlers/user-get.d.ts.map +1 -0
- package/dist/handlers/user-get.js +22 -0
- package/dist/handlers/user-get.js.map +1 -0
- package/dist/handlers/user-list.d.ts +4 -0
- package/dist/handlers/user-list.d.ts.map +1 -0
- package/dist/handlers/user-list.js +28 -0
- package/dist/handlers/user-list.js.map +1 -0
- package/dist/handlers/user-permissions.d.ts +6 -0
- package/dist/handlers/user-permissions.d.ts.map +1 -0
- package/dist/handlers/user-permissions.js +42 -0
- package/dist/handlers/user-permissions.js.map +1 -0
- package/dist/handlers/user-update.d.ts +4 -0
- package/dist/handlers/user-update.d.ts.map +1 -0
- package/dist/handlers/user-update.js +54 -0
- package/dist/handlers/user-update.js.map +1 -0
- package/dist/handlers/validate-all.d.ts +4 -0
- package/dist/handlers/validate-all.d.ts.map +1 -0
- package/dist/handlers/validate-all.js +14 -0
- package/dist/handlers/validate-all.js.map +1 -0
- package/dist/handlers/version-retention.d.ts +6 -0
- package/dist/handlers/version-retention.d.ts.map +1 -0
- package/dist/handlers/version-retention.js +40 -0
- package/dist/handlers/version-retention.js.map +1 -0
- package/dist/handlers/webhook-deliveries.d.ts +4 -0
- package/dist/handlers/webhook-deliveries.d.ts.map +1 -0
- package/dist/handlers/webhook-deliveries.js +24 -0
- package/dist/handlers/webhook-deliveries.js.map +1 -0
- package/dist/handlers/webhook-retry.d.ts +11 -0
- package/dist/handlers/webhook-retry.d.ts.map +1 -0
- package/dist/handlers/webhook-retry.js +69 -0
- package/dist/handlers/webhook-retry.js.map +1 -0
- package/dist/head.d.ts +9 -0
- package/dist/head.d.ts.map +1 -0
- package/dist/head.js +28 -0
- package/dist/head.js.map +1 -0
- package/dist/hooks.d.ts +34 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +19 -0
- package/dist/hooks.js.map +1 -0
- package/dist/image-cache.d.ts +47 -0
- package/dist/image-cache.d.ts.map +1 -0
- package/dist/image-cache.js +112 -0
- package/dist/image-cache.js.map +1 -0
- package/dist/image-dimensions.d.ts +12 -0
- package/dist/image-dimensions.d.ts.map +1 -0
- package/dist/image-dimensions.js +129 -0
- package/dist/image-dimensions.js.map +1 -0
- package/dist/image-optimizer.d.ts +86 -0
- package/dist/image-optimizer.d.ts.map +1 -0
- package/dist/image-optimizer.js +206 -0
- package/dist/image-optimizer.js.map +1 -0
- package/dist/image-presets.d.ts +17 -0
- package/dist/image-presets.d.ts.map +1 -0
- package/dist/image-presets.js +50 -0
- package/dist/image-presets.js.map +1 -0
- package/dist/image-url.d.ts +26 -0
- package/dist/image-url.d.ts.map +1 -0
- package/dist/image-url.js +47 -0
- package/dist/image-url.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/jwt.d.ts +54 -0
- package/dist/jwt.d.ts.map +1 -0
- package/dist/jwt.js +114 -0
- package/dist/jwt.js.map +1 -0
- package/dist/locale-fallback.d.ts +18 -0
- package/dist/locale-fallback.d.ts.map +1 -0
- package/dist/locale-fallback.js +42 -0
- package/dist/locale-fallback.js.map +1 -0
- package/dist/media-library.d.ts +46 -0
- package/dist/media-library.d.ts.map +1 -0
- package/dist/media-library.js +231 -0
- package/dist/media-library.js.map +1 -0
- package/dist/media-reference-updater.d.ts +24 -0
- package/dist/media-reference-updater.d.ts.map +1 -0
- package/dist/media-reference-updater.js +124 -0
- package/dist/media-reference-updater.js.map +1 -0
- package/dist/media-references.d.ts +14 -0
- package/dist/media-references.d.ts.map +1 -0
- package/dist/media-references.js +25 -0
- package/dist/media-references.js.map +1 -0
- package/dist/merged-schema.d.ts +10 -0
- package/dist/merged-schema.d.ts.map +1 -0
- package/dist/merged-schema.js +21 -0
- package/dist/merged-schema.js.map +1 -0
- package/dist/middleware/auth.d.ts +21 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +82 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/oidc-state.d.ts +42 -0
- package/dist/oidc-state.d.ts.map +1 -0
- package/dist/oidc-state.js +72 -0
- package/dist/oidc-state.js.map +1 -0
- package/dist/oidc.d.ts +83 -0
- package/dist/oidc.d.ts.map +1 -0
- package/dist/oidc.js +226 -0
- package/dist/oidc.js.map +1 -0
- package/dist/openapi.d.ts +13 -0
- package/dist/openapi.d.ts.map +1 -0
- package/dist/openapi.js +133 -0
- package/dist/openapi.js.map +1 -0
- package/dist/permissions.d.ts +37 -0
- package/dist/permissions.d.ts.map +1 -0
- package/dist/permissions.js +69 -0
- package/dist/permissions.js.map +1 -0
- package/dist/plugins.d.ts +64 -0
- package/dist/plugins.d.ts.map +1 -0
- package/dist/plugins.js +73 -0
- package/dist/plugins.js.map +1 -0
- package/dist/preview-token.d.ts +13 -0
- package/dist/preview-token.d.ts.map +1 -0
- package/dist/preview-token.js +45 -0
- package/dist/preview-token.js.map +1 -0
- package/dist/public-cache.d.ts +8 -0
- package/dist/public-cache.d.ts.map +1 -0
- package/dist/public-cache.js +8 -0
- package/dist/public-cache.js.map +1 -0
- package/dist/reference-resolver.d.ts +21 -0
- package/dist/reference-resolver.d.ts.map +1 -0
- package/dist/reference-resolver.js +128 -0
- package/dist/reference-resolver.js.map +1 -0
- package/dist/return-to.d.ts +7 -0
- package/dist/return-to.d.ts.map +1 -0
- package/dist/return-to.js +15 -0
- package/dist/return-to.js.map +1 -0
- package/dist/router.d.ts +14 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +51 -0
- package/dist/router.js.map +1 -0
- package/dist/runtime-field-checks.d.ts +11 -0
- package/dist/runtime-field-checks.d.ts.map +1 -0
- package/dist/runtime-field-checks.js +72 -0
- package/dist/runtime-field-checks.js.map +1 -0
- package/dist/save-document.d.ts +71 -0
- package/dist/save-document.d.ts.map +1 -0
- package/dist/save-document.js +213 -0
- package/dist/save-document.js.map +1 -0
- package/dist/seo-compose.d.ts +50 -0
- package/dist/seo-compose.d.ts.map +1 -0
- package/dist/seo-compose.js +104 -0
- package/dist/seo-compose.js.map +1 -0
- package/dist/seo-config-snapshot.d.ts +10 -0
- package/dist/seo-config-snapshot.d.ts.map +1 -0
- package/dist/seo-config-snapshot.js +16 -0
- package/dist/seo-config-snapshot.js.map +1 -0
- package/dist/seo-loader.d.ts +10 -0
- package/dist/seo-loader.d.ts.map +1 -0
- package/dist/seo-loader.js +14 -0
- package/dist/seo-loader.js.map +1 -0
- package/dist/seo-site-findings.d.ts +27 -0
- package/dist/seo-site-findings.d.ts.map +1 -0
- package/dist/seo-site-findings.js +87 -0
- package/dist/seo-site-findings.js.map +1 -0
- package/dist/seo-subsystem.d.ts +28 -0
- package/dist/seo-subsystem.d.ts.map +1 -0
- package/dist/seo-subsystem.js +62 -0
- package/dist/seo-subsystem.js.map +1 -0
- package/dist/seo-validation.d.ts +20 -0
- package/dist/seo-validation.d.ts.map +1 -0
- package/dist/seo-validation.js +96 -0
- package/dist/seo-validation.js.map +1 -0
- package/dist/types.d.ts +126 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/validators.d.ts +107 -0
- package/dist/validators.d.ts.map +1 -0
- package/dist/validators.js +199 -0
- package/dist/validators.js.map +1 -0
- package/dist/webhooks.d.ts +29 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +123 -0
- package/dist/webhooks.js.map +1 -0
- package/dist/workload-identity.d.ts +23 -0
- package/dist/workload-identity.d.ts.map +1 -0
- package/dist/workload-identity.js +145 -0
- package/dist/workload-identity.js.map +1 -0
- package/package.json +51 -3
- package/README.md +0 -3
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { canGetContent, canQuery, hasRuntimeSchema, } from '@krantho/persistence';
|
|
2
|
+
/** Extract reference fields from runtime schema for a collection */
|
|
3
|
+
async function getReferenceFields(collection, adapter) {
|
|
4
|
+
if (!hasRuntimeSchema(adapter))
|
|
5
|
+
return [];
|
|
6
|
+
const schema = await adapter.getRuntimeSchema(collection);
|
|
7
|
+
if (!schema)
|
|
8
|
+
return [];
|
|
9
|
+
return schema.fields
|
|
10
|
+
.filter((f) => f.type === 'reference' && f.refCollection)
|
|
11
|
+
.map((f) => ({
|
|
12
|
+
name: f.name,
|
|
13
|
+
// Safe: the filter above guarantees f.refCollection is defined
|
|
14
|
+
refCollection: f.refCollection,
|
|
15
|
+
isArray: f.isArray ?? false,
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Resolve reference fields in a ContentDocument.
|
|
20
|
+
*
|
|
21
|
+
* Collects all reference field slugs, batch-loads them per collection,
|
|
22
|
+
* and replaces slug strings with full ContentDocument objects.
|
|
23
|
+
*/
|
|
24
|
+
export async function resolveReferences(doc, adapter) {
|
|
25
|
+
const refFields = await getReferenceFields(doc.meta.collection, adapter);
|
|
26
|
+
if (refFields.length === 0)
|
|
27
|
+
return doc;
|
|
28
|
+
// Collect slugs to resolve, grouped by target collection
|
|
29
|
+
const toResolve = new Map();
|
|
30
|
+
for (const field of refFields) {
|
|
31
|
+
const value = doc.fields[field.name];
|
|
32
|
+
if (!value || !field.refCollection)
|
|
33
|
+
continue;
|
|
34
|
+
if (!toResolve.has(field.refCollection)) {
|
|
35
|
+
toResolve.set(field.refCollection, new Set());
|
|
36
|
+
}
|
|
37
|
+
const slugs = toResolve.get(field.refCollection);
|
|
38
|
+
if (field.isArray && Array.isArray(value)) {
|
|
39
|
+
for (const slug of value) {
|
|
40
|
+
if (typeof slug === 'string')
|
|
41
|
+
slugs.add(slug);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else if (typeof value === 'string') {
|
|
45
|
+
slugs.add(value);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (toResolve.size === 0)
|
|
49
|
+
return doc;
|
|
50
|
+
// Batch load per collection
|
|
51
|
+
const resolved = new Map();
|
|
52
|
+
for (const [collection, slugs] of toResolve) {
|
|
53
|
+
if (!canGetContent(adapter))
|
|
54
|
+
continue;
|
|
55
|
+
for (const slug of slugs) {
|
|
56
|
+
const refDoc = await adapter.getContent(collection, slug);
|
|
57
|
+
if (refDoc)
|
|
58
|
+
resolved.set(`${collection}/${slug}`, refDoc);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (resolved.size === 0)
|
|
62
|
+
return doc;
|
|
63
|
+
// Replace slug values with resolved documents
|
|
64
|
+
const resolvedFields = { ...doc.fields };
|
|
65
|
+
for (const field of refFields) {
|
|
66
|
+
const value = doc.fields[field.name];
|
|
67
|
+
if (!value || !field.refCollection)
|
|
68
|
+
continue;
|
|
69
|
+
if (field.isArray && Array.isArray(value)) {
|
|
70
|
+
resolvedFields[field.name] = value.map((slug) => {
|
|
71
|
+
if (typeof slug !== 'string')
|
|
72
|
+
return slug;
|
|
73
|
+
return resolved.get(`${field.refCollection}/${slug}`) ?? slug;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else if (typeof value === 'string') {
|
|
77
|
+
const refDoc = resolved.get(`${field.refCollection}/${value}`);
|
|
78
|
+
if (refDoc)
|
|
79
|
+
resolvedFields[field.name] = refDoc;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return { ...doc, fields: resolvedFields };
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Find all content items that reference a specific slug in a specific collection.
|
|
86
|
+
*
|
|
87
|
+
* Scans all collections for reference fields pointing to the target collection,
|
|
88
|
+
* then checks each item's field values.
|
|
89
|
+
*/
|
|
90
|
+
export async function findReferencingItems(targetCollection, targetSlug, adapter, contentConfig) {
|
|
91
|
+
const references = [];
|
|
92
|
+
for (const [, collectionDef] of contentConfig.collections) {
|
|
93
|
+
const refFields = await getReferenceFields(collectionDef.name, adapter);
|
|
94
|
+
const matching = refFields.filter((f) => f.refCollection === targetCollection);
|
|
95
|
+
if (matching.length === 0)
|
|
96
|
+
continue;
|
|
97
|
+
if (!canQuery(adapter))
|
|
98
|
+
continue;
|
|
99
|
+
const { items } = await adapter.query({
|
|
100
|
+
state: 'current',
|
|
101
|
+
projection: 'summary',
|
|
102
|
+
collections: [collectionDef.name],
|
|
103
|
+
});
|
|
104
|
+
for (const item of items) {
|
|
105
|
+
for (const field of matching) {
|
|
106
|
+
const value = item.fields[field.name];
|
|
107
|
+
if (field.isArray && Array.isArray(value)) {
|
|
108
|
+
if (value.includes(targetSlug)) {
|
|
109
|
+
references.push({
|
|
110
|
+
collection: collectionDef.name,
|
|
111
|
+
slug: item.meta.slug,
|
|
112
|
+
field: field.name,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
else if (value === targetSlug) {
|
|
117
|
+
references.push({
|
|
118
|
+
collection: collectionDef.name,
|
|
119
|
+
slug: item.meta.slug,
|
|
120
|
+
field: field.name,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return references;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=reference-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference-resolver.js","sourceRoot":"","sources":["../src/reference-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The path from `?returnTo=`, kept only when it is a same-origin path —
|
|
3
|
+
* anything that could leave the site (`//host`, `/\host`, a scheme, control
|
|
4
|
+
* characters) falls back to Studio.
|
|
5
|
+
*/
|
|
6
|
+
export declare function safeReturnTo(value: string | undefined): string;
|
|
7
|
+
//# sourceMappingURL=return-to.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"return-to.d.ts","sourceRoot":"","sources":["../src/return-to.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAM9D"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Where the browser lands after a sign-in or refresh when the request names nowhere */
|
|
2
|
+
const DEFAULT_RETURN_TO = '/studio/';
|
|
3
|
+
/**
|
|
4
|
+
* The path from `?returnTo=`, kept only when it is a same-origin path —
|
|
5
|
+
* anything that could leave the site (`//host`, `/\host`, a scheme, control
|
|
6
|
+
* characters) falls back to Studio.
|
|
7
|
+
*/
|
|
8
|
+
export function safeReturnTo(value) {
|
|
9
|
+
if (!value?.startsWith('/') || value.startsWith('//') || value.startsWith('/\\')) {
|
|
10
|
+
return DEFAULT_RETURN_TO;
|
|
11
|
+
}
|
|
12
|
+
const hasControlCharacter = [...value].some((ch) => ch <= '\u001f' || ch === '\u007f');
|
|
13
|
+
return hasControlCharacter ? DEFAULT_RETURN_TO : value;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=return-to.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"return-to.js","sourceRoot":"","sources":["../src/return-to.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,MAAM,iBAAiB,GAAG,UAAU,CAAA;AAEpC;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAyB;IACpD,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACjF,OAAO,iBAAiB,CAAA;IAC1B,CAAC;IACD,MAAM,mBAAmB,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,QAAQ,IAAI,EAAE,KAAK,QAAQ,CAAC,CAAA;IACtF,OAAO,mBAAmB,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAA;AACxD,CAAC"}
|
package/dist/router.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ApiContext, ApiHandler, ApiRequest, ApiResponse } from './types.js';
|
|
2
|
+
export declare class ApiRouter {
|
|
3
|
+
private readonly routes;
|
|
4
|
+
/** Register a route */
|
|
5
|
+
add(method: string, pattern: string, handler: ApiHandler): void;
|
|
6
|
+
/** List all registered routes (for OpenAPI spec generation) */
|
|
7
|
+
listRoutes(): Array<{
|
|
8
|
+
method: string;
|
|
9
|
+
pattern: string;
|
|
10
|
+
}>;
|
|
11
|
+
/** Handle an incoming request */
|
|
12
|
+
handle(req: ApiRequest, ctx: ApiContext): Promise<ApiResponse>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AA2CjF,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IAErC,uBAAuB;IACvB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAK/D,+DAA+D;IAC/D,UAAU,IAAI,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAIxD,iCAAiC;IAC3B,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;CASrE"}
|
package/dist/router.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** Parse a route pattern like '/api/content/:collection/:slug' into a regex */
|
|
2
|
+
function compilePattern(pattern) {
|
|
3
|
+
const paramNames = [];
|
|
4
|
+
const regexStr = pattern.replace(/:(\w+)/g, (_, name) => {
|
|
5
|
+
paramNames.push(name);
|
|
6
|
+
return '([^/]+)';
|
|
7
|
+
});
|
|
8
|
+
return { regex: new RegExp(`^${regexStr}$`), paramNames };
|
|
9
|
+
}
|
|
10
|
+
/** Match a request path against a route and extract params */
|
|
11
|
+
function matchRoute(req, routes) {
|
|
12
|
+
for (const route of routes) {
|
|
13
|
+
if (route.method !== req.method)
|
|
14
|
+
continue;
|
|
15
|
+
const match = route.regex.exec(req.path);
|
|
16
|
+
if (!match)
|
|
17
|
+
continue;
|
|
18
|
+
const params = { ...req.params };
|
|
19
|
+
for (let i = 0; i < route.paramNames.length; i++) {
|
|
20
|
+
const name = route.paramNames[i];
|
|
21
|
+
const value = match[i + 1];
|
|
22
|
+
if (name && value) {
|
|
23
|
+
params[name] = value;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return { route, params };
|
|
27
|
+
}
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
export class ApiRouter {
|
|
31
|
+
routes = [];
|
|
32
|
+
/** Register a route */
|
|
33
|
+
add(method, pattern, handler) {
|
|
34
|
+
const { regex, paramNames } = compilePattern(pattern);
|
|
35
|
+
this.routes.push({ method, pattern, paramNames, regex, handler });
|
|
36
|
+
}
|
|
37
|
+
/** List all registered routes (for OpenAPI spec generation) */
|
|
38
|
+
listRoutes() {
|
|
39
|
+
return this.routes.map((r) => ({ method: r.method, pattern: r.pattern }));
|
|
40
|
+
}
|
|
41
|
+
/** Handle an incoming request */
|
|
42
|
+
async handle(req, ctx) {
|
|
43
|
+
const matched = matchRoute(req, this.routes);
|
|
44
|
+
if (!matched) {
|
|
45
|
+
return { status: 404, body: { error: `No handler for ${req.method} ${req.path}` } };
|
|
46
|
+
}
|
|
47
|
+
const enrichedReq = { ...req, params: matched.params };
|
|
48
|
+
return matched.route.handler(enrichedReq, ctx);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAUA,+EAA+E;AAC/E,SAAS,cAAc,CAAC,OAAe;IACrC,MAAM,UAAU,GAAa,EAAE,CAAA;IAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE;QACtD,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACrB,OAAO,SAAS,CAAA;IAClB,CAAC,CAAC,CAAA;IACF,OAAO,EAAE,KAAK,EAAE,IAAI,MAAM,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,UAAU,EAAE,CAAA;AAC3D,CAAC;AAED,8DAA8D;AAC9D,SAAS,UAAU,CACjB,GAAe,EACf,MAAwB;IAExB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM;YAAE,SAAQ;QACzC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACxC,IAAI,CAAC,KAAK;YAAE,SAAQ;QAEpB,MAAM,MAAM,GAA2B,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,CAAA;QACxD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACjD,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;YAChC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YAC1B,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;gBAClB,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;YACtB,CAAC;QACH,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;IAC1B,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,OAAO,SAAS;IACH,MAAM,GAAY,EAAE,CAAA;IAErC,uBAAuB;IACvB,GAAG,CAAC,MAAc,EAAE,OAAe,EAAE,OAAmB;QACtD,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QACrD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;IACnE,CAAC;IAED,+DAA+D;IAC/D,UAAU;QACR,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;IAC3E,CAAC;IAED,iCAAiC;IACjC,KAAK,CAAC,MAAM,CAAC,GAAe,EAAE,GAAe;QAC3C,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,kBAAkB,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,CAAA;QACrF,CAAC;QAED,MAAM,WAAW,GAAe,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAA;QAClE,OAAO,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAA;IAChD,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RuntimeFieldDefinition } from '@krantho/persistence';
|
|
2
|
+
/** Whether a value sent as an enum's values is a list of text */
|
|
3
|
+
export declare function isTextList(value: unknown): value is string[];
|
|
4
|
+
/**
|
|
5
|
+
* Why a runtime field definition cannot be saved, or null when it can. The
|
|
6
|
+
* merged schema is built from these definitions, so one that does not hold —
|
|
7
|
+
* a pattern that does not compile, an enum the schema would turn into plain
|
|
8
|
+
* text — would break every save in its collection.
|
|
9
|
+
*/
|
|
10
|
+
export declare function runtimeFieldError(field: RuntimeFieldDefinition, collections: ReadonlySet<string>): string | null;
|
|
11
|
+
//# sourceMappingURL=runtime-field-checks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-field-checks.d.ts","sourceRoot":"","sources":["../src/runtime-field-checks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAsBlE,iEAAiE;AACjE,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,EAAE,CAE5D;AAiCD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,sBAAsB,EAC7B,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAC/B,MAAM,GAAG,IAAI,CAWf"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/** A runtime field's name: a letter, then letters, digits, hyphens and underscores */
|
|
2
|
+
const FIELD_NAME = /^[a-z][a-z0-9_-]*$/i;
|
|
3
|
+
/** Why the default does not fit the field's type, or null */
|
|
4
|
+
function defaultError(field) {
|
|
5
|
+
const value = field.default;
|
|
6
|
+
if (value === undefined)
|
|
7
|
+
return null;
|
|
8
|
+
if (field.type === 'number') {
|
|
9
|
+
return typeof value === 'number' && Number.isFinite(value) ? null : 'The default is a number.';
|
|
10
|
+
}
|
|
11
|
+
if (field.type === 'boolean') {
|
|
12
|
+
return typeof value === 'boolean' ? null : 'The default is true or false.';
|
|
13
|
+
}
|
|
14
|
+
if (typeof value !== 'string')
|
|
15
|
+
return 'The default is text.';
|
|
16
|
+
if (field.type === 'enum' && !field.enumValues?.includes(value)) {
|
|
17
|
+
return 'The default is one of the values.';
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
/** Whether a value sent as an enum's values is a list of text */
|
|
22
|
+
export function isTextList(value) {
|
|
23
|
+
return Array.isArray(value) && value.every((item) => typeof item === 'string');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Why the enum's values do not hold, or null: the schema makes an enum of two
|
|
27
|
+
* different values or more, and with fewer the field would take any text
|
|
28
|
+
*/
|
|
29
|
+
function enumError({ type, enumValues }) {
|
|
30
|
+
if (type !== 'enum')
|
|
31
|
+
return null;
|
|
32
|
+
return new Set(enumValues).size < 2 ? 'An enum has two different values or more.' : null;
|
|
33
|
+
}
|
|
34
|
+
/** Why the bounds do not hold, or null */
|
|
35
|
+
function boundsError({ min, max }) {
|
|
36
|
+
if ([min, max].some((bound) => bound !== undefined && !Number.isFinite(bound))) {
|
|
37
|
+
return 'Minimum and maximum are numbers.';
|
|
38
|
+
}
|
|
39
|
+
if (min !== undefined && max !== undefined && min > max) {
|
|
40
|
+
return 'The minimum is not above the maximum.';
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
/** Why the pattern is not a regular expression, or null */
|
|
45
|
+
function patternError({ pattern }) {
|
|
46
|
+
if (pattern === undefined)
|
|
47
|
+
return null;
|
|
48
|
+
try {
|
|
49
|
+
new RegExp(pattern);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return 'The pattern is not a valid regular expression.';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Why a runtime field definition cannot be saved, or null when it can. The
|
|
58
|
+
* merged schema is built from these definitions, so one that does not hold —
|
|
59
|
+
* a pattern that does not compile, an enum the schema would turn into plain
|
|
60
|
+
* text — would break every save in its collection.
|
|
61
|
+
*/
|
|
62
|
+
export function runtimeFieldError(field, collections) {
|
|
63
|
+
if (!FIELD_NAME.test(field.name)) {
|
|
64
|
+
return 'A name starts with a letter and holds only letters, digits, hyphens and underscores.';
|
|
65
|
+
}
|
|
66
|
+
if (field.type === 'reference' &&
|
|
67
|
+
!(field.refCollection && collections.has(field.refCollection))) {
|
|
68
|
+
return 'A reference field names the collection it refers to.';
|
|
69
|
+
}
|
|
70
|
+
return enumError(field) ?? boundsError(field) ?? patternError(field) ?? defaultError(field);
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=runtime-field-checks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-field-checks.js","sourceRoot":"","sources":["../src/runtime-field-checks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { ContentChange } from '@krantho/core';
|
|
2
|
+
import { type ContentDocument, type DefaultProvenance } from '@krantho/persistence';
|
|
3
|
+
import { type Collection } from '@krantho/schema';
|
|
4
|
+
import type { ZodObject, ZodRawShape } from 'zod';
|
|
5
|
+
import type { ApiContext, ApiResponse } from './types.js';
|
|
6
|
+
/** One document save, as the REST create/update handlers and the assistant make it */
|
|
7
|
+
export interface SaveDocumentInput {
|
|
8
|
+
collection: string;
|
|
9
|
+
slug: string;
|
|
10
|
+
fields: Record<string, unknown>;
|
|
11
|
+
/** A string replaces the body; undefined keeps the current body (existing documents only) */
|
|
12
|
+
body: string | undefined;
|
|
13
|
+
locale: string | undefined;
|
|
14
|
+
isNew: boolean;
|
|
15
|
+
/** Reject with 409 when the current version differs */
|
|
16
|
+
expectedVersion?: number | undefined;
|
|
17
|
+
changedBy: string;
|
|
18
|
+
repositoryBasis?: ContentDocument['repositoryBasis'] | undefined;
|
|
19
|
+
metadata?: unknown;
|
|
20
|
+
defaults?: readonly DefaultProvenance[] | undefined;
|
|
21
|
+
}
|
|
22
|
+
/** A committed save: the document's version after it and its live version (null when nothing is live) */
|
|
23
|
+
export type SaveDocumentResult = {
|
|
24
|
+
ok: true;
|
|
25
|
+
slug: string;
|
|
26
|
+
version: number;
|
|
27
|
+
liveVersion: number | null;
|
|
28
|
+
} | {
|
|
29
|
+
ok: false;
|
|
30
|
+
response: ApiResponse;
|
|
31
|
+
};
|
|
32
|
+
type PreparedFields = {
|
|
33
|
+
ok: true;
|
|
34
|
+
fields: Record<string, unknown>;
|
|
35
|
+
} | {
|
|
36
|
+
ok: false;
|
|
37
|
+
response: ApiResponse;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Validate a document's values against the collection's active contract, as
|
|
41
|
+
* `saveDocument` does: a draft prepared ahead of its save (the assistant's)
|
|
42
|
+
* passes or fails exactly as the save will.
|
|
43
|
+
*/
|
|
44
|
+
export declare function prepareFields(ctx: ApiContext, collectionDef: Collection<ZodObject<ZodRawShape>>, values: {
|
|
45
|
+
fields: Record<string, unknown>;
|
|
46
|
+
body: string;
|
|
47
|
+
metadata: ContentDocument['metadata'];
|
|
48
|
+
}): Promise<PreparedFields>;
|
|
49
|
+
/**
|
|
50
|
+
* The change a committed save announces: visitors see it only when the saved
|
|
51
|
+
* version is live — never on an adapter with history, where a save keeps the
|
|
52
|
+
* live version; at once on one without (the filesystem adapter).
|
|
53
|
+
*/
|
|
54
|
+
export declare function savedChange(ctx: ApiContext, target: {
|
|
55
|
+
collection: string;
|
|
56
|
+
slug: string;
|
|
57
|
+
locale: string | undefined;
|
|
58
|
+
}): Promise<ContentChange & {
|
|
59
|
+
version: number;
|
|
60
|
+
liveVersion: number | null;
|
|
61
|
+
}>;
|
|
62
|
+
/**
|
|
63
|
+
* Save one document as a new version: role, collection, edit lock,
|
|
64
|
+
* concurrency, the before-save hook, the active contract, the write, then the
|
|
65
|
+
* webhook, the after-hook and the change announcement. A save never changes
|
|
66
|
+
* what visitors see — publishing does (`changePublication`). The single write
|
|
67
|
+
* path of the REST handlers and the assistant.
|
|
68
|
+
*/
|
|
69
|
+
export declare function saveDocument(ctx: ApiContext, input: SaveDocumentInput): Promise<SaveDocumentResult>;
|
|
70
|
+
export {};
|
|
71
|
+
//# sourceMappingURL=save-document.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save-document.d.ts","sourceRoot":"","sources":["../src/save-document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAClD,OAAO,EAEL,KAAK,eAAe,EAMpB,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,KAAK,UAAU,EAA6C,MAAM,iBAAiB,CAAA;AAC5F,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,KAAK,CAAA;AAMjD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAGzD,sFAAsF;AACtF,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,6FAA6F;IAC7F,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IACxB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,KAAK,EAAE,OAAO,CAAA;IACd,uDAAuD;IACvD,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,SAAS,EAAE,MAAM,CAAA;IACjB,eAAe,CAAC,EAAE,eAAe,CAAC,iBAAiB,CAAC,GAAG,SAAS,CAAA;IAChE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,SAAS,iBAAiB,EAAE,GAAG,SAAS,CAAA;CACpD;AAED,yGAAyG;AACzG,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACvE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,WAAW,CAAA;CAAE,CAAA;AAExC,KAAK,cAAc,GACf;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAC7C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,WAAW,CAAA;CAAE,CAAA;AAExC;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,UAAU,EACf,aAAa,EAAE,UAAU,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,EACjD,MAAM,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,CAAA;CAAE,GAC/F,OAAO,CAAC,cAAc,CAAC,CAYzB;AAmBD;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,UAAU,EACf,MAAM,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACvE,OAAO,CAAC,aAAa,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAe1E;AA2JD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,kBAAkB,CAAC,CA+B7B"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { ContentWriteConflict, canGetContent, canWriteContent, currentIsLive, } from '@krantho/persistence';
|
|
2
|
+
import { retainDefaultProvenance, validateDocument } from '@krantho/schema';
|
|
3
|
+
import { announceChange } from './content-change.js';
|
|
4
|
+
import { lockedByOther } from './content-locks.js';
|
|
5
|
+
import { runAfterHook, runBeforeSave } from './hooks.js';
|
|
6
|
+
import { getActiveContract } from './merged-schema.js';
|
|
7
|
+
import { requireRole } from './permissions.js';
|
|
8
|
+
import { formatZodErrors } from './validators.js';
|
|
9
|
+
/**
|
|
10
|
+
* Validate a document's values against the collection's active contract, as
|
|
11
|
+
* `saveDocument` does: a draft prepared ahead of its save (the assistant's)
|
|
12
|
+
* passes or fails exactly as the save will.
|
|
13
|
+
*/
|
|
14
|
+
export async function prepareFields(ctx, collectionDef, values) {
|
|
15
|
+
const contract = await getActiveContract(collectionDef, ctx.adapter);
|
|
16
|
+
const validation = validateDocument(contract, values);
|
|
17
|
+
if (!validation.success)
|
|
18
|
+
return {
|
|
19
|
+
ok: false,
|
|
20
|
+
response: {
|
|
21
|
+
status: 422,
|
|
22
|
+
body: { error: 'Validation failed', details: formatZodErrors(validation.error.issues) },
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
return { ok: true, fields: validation.data.fields };
|
|
26
|
+
}
|
|
27
|
+
/** Optimistic concurrency: 409 when the current version is not the expected one */
|
|
28
|
+
function versionConflict(input, current) {
|
|
29
|
+
if (input.expectedVersion === undefined)
|
|
30
|
+
return null;
|
|
31
|
+
if ((current?.meta.version ?? 0) === input.expectedVersion)
|
|
32
|
+
return null;
|
|
33
|
+
return {
|
|
34
|
+
status: 409,
|
|
35
|
+
body: {
|
|
36
|
+
error: 'Content has been modified by another user',
|
|
37
|
+
currentVersion: current?.meta.version ?? 0,
|
|
38
|
+
yourVersion: input.expectedVersion,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The change a committed save announces: visitors see it only when the saved
|
|
44
|
+
* version is live — never on an adapter with history, where a save keeps the
|
|
45
|
+
* live version; at once on one without (the filesystem adapter).
|
|
46
|
+
*/
|
|
47
|
+
export async function savedChange(ctx, target) {
|
|
48
|
+
const saved = canGetContent(ctx.adapter)
|
|
49
|
+
? await ctx.adapter.getContent(target.collection, target.slug, target.locale)
|
|
50
|
+
: null;
|
|
51
|
+
const version = saved?.meta.version ?? 0;
|
|
52
|
+
const liveVersion = saved?.meta.liveVersion ?? null;
|
|
53
|
+
return {
|
|
54
|
+
kind: 'document',
|
|
55
|
+
collection: target.collection,
|
|
56
|
+
slug: target.slug,
|
|
57
|
+
locale: target.locale,
|
|
58
|
+
live: currentIsLive({ version, liveVersion }),
|
|
59
|
+
version,
|
|
60
|
+
liveVersion,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** Write the prepared save as a new version: a save keeps the live version */
|
|
64
|
+
async function writeDocument(adapter, input, slug, fields, body, contract, metadata, current) {
|
|
65
|
+
await adapter.writeContent({
|
|
66
|
+
collection: input.collection,
|
|
67
|
+
slug,
|
|
68
|
+
fields,
|
|
69
|
+
body,
|
|
70
|
+
locale: input.locale,
|
|
71
|
+
contract,
|
|
72
|
+
metadata,
|
|
73
|
+
repositoryBasis: input.repositoryBasis ?? current?.repositoryBasis ?? null,
|
|
74
|
+
defaults: retainDefaultProvenance(input.defaults ?? current?.defaults ?? [], metadata),
|
|
75
|
+
expectedVersion: input.isNew ? 0 : (input.expectedVersion ?? current?.meta.version),
|
|
76
|
+
}, input.changedBy);
|
|
77
|
+
}
|
|
78
|
+
/** Webhook, after-hook and change announcement of a committed save */
|
|
79
|
+
async function afterSave(ctx, input, slug) {
|
|
80
|
+
const { collection, locale } = input;
|
|
81
|
+
ctx.fireWebhook?.(input.isNew ? 'create' : 'update', collection, slug);
|
|
82
|
+
const hook = input.isNew ? ctx.contentHooks?.afterCreate : ctx.contentHooks?.afterUpdate;
|
|
83
|
+
await runAfterHook(hook, { collection, slug });
|
|
84
|
+
const { version, liveVersion, ...change } = await savedChange(ctx, { collection, slug, locale });
|
|
85
|
+
await announceChange(ctx, change);
|
|
86
|
+
return { version, liveVersion };
|
|
87
|
+
}
|
|
88
|
+
/** The document as it stands before a save, or null for a new one */
|
|
89
|
+
async function currentDocument(ctx, input) {
|
|
90
|
+
if (input.isNew || !canGetContent(ctx.adapter))
|
|
91
|
+
return null;
|
|
92
|
+
const current = await ctx.adapter.getContent(input.collection, input.slug, input.locale);
|
|
93
|
+
const locale = input.locale ?? ctx.config.site.defaultLocale;
|
|
94
|
+
return current?.meta.locale === locale ? current : null;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* 409 when a create names a document that already exists: a create never
|
|
98
|
+
* writes over one, so another user's lock and version are never passed by.
|
|
99
|
+
* Read where the write would land — the same collection, slug and locale.
|
|
100
|
+
* This early check provides a readable error; the adapter atomically rejects
|
|
101
|
+
* a concurrent create through expectedVersion zero.
|
|
102
|
+
*/
|
|
103
|
+
async function alreadyExists(ctx, input, slug) {
|
|
104
|
+
if (!canGetContent(ctx.adapter))
|
|
105
|
+
return null;
|
|
106
|
+
const existing = await ctx.adapter.getContent(input.collection, slug, input.locale);
|
|
107
|
+
if (!existing || existing.meta.locale !== (input.locale ?? ctx.config.site.defaultLocale))
|
|
108
|
+
return null;
|
|
109
|
+
const error = `"${input.collection}/${slug}" already exists. Open it and save it instead.`;
|
|
110
|
+
return { status: 409, body: { error } };
|
|
111
|
+
}
|
|
112
|
+
const fail = (status, error) => ({
|
|
113
|
+
ok: false,
|
|
114
|
+
response: { status, body: { error } },
|
|
115
|
+
});
|
|
116
|
+
/** Role, collection, adapter, edit lock, version and existence, checked before anything runs */
|
|
117
|
+
async function admitSave(ctx, input) {
|
|
118
|
+
const denied = requireRole(ctx.auth, 'editor');
|
|
119
|
+
if (denied)
|
|
120
|
+
return { ok: false, response: denied };
|
|
121
|
+
const collectionDef = ctx.contentConfig.collections.get(input.collection);
|
|
122
|
+
if (!collectionDef)
|
|
123
|
+
return fail(404, `Collection "${input.collection}" not found`);
|
|
124
|
+
if (!canWriteContent(ctx.adapter))
|
|
125
|
+
return fail(501, 'Adapter does not support writeContent');
|
|
126
|
+
// Locks are checked when the request arrives; a lock taken after this point
|
|
127
|
+
// does not stop the write, and `expectedVersion` still catches the conflict
|
|
128
|
+
const locked = input.isNew ? null : await lockedByOther(ctx, input);
|
|
129
|
+
if (locked)
|
|
130
|
+
return { ok: false, response: locked };
|
|
131
|
+
const current = await currentDocument(ctx, input);
|
|
132
|
+
const conflict = versionConflict(input, current);
|
|
133
|
+
if (conflict)
|
|
134
|
+
return { ok: false, response: conflict };
|
|
135
|
+
if (!input.isNew && input.body === undefined && !canGetContent(ctx.adapter))
|
|
136
|
+
return fail(501, 'Adapter cannot read a document, so a save must send its body');
|
|
137
|
+
if (!input.isNew && canGetContent(ctx.adapter) && !current)
|
|
138
|
+
return fail(404, `Content "${input.collection}/${input.slug}" not found`);
|
|
139
|
+
return { ok: true, value: { collectionDef, writer: ctx.adapter, current } };
|
|
140
|
+
}
|
|
141
|
+
/** Metadata as the request sends it: an object of groups, each an object of properties */
|
|
142
|
+
function isMetadata(value) {
|
|
143
|
+
const isRecord = (entry) => entry !== null && typeof entry === 'object' && !Array.isArray(entry);
|
|
144
|
+
return isRecord(value) && Object.values(value).every(isRecord);
|
|
145
|
+
}
|
|
146
|
+
/** The before-save hook's view of the save: a save without a body merges the fields it names */
|
|
147
|
+
function hookInput(input, metadata, current) {
|
|
148
|
+
return {
|
|
149
|
+
collection: input.collection,
|
|
150
|
+
slug: input.slug,
|
|
151
|
+
fields: input.body === undefined && current ? { ...current.fields, ...input.fields } : input.fields,
|
|
152
|
+
body: input.body ?? current?.body ?? '',
|
|
153
|
+
metadata,
|
|
154
|
+
isNew: input.isNew,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/** The adapter's conflict as the 409 a client reloads on */
|
|
158
|
+
function writeConflict(error) {
|
|
159
|
+
return {
|
|
160
|
+
ok: false,
|
|
161
|
+
response: {
|
|
162
|
+
status: 409,
|
|
163
|
+
body: {
|
|
164
|
+
error: error.message,
|
|
165
|
+
currentVersion: error.currentVersion,
|
|
166
|
+
yourVersion: error.expectedVersion,
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Save one document as a new version: role, collection, edit lock,
|
|
173
|
+
* concurrency, the before-save hook, the active contract, the write, then the
|
|
174
|
+
* webhook, the after-hook and the change announcement. A save never changes
|
|
175
|
+
* what visitors see — publishing does (`changePublication`). The single write
|
|
176
|
+
* path of the REST handlers and the assistant.
|
|
177
|
+
*/
|
|
178
|
+
export async function saveDocument(ctx, input) {
|
|
179
|
+
const admitted = await admitSave(ctx, input);
|
|
180
|
+
if (!admitted.ok)
|
|
181
|
+
return admitted;
|
|
182
|
+
const { collectionDef, writer, current } = admitted.value;
|
|
183
|
+
// The hook sees metadata of the right shape; the contract checks its groups after it
|
|
184
|
+
const sent = input.metadata === undefined ? (current?.metadata ?? {}) : input.metadata;
|
|
185
|
+
if (!isMetadata(sent))
|
|
186
|
+
return fail(422, 'Metadata must be an object of named groups');
|
|
187
|
+
const hooked = await runBeforeSave(ctx.contentHooks, hookInput(input, sent, current));
|
|
188
|
+
const slug = input.isNew ? hooked.slug : input.slug;
|
|
189
|
+
const exists = input.isNew ? await alreadyExists(ctx, input, slug) : null;
|
|
190
|
+
if (exists)
|
|
191
|
+
return { ok: false, response: exists };
|
|
192
|
+
const contract = await getActiveContract(collectionDef, ctx.adapter);
|
|
193
|
+
const parsed = validateDocument(contract, {
|
|
194
|
+
fields: hooked.fields,
|
|
195
|
+
body: hooked.body,
|
|
196
|
+
metadata: hooked.metadata,
|
|
197
|
+
});
|
|
198
|
+
if (!parsed.success) {
|
|
199
|
+
const details = formatZodErrors(parsed.error.issues);
|
|
200
|
+
return { ok: false, response: { status: 422, body: { error: 'Validation failed', details } } };
|
|
201
|
+
}
|
|
202
|
+
const { fields, body, metadata } = parsed.data;
|
|
203
|
+
try {
|
|
204
|
+
await writeDocument(writer, input, slug, fields, body, contract, metadata, current);
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
if (error instanceof ContentWriteConflict)
|
|
208
|
+
return writeConflict(error);
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
return { ok: true, slug, ...(await afterSave(ctx, input, slug)) };
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=save-document.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save-document.js","sourceRoot":"","sources":["../src/save-document.ts"],"names":[],"mappings":"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"}
|