@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
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import type { AuthMode, KranthoConfig, WebhookTarget } from '@krantho/config';
|
|
2
|
+
import type { IContentEngine } from '@krantho/core';
|
|
3
|
+
import type { ContentDocument, IAuthAdapter, IPersistenceAdapter, Role } from '@krantho/persistence';
|
|
4
|
+
import type { ContentConfig, PageDefinition } from '@krantho/schema';
|
|
5
|
+
/** Framework-agnostic HTTP request */
|
|
6
|
+
export interface ApiRequest {
|
|
7
|
+
method: string;
|
|
8
|
+
path: string;
|
|
9
|
+
params: Record<string, string>;
|
|
10
|
+
query: Record<string, string>;
|
|
11
|
+
body?: unknown | undefined;
|
|
12
|
+
headers?: Record<string, string> | undefined;
|
|
13
|
+
rawRequest?: Request | undefined;
|
|
14
|
+
files?: Array<{
|
|
15
|
+
name: string;
|
|
16
|
+
data: Uint8Array;
|
|
17
|
+
filename: string;
|
|
18
|
+
mimeType: string;
|
|
19
|
+
}> | undefined;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* How the host shows an editor a draft on the site: `draft-mode` — the host
|
|
23
|
+
* turns the API's answer into its own preview mode (Next.js draft mode);
|
|
24
|
+
* `signed-url` — the API sends the editor to the page with a short-lived
|
|
25
|
+
* signed token the page's server verifies
|
|
26
|
+
*/
|
|
27
|
+
export type SitePreviewMode = 'draft-mode' | 'signed-url';
|
|
28
|
+
/** The server package hosting the API: `@krantho/server-next`, `-sveltekit` or `-node` */
|
|
29
|
+
export type ServerFramework = 'next' | 'sveltekit' | 'node';
|
|
30
|
+
/** Framework-agnostic HTTP response */
|
|
31
|
+
export interface ApiResponse {
|
|
32
|
+
status: number;
|
|
33
|
+
/** JSON by default; a string or bytes as is; a `ReadableStream<Uint8Array>` is streamed to the client as is */
|
|
34
|
+
body: unknown;
|
|
35
|
+
headers?: Record<string, string> | undefined;
|
|
36
|
+
/** Set-Cookie values — one per cookie, emitted as separate header lines (RFC 6265). */
|
|
37
|
+
cookies?: readonly string[] | undefined;
|
|
38
|
+
}
|
|
39
|
+
/** Handler function signature */
|
|
40
|
+
export type ApiHandler = (req: ApiRequest, ctx: ApiContext) => Promise<ApiResponse>;
|
|
41
|
+
/** Webhook configuration: the `webhooks` entries of the configuration tree, or wiring passed to `createApiHandlers` */
|
|
42
|
+
export type WebhookConfig = WebhookTarget;
|
|
43
|
+
/** Shared context passed to all handlers */
|
|
44
|
+
export interface ApiContext {
|
|
45
|
+
contentConfig: ContentConfig;
|
|
46
|
+
/** The resolved configuration tree — the only place a handler reads settings from */
|
|
47
|
+
config: KranthoConfig;
|
|
48
|
+
adapter: IPersistenceAdapter;
|
|
49
|
+
engine: IContentEngine;
|
|
50
|
+
auth?: AuthenticatedUser | undefined;
|
|
51
|
+
pages?: readonly PageDefinition[] | undefined;
|
|
52
|
+
/** Fire webhook callback after content mutations */
|
|
53
|
+
fireWebhook?: ((event: string, collection: string, slug: string) => void) | undefined;
|
|
54
|
+
/** The configured webhooks: a retried delivery is sent to the one with its URL, signed with its secret */
|
|
55
|
+
webhooks?: readonly WebhookConfig[] | undefined;
|
|
56
|
+
/** Lifecycle hooks */
|
|
57
|
+
contentHooks?: import('./hooks.js').ContentHooks | undefined;
|
|
58
|
+
/** Told about every committed write (see `announceChange`) */
|
|
59
|
+
changeListeners?: readonly import('@krantho/core').ContentChangeListener[] | undefined;
|
|
60
|
+
/** Keeps a background job running until it settles (see `CreateApiHandlersConfig.waitUntil`) */
|
|
61
|
+
waitUntil?: ((work: Promise<unknown>) => void) | undefined;
|
|
62
|
+
/** Media storage adapter */
|
|
63
|
+
mediaStorage?: import('@krantho/persistence').IMediaStorage | undefined;
|
|
64
|
+
/** Media folder storage adapter */
|
|
65
|
+
mediaFolderStorage?: import('@krantho/persistence').IMediaFolderStorage | undefined;
|
|
66
|
+
/** The file store's display name (e.g. 'Local disk', 'Vercel Blob') */
|
|
67
|
+
mediaStorageLabel?: string | undefined;
|
|
68
|
+
/** The file store's directory or bucket, when it has one */
|
|
69
|
+
mediaStoragePath?: string | undefined;
|
|
70
|
+
/** Image optimizer instance */
|
|
71
|
+
imageOptimizer?: import('./image-optimizer.js').ImageOptimizer | undefined;
|
|
72
|
+
/** Image variant cache */
|
|
73
|
+
imageCache?: import('./image-cache.js').ImageCache | undefined;
|
|
74
|
+
/** Checkpoint adapter for backup/restore operations */
|
|
75
|
+
checkpointAdapter?: import('@krantho/persistence').ICheckpointAdapter | undefined;
|
|
76
|
+
/** Current schema version from migration runner */
|
|
77
|
+
schemaVersion?: number | undefined;
|
|
78
|
+
/** Persistence adapter type */
|
|
79
|
+
persistenceType?: 'filesystem' | 'sqlite' | 'postgres' | undefined;
|
|
80
|
+
/** How the host renders drafts for editors on the site (see `CreateApiHandlersConfig.sitePreview`) */
|
|
81
|
+
sitePreview?: SitePreviewMode | undefined;
|
|
82
|
+
/** The server package hosting the API (see `CreateApiHandlersConfig.framework`) */
|
|
83
|
+
framework?: ServerFramework | undefined;
|
|
84
|
+
/** Content migration adapter for conflict resolution */
|
|
85
|
+
contentMigrationAdapter?: import('@krantho/persistence').IContentMigrationAdapter | undefined;
|
|
86
|
+
/** Auth adapter for user/token operations */
|
|
87
|
+
authAdapter?: IAuthAdapter | undefined;
|
|
88
|
+
/** Advisory lock adapter */
|
|
89
|
+
lockAdapter?: import('@krantho/persistence').ILockAdapter | undefined;
|
|
90
|
+
/** Webhook delivery log adapter */
|
|
91
|
+
webhookDeliveryAdapter?: import('@krantho/persistence').IWebhookDeliveryAdapter | undefined;
|
|
92
|
+
/** Version retention adapter */
|
|
93
|
+
retentionAdapter?: import('@krantho/persistence').IRetentionAdapter | undefined;
|
|
94
|
+
/** Site settings adapter */
|
|
95
|
+
siteSettingsAdapter?: import('@krantho/persistence').ISiteSettingsAdapter | undefined;
|
|
96
|
+
/** Vault that seals the secrets stored in site settings; none means a site stores none */
|
|
97
|
+
secrets?: import('@krantho/persistence').ISecretVault | undefined;
|
|
98
|
+
/** SEO configuration adapter */
|
|
99
|
+
seoConfigAdapter?: import('@krantho/persistence').ISeoConfigAdapter | undefined;
|
|
100
|
+
/** The page cache the site's instances share, when `cache.shared` is `database` */
|
|
101
|
+
pageCacheStore?: import('@krantho/persistence').IPageCacheStore | undefined;
|
|
102
|
+
}
|
|
103
|
+
/** Authenticated user attached to request context */
|
|
104
|
+
export interface AuthenticatedUser {
|
|
105
|
+
id: string;
|
|
106
|
+
email: string;
|
|
107
|
+
name: string;
|
|
108
|
+
roles: Role[];
|
|
109
|
+
mode: AuthMode;
|
|
110
|
+
}
|
|
111
|
+
/** Content item response shape — mirrors ContentDocument from persistence */
|
|
112
|
+
export type ContentItemResponse = ContentDocument;
|
|
113
|
+
/** Error response shape */
|
|
114
|
+
export interface ErrorResponse {
|
|
115
|
+
error: string;
|
|
116
|
+
details?: unknown | undefined;
|
|
117
|
+
}
|
|
118
|
+
/** Media wiring: metadata and folders from the persistence, bytes from the file store */
|
|
119
|
+
export interface MediaConfig {
|
|
120
|
+
metadata: import('@krantho/persistence').IMediaMetadataAdapter;
|
|
121
|
+
folders: import('@krantho/persistence').IMediaFolderStorage;
|
|
122
|
+
files: import('@krantho/persistence').IFileStore;
|
|
123
|
+
}
|
|
124
|
+
/** Check if adapter supports version history (append-only adapters do) */
|
|
125
|
+
export declare function hasVersioning(adapter: unknown): boolean;
|
|
126
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAkIA,0EAA0E;AAC1E,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,MAAM,CAAC,GAAG,OAAkC,CAAA;IAC5C,OAAO,OAAO,CAAC,CAAC,cAAc,CAAC,KAAK,UAAU,IAAI,OAAO,CAAC,CAAC,YAAY,CAAC,KAAK,UAAU,CAAA;AACzF,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { MediaCrop, MediaHotspot } from '@krantho/persistence';
|
|
2
|
+
import type { Collection } from '@krantho/schema';
|
|
3
|
+
import type { ZodObject, ZodRawShape } from 'zod';
|
|
4
|
+
import type { ApiContext, ApiResponse } from './types.js';
|
|
5
|
+
/** Type-safe inclusion check for const arrays — avoids `as readonly string[]` casts. */
|
|
6
|
+
export declare function isOneOf<T extends string>(arr: readonly T[], value: string): value is T;
|
|
7
|
+
/** Validate that a collection exists in the content config */
|
|
8
|
+
export declare function validateCollectionParam(collection: string | undefined, ctx: ApiContext): {
|
|
9
|
+
isValid: true;
|
|
10
|
+
collection: string;
|
|
11
|
+
collectionDef: Collection<ZodObject<ZodRawShape>>;
|
|
12
|
+
} | {
|
|
13
|
+
isValid: false;
|
|
14
|
+
response: ApiResponse;
|
|
15
|
+
};
|
|
16
|
+
/** Validate request body is a non-null object */
|
|
17
|
+
export declare function validateRequestBody(body: unknown): {
|
|
18
|
+
isValid: true;
|
|
19
|
+
body: Record<string, unknown>;
|
|
20
|
+
} | {
|
|
21
|
+
isValid: false;
|
|
22
|
+
response: ApiResponse;
|
|
23
|
+
};
|
|
24
|
+
/** Parse and validate a status query parameter: draft, published or archived */
|
|
25
|
+
export declare function parseStatusParam(value: string | undefined): 'draft' | 'published' | 'archived' | undefined;
|
|
26
|
+
/** Parse and validate a positive integer query parameter */
|
|
27
|
+
export declare function parsePositiveInt(value: string | undefined): number | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Apply the configured page-size cap to a requested list limit.
|
|
30
|
+
*
|
|
31
|
+
* `content.list.maxLimit` is unset by default, and an unset cap means a list
|
|
32
|
+
* without a `limit` parameter returns every row — the behaviour the API has
|
|
33
|
+
* always had. Setting it both caps an oversized request and imposes a page size
|
|
34
|
+
* on a request that asked for none. A negative or NaN request counts as no
|
|
35
|
+
* request, so it can never slip past the cap (SQLite reads `LIMIT -1` as
|
|
36
|
+
* unbounded).
|
|
37
|
+
*/
|
|
38
|
+
export declare function applyListLimit(requested: number | undefined, maxLimit: number | undefined): number | undefined;
|
|
39
|
+
/** Parse and validate a locale query parameter */
|
|
40
|
+
export declare function parseLocaleParam(value: string | undefined): string | undefined;
|
|
41
|
+
/** Validate that a named route parameter exists */
|
|
42
|
+
export declare function requireParam(params: Record<string, string> | undefined, name: string): {
|
|
43
|
+
isValid: true;
|
|
44
|
+
value: string;
|
|
45
|
+
} | {
|
|
46
|
+
isValid: false;
|
|
47
|
+
response: ApiResponse;
|
|
48
|
+
};
|
|
49
|
+
/** Validate that a slug parameter exists */
|
|
50
|
+
export declare function validateSlugParam(slug: string | undefined): {
|
|
51
|
+
isValid: true;
|
|
52
|
+
slug: string;
|
|
53
|
+
} | {
|
|
54
|
+
isValid: false;
|
|
55
|
+
response: ApiResponse;
|
|
56
|
+
};
|
|
57
|
+
/** Parse a named cookie from a cookie header string */
|
|
58
|
+
export declare function parseCookie(cookieHeader: string | undefined, name: string): string | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Validate a crop region. Crop must fit entirely within the image (x + w <= 100).
|
|
61
|
+
*/
|
|
62
|
+
export declare function validateCrop(crop: unknown): {
|
|
63
|
+
isValid: true;
|
|
64
|
+
crop: MediaCrop;
|
|
65
|
+
} | {
|
|
66
|
+
isValid: false;
|
|
67
|
+
error: string;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Validate a hotspot center + ellipse. Unlike crop, hotspot can overflow image bounds
|
|
71
|
+
* because it represents a center of interest, not a hard crop boundary. The image
|
|
72
|
+
* optimizer clamps the computed crop region to image bounds at serve time.
|
|
73
|
+
* Width/height are stored for UI rendering (ellipse visualization) — only center (x, y)
|
|
74
|
+
* is used by the image optimizer for crop positioning.
|
|
75
|
+
*/
|
|
76
|
+
export declare function validateHotspot(hotspot: unknown): {
|
|
77
|
+
isValid: true;
|
|
78
|
+
hotspot: MediaHotspot;
|
|
79
|
+
} | {
|
|
80
|
+
isValid: false;
|
|
81
|
+
error: string;
|
|
82
|
+
};
|
|
83
|
+
/** Parse and validate a checkpoint version from route params */
|
|
84
|
+
export declare function parseCheckpointVersion(params: Record<string, string> | undefined): {
|
|
85
|
+
isValid: true;
|
|
86
|
+
version: number;
|
|
87
|
+
} | {
|
|
88
|
+
isValid: false;
|
|
89
|
+
response: ApiResponse;
|
|
90
|
+
};
|
|
91
|
+
/** Type predicate: narrows ctx to have non-undefined mediaStorage */
|
|
92
|
+
export declare function hasMediaStorage(ctx: ApiContext): ctx is ApiContext & {
|
|
93
|
+
mediaStorage: NonNullable<ApiContext['mediaStorage']>;
|
|
94
|
+
};
|
|
95
|
+
/** 501 response for missing media storage */
|
|
96
|
+
export declare const MEDIA_NOT_CONFIGURED: ApiResponse;
|
|
97
|
+
/** Format Zod validation errors into API response details */
|
|
98
|
+
export declare function formatZodErrors(issues: ReadonlyArray<{
|
|
99
|
+
path: PropertyKey[];
|
|
100
|
+
message: string;
|
|
101
|
+
code?: string;
|
|
102
|
+
keys?: readonly string[];
|
|
103
|
+
}>): Array<{
|
|
104
|
+
field: string;
|
|
105
|
+
message: string;
|
|
106
|
+
}>;
|
|
107
|
+
//# sourceMappingURL=validators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../src/validators.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
const VALID_STATUSES = ['draft', 'published', 'archived'];
|
|
2
|
+
/** Type-safe inclusion check for const arrays — avoids `as readonly string[]` casts. */
|
|
3
|
+
export function isOneOf(arr, value) {
|
|
4
|
+
return arr.includes(value);
|
|
5
|
+
}
|
|
6
|
+
/** Validate that a collection exists in the content config */
|
|
7
|
+
export function validateCollectionParam(collection, ctx) {
|
|
8
|
+
if (!collection) {
|
|
9
|
+
return {
|
|
10
|
+
isValid: false,
|
|
11
|
+
response: { status: 400, body: { error: 'Missing collection parameter' } },
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const collectionDef = ctx.contentConfig.collections.get(collection);
|
|
15
|
+
if (!collectionDef) {
|
|
16
|
+
return {
|
|
17
|
+
isValid: false,
|
|
18
|
+
response: { status: 404, body: { error: `Collection "${collection}" not found` } },
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return { isValid: true, collection, collectionDef };
|
|
22
|
+
}
|
|
23
|
+
/** Validate request body is a non-null object */
|
|
24
|
+
export function validateRequestBody(body) {
|
|
25
|
+
if (!body || typeof body !== 'object' || Array.isArray(body)) {
|
|
26
|
+
return {
|
|
27
|
+
isValid: false,
|
|
28
|
+
response: { status: 400, body: { error: 'Request body must be a JSON object' } },
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return { isValid: true, body: body };
|
|
32
|
+
}
|
|
33
|
+
/** Parse and validate a status query parameter: draft, published or archived */
|
|
34
|
+
export function parseStatusParam(value) {
|
|
35
|
+
if (!value)
|
|
36
|
+
return undefined;
|
|
37
|
+
if (value === 'draft' || value === 'published' || value === 'archived') {
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
/** Parse and validate a positive integer query parameter */
|
|
43
|
+
export function parsePositiveInt(value) {
|
|
44
|
+
if (!value)
|
|
45
|
+
return undefined;
|
|
46
|
+
const parsed = parseInt(value, 10);
|
|
47
|
+
if (isNaN(parsed) || parsed < 0)
|
|
48
|
+
return undefined;
|
|
49
|
+
return parsed;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Apply the configured page-size cap to a requested list limit.
|
|
53
|
+
*
|
|
54
|
+
* `content.list.maxLimit` is unset by default, and an unset cap means a list
|
|
55
|
+
* without a `limit` parameter returns every row — the behaviour the API has
|
|
56
|
+
* always had. Setting it both caps an oversized request and imposes a page size
|
|
57
|
+
* on a request that asked for none. A negative or NaN request counts as no
|
|
58
|
+
* request, so it can never slip past the cap (SQLite reads `LIMIT -1` as
|
|
59
|
+
* unbounded).
|
|
60
|
+
*/
|
|
61
|
+
export function applyListLimit(requested, maxLimit) {
|
|
62
|
+
const wanted = requested !== undefined && requested >= 0 ? requested : undefined;
|
|
63
|
+
if (maxLimit === undefined)
|
|
64
|
+
return wanted;
|
|
65
|
+
if (wanted === undefined)
|
|
66
|
+
return maxLimit;
|
|
67
|
+
return Math.min(wanted, maxLimit);
|
|
68
|
+
}
|
|
69
|
+
/** Parse and validate a locale query parameter */
|
|
70
|
+
export function parseLocaleParam(value) {
|
|
71
|
+
if (!value)
|
|
72
|
+
return undefined;
|
|
73
|
+
// Locale must be 2-5 char alphanumeric with optional hyphen (e.g., en, en-US, nb-NO)
|
|
74
|
+
if (/^[a-z]{2}(-[A-Za-z]{2,3})?$/.test(value))
|
|
75
|
+
return value;
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
/** Validate that a named route parameter exists */
|
|
79
|
+
export function requireParam(params, name) {
|
|
80
|
+
const value = params?.[name];
|
|
81
|
+
if (!value) {
|
|
82
|
+
return {
|
|
83
|
+
isValid: false,
|
|
84
|
+
response: { status: 400, body: { error: `Missing parameter: ${name}` } },
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return { isValid: true, value };
|
|
88
|
+
}
|
|
89
|
+
/** Validate that a slug parameter exists */
|
|
90
|
+
export function validateSlugParam(slug) {
|
|
91
|
+
if (!slug) {
|
|
92
|
+
return { isValid: false, response: { status: 400, body: { error: 'Missing parameter: slug' } } };
|
|
93
|
+
}
|
|
94
|
+
return { isValid: true, slug };
|
|
95
|
+
}
|
|
96
|
+
/** Parse a named cookie from a cookie header string */
|
|
97
|
+
export function parseCookie(cookieHeader, name) {
|
|
98
|
+
if (!cookieHeader)
|
|
99
|
+
return undefined;
|
|
100
|
+
const match = cookieHeader.split(';').find((c) => c.trim().startsWith(`${name}=`));
|
|
101
|
+
return match ? match.split('=')[1]?.trim() : undefined;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Validate a crop region. Crop must fit entirely within the image (x + w <= 100).
|
|
105
|
+
*/
|
|
106
|
+
export function validateCrop(crop) {
|
|
107
|
+
if (typeof crop !== 'object' || crop === null) {
|
|
108
|
+
return { isValid: false, error: 'Crop must be an object' };
|
|
109
|
+
}
|
|
110
|
+
const c = crop;
|
|
111
|
+
const x = typeof c['x'] === 'number' ? c['x'] : NaN;
|
|
112
|
+
const y = typeof c['y'] === 'number' ? c['y'] : NaN;
|
|
113
|
+
const w = typeof c['width'] === 'number' ? c['width'] : NaN;
|
|
114
|
+
const h = typeof c['height'] === 'number' ? c['height'] : NaN;
|
|
115
|
+
if (Number.isNaN(x) ||
|
|
116
|
+
Number.isNaN(y) ||
|
|
117
|
+
Number.isNaN(w) ||
|
|
118
|
+
Number.isNaN(h) ||
|
|
119
|
+
x < 0 ||
|
|
120
|
+
y < 0 ||
|
|
121
|
+
w <= 0 ||
|
|
122
|
+
h <= 0 ||
|
|
123
|
+
x + w > 100 ||
|
|
124
|
+
y + h > 100) {
|
|
125
|
+
return {
|
|
126
|
+
isValid: false,
|
|
127
|
+
error: 'Invalid crop: x, y, width, height must be numbers 0-100 with width/height > 0',
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return { isValid: true, crop: { x, y, width: w, height: h } };
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Validate a hotspot center + ellipse. Unlike crop, hotspot can overflow image bounds
|
|
134
|
+
* because it represents a center of interest, not a hard crop boundary. The image
|
|
135
|
+
* optimizer clamps the computed crop region to image bounds at serve time.
|
|
136
|
+
* Width/height are stored for UI rendering (ellipse visualization) — only center (x, y)
|
|
137
|
+
* is used by the image optimizer for crop positioning.
|
|
138
|
+
*/
|
|
139
|
+
export function validateHotspot(hotspot) {
|
|
140
|
+
if (typeof hotspot !== 'object' || hotspot === null) {
|
|
141
|
+
return { isValid: false, error: 'Hotspot must be an object' };
|
|
142
|
+
}
|
|
143
|
+
const h = hotspot;
|
|
144
|
+
const x = typeof h['x'] === 'number' ? h['x'] : NaN;
|
|
145
|
+
const y = typeof h['y'] === 'number' ? h['y'] : NaN;
|
|
146
|
+
const w = typeof h['width'] === 'number' ? h['width'] : NaN;
|
|
147
|
+
const ht = typeof h['height'] === 'number' ? h['height'] : NaN;
|
|
148
|
+
if (Number.isNaN(x) ||
|
|
149
|
+
Number.isNaN(y) ||
|
|
150
|
+
Number.isNaN(w) ||
|
|
151
|
+
Number.isNaN(ht) ||
|
|
152
|
+
x < 0 ||
|
|
153
|
+
y < 0 ||
|
|
154
|
+
w <= 0 ||
|
|
155
|
+
ht <= 0 ||
|
|
156
|
+
x > 100 ||
|
|
157
|
+
y > 100 ||
|
|
158
|
+
w > 100 ||
|
|
159
|
+
ht > 100) {
|
|
160
|
+
return {
|
|
161
|
+
isValid: false,
|
|
162
|
+
error: 'Invalid hotspot: x, y, width, height must be numbers 0-100 with width/height > 0',
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
return { isValid: true, hotspot: { x, y, width: w, height: ht } };
|
|
166
|
+
}
|
|
167
|
+
/** Parse and validate a checkpoint version from route params */
|
|
168
|
+
export function parseCheckpointVersion(params) {
|
|
169
|
+
const result = requireParam(params, 'version');
|
|
170
|
+
if (!result.isValid)
|
|
171
|
+
return result;
|
|
172
|
+
const version = parseInt(result.value, 10);
|
|
173
|
+
if (Number.isNaN(version)) {
|
|
174
|
+
return { isValid: false, response: { status: 400, body: { error: 'Invalid version number' } } };
|
|
175
|
+
}
|
|
176
|
+
return { isValid: true, version };
|
|
177
|
+
}
|
|
178
|
+
/** Type predicate: narrows ctx to have non-undefined mediaStorage */
|
|
179
|
+
export function hasMediaStorage(ctx) {
|
|
180
|
+
return ctx.mediaStorage !== undefined;
|
|
181
|
+
}
|
|
182
|
+
/** 501 response for missing media storage */
|
|
183
|
+
export const MEDIA_NOT_CONFIGURED = {
|
|
184
|
+
status: 501,
|
|
185
|
+
body: { error: 'Media storage not configured' },
|
|
186
|
+
};
|
|
187
|
+
/** Format Zod validation errors into API response details */
|
|
188
|
+
export function formatZodErrors(issues) {
|
|
189
|
+
return issues.flatMap((issue) => {
|
|
190
|
+
const paths = issue.code === 'unrecognized_keys' && issue.keys?.length
|
|
191
|
+
? issue.keys.map((key) => [...issue.path, key])
|
|
192
|
+
: [issue.path];
|
|
193
|
+
return paths.map((path) => ({
|
|
194
|
+
field: path.map(String).join('.') || '(root)',
|
|
195
|
+
message: issue.message,
|
|
196
|
+
}));
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=validators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../src/validators.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { WebhookEvent } from '@krantho/config';
|
|
2
|
+
import { type IWebhookDeliveryAdapter } from '@krantho/persistence';
|
|
3
|
+
import type { WebhookConfig } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Fire webhooks for a content event.
|
|
6
|
+
*
|
|
7
|
+
* With a delivery adapter, deliveries are logged and failed deliveries are
|
|
8
|
+
* retried with backoff. Without one, falls back to fire-and-forget.
|
|
9
|
+
*/
|
|
10
|
+
export declare function fireWebhooks(webhooks: readonly WebhookConfig[], event: WebhookEvent, collection: string, slug: string, deliveries?: IWebhookDeliveryAdapter): void;
|
|
11
|
+
/** A stored delivery to send again: its row, its event, the payload it carried and the attempts made */
|
|
12
|
+
export interface Redelivery {
|
|
13
|
+
id: number;
|
|
14
|
+
event: string;
|
|
15
|
+
payload: string;
|
|
16
|
+
attempts: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Send a stored delivery to its webhook once more, now, signed afresh with
|
|
20
|
+
* the hook's secret; the row records how it went. Resolves when it has.
|
|
21
|
+
*/
|
|
22
|
+
export declare function redeliverWebhook(hook: WebhookConfig, delivery: Redelivery, deliveries: IWebhookDeliveryAdapter): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Send the deliveries that are due again: failed ones whose retry time has
|
|
25
|
+
* passed, and any whose first send never recorded an outcome. Resolves when
|
|
26
|
+
* every one has been sent and its outcome recorded.
|
|
27
|
+
*/
|
|
28
|
+
export declare function processWebhookRetries(webhooks: readonly WebhookConfig[], deliveries: IWebhookDeliveryAdapter): Promise<void>;
|
|
29
|
+
//# sourceMappingURL=webhooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,KAAK,uBAAuB,EAAwB,MAAM,sBAAsB,CAAA;AACzF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAiC/C;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,KAAK,EAAE,YAAY,EACnB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,uBAAuB,GACnC,IAAI,CAcN;AA+CD,wGAAwG;AACxG,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,aAAa,EACnB,QAAQ,EAAE,UAAU,EACpB,UAAU,EAAE,uBAAuB,GAClC,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,UAAU,EAAE,uBAAuB,GAClC,OAAO,CAAC,IAAI,CAAC,CAyBf"}
|
package/dist/webhooks.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { createHmac } from 'node:crypto';
|
|
2
|
+
import { MAX_WEBHOOK_ATTEMPTS } from '@krantho/persistence';
|
|
3
|
+
/**
|
|
4
|
+
* Retry delays in seconds, indexed by the attempts made: after a first attempt 30s, then 2min,
|
|
5
|
+
* 15min and 1h (index 0 is never used: every delivery has made one attempt by the time it is
|
|
6
|
+
* logged). The length equals MAX_WEBHOOK_ATTEMPTS from @krantho/persistence, which owns the limit.
|
|
7
|
+
*/
|
|
8
|
+
const RETRY_DELAYS = [0, 30, 120, 900, 3600];
|
|
9
|
+
/** When a delivery that has made `attempts` attempts, the last of them failing or still in flight, is due again */
|
|
10
|
+
function retryDueAt(attempts) {
|
|
11
|
+
const retryIndex = Math.min(attempts, MAX_WEBHOOK_ATTEMPTS - 1);
|
|
12
|
+
const delaySeconds = RETRY_DELAYS[retryIndex] ?? 3600;
|
|
13
|
+
return new Date(Date.now() + delaySeconds * 1000);
|
|
14
|
+
}
|
|
15
|
+
/** The sweep sends no more than this many deliveries at a time */
|
|
16
|
+
const SWEEP_BATCH = 20;
|
|
17
|
+
/**
|
|
18
|
+
* A send gives up after this long, well inside the first retry delay: a first
|
|
19
|
+
* send is logged as due for retry only after that delay, so the retry sweep
|
|
20
|
+
* never sends a delivery whose first send is still in flight.
|
|
21
|
+
*/
|
|
22
|
+
const SEND_TIMEOUT_MS = 10_000;
|
|
23
|
+
/**
|
|
24
|
+
* Fire webhooks for a content event.
|
|
25
|
+
*
|
|
26
|
+
* With a delivery adapter, deliveries are logged and failed deliveries are
|
|
27
|
+
* retried with backoff. Without one, falls back to fire-and-forget.
|
|
28
|
+
*/
|
|
29
|
+
export function fireWebhooks(webhooks, event, collection, slug, deliveries) {
|
|
30
|
+
const payload = {
|
|
31
|
+
event,
|
|
32
|
+
collection,
|
|
33
|
+
slug,
|
|
34
|
+
timestamp: new Date().toISOString(),
|
|
35
|
+
};
|
|
36
|
+
const body = JSON.stringify(payload);
|
|
37
|
+
for (const hook of webhooks) {
|
|
38
|
+
if (!hook.events.includes(event))
|
|
39
|
+
continue;
|
|
40
|
+
deliverWebhook(hook, body, event, deliveries);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** Sign a payload with HMAC and deliver via fetch. Returns the Response or null on network error. */
|
|
44
|
+
function signAndDeliver(hook, body) {
|
|
45
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
46
|
+
if (hook.secret) {
|
|
47
|
+
const timestamp = Date.now().toString();
|
|
48
|
+
const signature = createHmac('sha256', hook.secret).update(`${timestamp}.${body}`).digest('hex');
|
|
49
|
+
headers['X-Webhook-Signature'] = `t=${timestamp},v1=${signature}`;
|
|
50
|
+
}
|
|
51
|
+
return fetch(hook.url, {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
headers,
|
|
54
|
+
body,
|
|
55
|
+
signal: AbortSignal.timeout(SEND_TIMEOUT_MS),
|
|
56
|
+
}).catch(() => null);
|
|
57
|
+
}
|
|
58
|
+
/** Deliver a single webhook, logging the send when there is a delivery log */
|
|
59
|
+
function deliverWebhook(hook, body, event, deliveries) {
|
|
60
|
+
// Logged as due for a retry only after the first retry delay: until then the send is in flight
|
|
61
|
+
const logged = deliveries
|
|
62
|
+
? deliveries.logDelivery({ url: hook.url, event, payload: body, retryAt: retryDueAt(1) })
|
|
63
|
+
: null;
|
|
64
|
+
Promise.all([logged, signAndDeliver(hook, body)])
|
|
65
|
+
.then(([deliveryId, res]) => {
|
|
66
|
+
if (!res?.ok) {
|
|
67
|
+
console.warn(`[webhook] ${event} to ${hook.url} failed with status ${res?.status ?? 0}`);
|
|
68
|
+
}
|
|
69
|
+
if (deliveries === undefined || deliveryId === null)
|
|
70
|
+
return;
|
|
71
|
+
return res?.ok
|
|
72
|
+
? deliveries.markDelivered(deliveryId, res.status)
|
|
73
|
+
: deliveries.markFailed(deliveryId, res?.status ?? 0, retryDueAt(1));
|
|
74
|
+
})
|
|
75
|
+
.catch((err) => {
|
|
76
|
+
console.warn(`[webhook] ${event} to ${hook.url} could not be recorded:`, err);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Send a stored delivery to its webhook once more, now, signed afresh with
|
|
81
|
+
* the hook's secret; the row records how it went. Resolves when it has.
|
|
82
|
+
*/
|
|
83
|
+
export async function redeliverWebhook(hook, delivery, deliveries) {
|
|
84
|
+
const res = await signAndDeliver(hook, delivery.payload);
|
|
85
|
+
if (res?.ok) {
|
|
86
|
+
await deliveries.markDelivered(delivery.id, res.status);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
console.warn(`[webhook] Retry of ${delivery.event} to ${hook.url} failed: ${res?.status ?? 0}`);
|
|
90
|
+
await deliveries.markFailed(delivery.id, res?.status ?? 0, retryDueAt(delivery.attempts));
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Send the deliveries that are due again: failed ones whose retry time has
|
|
94
|
+
* passed, and any whose first send never recorded an outcome. Resolves when
|
|
95
|
+
* every one has been sent and its outcome recorded.
|
|
96
|
+
*/
|
|
97
|
+
export async function processWebhookRetries(webhooks, deliveries) {
|
|
98
|
+
if (webhooks.length === 0)
|
|
99
|
+
return;
|
|
100
|
+
// Only the configured hooks: a delivery to a hook removed since stays unsent
|
|
101
|
+
// and must not take the places of the ones that can be sent. A claimed
|
|
102
|
+
// delivery is held for the first retry delay, well beyond a send's timeout,
|
|
103
|
+
// so no other sweep sends it meanwhile; its outcome then sets its next time
|
|
104
|
+
const now = new Date();
|
|
105
|
+
const pending = await deliveries.claimDueDeliveries({
|
|
106
|
+
urls: webhooks.map((hook) => hook.url),
|
|
107
|
+
now,
|
|
108
|
+
leaseUntil: new Date(now.getTime() + (RETRY_DELAYS[1] ?? 30) * 1000),
|
|
109
|
+
limit: SWEEP_BATCH,
|
|
110
|
+
});
|
|
111
|
+
const sends = pending.flatMap((delivery) => {
|
|
112
|
+
const hook = webhooks.find((h) => h.url === delivery.url);
|
|
113
|
+
if (!hook)
|
|
114
|
+
return [];
|
|
115
|
+
return [
|
|
116
|
+
redeliverWebhook(hook, delivery, deliveries).catch((err) => {
|
|
117
|
+
console.warn(`[webhook] Retry of delivery ${delivery.id} could not be recorded:`, err);
|
|
118
|
+
}),
|
|
119
|
+
];
|
|
120
|
+
});
|
|
121
|
+
await Promise.all(sends);
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=webhooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"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"}
|