@rakun-kit/core 1.6.1 → 1.7.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/README.md +1393 -1278
- package/dist/cjs/api/operations/manager-contract.js +49 -0
- package/dist/cjs/api/operations/manager-contract.js.map +1 -1
- package/dist/cjs/api/operations/manager-manifest.js +30 -0
- package/dist/cjs/api/operations/manager-manifest.js.map +1 -1
- package/dist/cjs/api/operations/manager.js +20 -0
- package/dist/cjs/api/operations/manager.js.map +1 -1
- package/dist/cjs/api/realtime.js +144 -0
- package/dist/cjs/api/realtime.js.map +1 -0
- package/dist/cjs/api/routes/manager/auth/externalLogin.js +7 -5
- package/dist/cjs/api/routes/manager/auth/externalLogin.js.map +1 -1
- package/dist/cjs/api/routes/manager/auth/mfa/verifyRecoveryCode.js +2 -1
- package/dist/cjs/api/routes/manager/auth/mfa/verifyRecoveryCode.js.map +1 -1
- package/dist/cjs/api/routes/manager/auth/passwordRecovery.js +3 -3
- package/dist/cjs/api/routes/manager/auth/passwordRecovery.js.map +1 -1
- package/dist/cjs/api/routes/manager/auth/totp/enrollTotp.js +2 -2
- package/dist/cjs/api/routes/manager/auth/totp/enrollTotp.js.map +1 -1
- package/dist/cjs/api/routes/manager/auth/totp/verifyTotp.js +2 -1
- package/dist/cjs/api/routes/manager/auth/totp/verifyTotp.js.map +1 -1
- package/dist/cjs/api/routes/manager/auth/webauthn/webauthnAuthVerify.js +2 -1
- package/dist/cjs/api/routes/manager/auth/webauthn/webauthnAuthVerify.js.map +1 -1
- package/dist/cjs/api/routes/manager/auth/webauthn/webauthnRegisterOptions.js +2 -2
- package/dist/cjs/api/routes/manager/auth/webauthn/webauthnRegisterOptions.js.map +1 -1
- package/dist/cjs/api/routes/manager/auth/webauthn/webauthnRegisterVerify.js +2 -1
- package/dist/cjs/api/routes/manager/auth/webauthn/webauthnRegisterVerify.js.map +1 -1
- package/dist/cjs/api/routes/manager/collaborationBinary.js +8 -0
- package/dist/cjs/api/routes/manager/collaborationBinary.js.map +1 -0
- package/dist/cjs/api/routes/manager/comments.js +4 -0
- package/dist/cjs/api/routes/manager/comments.js.map +1 -1
- package/dist/cjs/api/routes/manager/contentCollaboration.js +102 -0
- package/dist/cjs/api/routes/manager/contentCollaboration.js.map +1 -0
- package/dist/cjs/api/routes/manager/contentVersions.js +3 -0
- package/dist/cjs/api/routes/manager/contentVersions.js.map +1 -1
- package/dist/cjs/api/routes/manager/delete.js +15 -0
- package/dist/cjs/api/routes/manager/delete.js.map +1 -1
- package/dist/cjs/api/routes/manager/duplicate.js +2 -2
- package/dist/cjs/api/routes/manager/duplicate.js.map +1 -1
- package/dist/cjs/api/routes/manager/localeVariants.js +9 -1
- package/dist/cjs/api/routes/manager/localeVariants.js.map +1 -1
- package/dist/cjs/api/routes/manager/notifications.js +2 -0
- package/dist/cjs/api/routes/manager/notifications.js.map +1 -1
- package/dist/cjs/api/routes/manager/template.js +3 -2
- package/dist/cjs/api/routes/manager/template.js.map +1 -1
- package/dist/cjs/api/routes/manager/templateCollaboration.js +101 -0
- package/dist/cjs/api/routes/manager/templateCollaboration.js.map +1 -0
- package/dist/cjs/api/routes/manager/translateDocument.js +4 -22
- package/dist/cjs/api/routes/manager/translateDocument.js.map +1 -1
- package/dist/cjs/api/routes/manager/trash.js +4 -0
- package/dist/cjs/api/routes/manager/trash.js.map +1 -1
- package/dist/cjs/api/routes/manager/uiLocales.js +13 -1
- package/dist/cjs/api/routes/manager/uiLocales.js.map +1 -1
- package/dist/cjs/api/routes/manager/update.js +4 -0
- package/dist/cjs/api/routes/manager/update.js.map +1 -1
- package/dist/cjs/api/routes/web/llms.js +5 -5
- package/dist/cjs/api/routes/web/llms.js.map +1 -1
- package/dist/cjs/api/routes/web/seo.js +2 -2
- package/dist/cjs/api/routes/web/seo.js.map +1 -1
- package/dist/cjs/api/utils/contentTemplate.js +11 -14
- package/dist/cjs/api/utils/contentTemplate.js.map +1 -1
- package/dist/cjs/api/utils/iteratorVisibility.js +5 -5
- package/dist/cjs/api/utils/iteratorVisibility.js.map +1 -1
- package/dist/cjs/api/utils/managerNotifications.js +4 -1
- package/dist/cjs/api/utils/managerNotifications.js.map +1 -1
- package/dist/cjs/api/utils/mediaUploadToken.js +3 -3
- package/dist/cjs/api/utils/mediaUploadToken.js.map +1 -1
- package/dist/cjs/api/utils/passwords.js +13 -0
- package/dist/cjs/api/utils/passwords.js.map +1 -1
- package/dist/cjs/api/utils/previewToken.js +2 -2
- package/dist/cjs/api/utils/previewToken.js.map +1 -1
- package/dist/cjs/api/utils/realtime.js +20 -0
- package/dist/cjs/api/utils/realtime.js.map +1 -0
- package/dist/cjs/api/utils/recoveryCodes.js +7 -4
- package/dist/cjs/api/utils/recoveryCodes.js.map +1 -1
- package/dist/cjs/api/utils/safeManagerQuery.js +5 -5
- package/dist/cjs/api/utils/safeManagerQuery.js.map +1 -1
- package/dist/cjs/api/utils/sanitizeManagerOutput.js +2 -2
- package/dist/cjs/api/utils/sanitizeManagerOutput.js.map +1 -1
- package/dist/cjs/auth/completePrimaryAuthentication.js +3 -3
- package/dist/cjs/auth/completePrimaryAuthentication.js.map +1 -1
- package/dist/cjs/bootstrapState.js.map +1 -1
- package/dist/cjs/client.js +12 -1
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/collaboration/document.js +170 -0
- package/dist/cjs/collaboration/document.js.map +1 -0
- package/dist/cjs/collaboration/index.js +31 -0
- package/dist/cjs/collaboration/index.js.map +1 -0
- package/dist/cjs/collaboration/memory.js +38 -0
- package/dist/cjs/collaboration/memory.js.map +1 -0
- package/dist/cjs/collaboration/rooms.js +39 -0
- package/dist/cjs/collaboration/rooms.js.map +1 -0
- package/dist/cjs/collaboration/service.js +237 -0
- package/dist/cjs/collaboration/service.js.map +1 -0
- package/dist/cjs/collaboration/types.js +3 -0
- package/dist/cjs/collaboration/types.js.map +1 -0
- package/dist/cjs/contracts.js +2 -0
- package/dist/cjs/contracts.js.map +1 -1
- package/dist/cjs/index.js +19 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/utils/isRecord.js +9 -0
- package/dist/cjs/lib/utils/isRecord.js.map +1 -0
- package/dist/cjs/mail/mailService.js +2 -1
- package/dist/cjs/mail/mailService.js.map +1 -1
- package/dist/cjs/media/imageOptimization.js +22 -32
- package/dist/cjs/media/imageOptimization.js.map +1 -1
- package/dist/cjs/media/index.js +1 -0
- package/dist/cjs/media/index.js.map +1 -1
- package/dist/cjs/media/mediaService.js +2 -2
- package/dist/cjs/media/mediaService.js.map +1 -1
- package/dist/cjs/media/publicMedia.js +114 -0
- package/dist/cjs/media/publicMedia.js.map +1 -0
- package/dist/cjs/media/videoOptimization.js +11 -24
- package/dist/cjs/media/videoOptimization.js.map +1 -1
- package/dist/cjs/platform/image.js +140 -0
- package/dist/cjs/platform/image.js.map +1 -0
- package/dist/cjs/platform/index.js +55 -0
- package/dist/cjs/platform/index.js.map +1 -0
- package/dist/cjs/platform/node.js +53 -0
- package/dist/cjs/platform/node.js.map +1 -0
- package/dist/cjs/platform/realtime.js +55 -0
- package/dist/cjs/platform/realtime.js.map +1 -0
- package/dist/cjs/platform/realtimeServer.js +126 -0
- package/dist/cjs/platform/realtimeServer.js.map +1 -0
- package/dist/cjs/platform/realtimeTopics.js +16 -0
- package/dist/cjs/platform/realtimeTopics.js.map +1 -0
- package/dist/cjs/platform/runtime.js +8 -0
- package/dist/cjs/platform/runtime.js.map +1 -0
- package/dist/cjs/platform/types.js +3 -0
- package/dist/cjs/platform/types.js.map +1 -0
- package/dist/cjs/schemas/manager/collaborationPresence.js +22 -0
- package/dist/cjs/schemas/manager/collaborationPresence.js.map +1 -0
- package/dist/cjs/schemas/manager/contentCollaboration.js +36 -0
- package/dist/cjs/schemas/manager/contentCollaboration.js.map +1 -0
- package/dist/cjs/schemas/manager/templateCollaboration.js +36 -0
- package/dist/cjs/schemas/manager/templateCollaboration.js.map +1 -0
- package/dist/cjs/schemas/manager/uiLocales.js +12 -0
- package/dist/cjs/schemas/manager/uiLocales.js.map +1 -1
- package/dist/cjs/translation/document.js +19 -19
- package/dist/cjs/translation/document.js.map +1 -1
- package/dist/docs/index.md +557 -422
- package/dist/esm/api/context.d.ts +1 -1
- package/dist/esm/api/context.js +3 -3
- package/dist/esm/api/hooks/context.d.ts +1 -1
- package/dist/esm/api/hooks/runContentHooks.d.ts +4 -4
- package/dist/esm/api/hooks/runContentHooks.js +1 -1
- package/dist/esm/api/operations/apiEventLog.d.ts +3 -3
- package/dist/esm/api/operations/apiEventLog.js +3 -3
- package/dist/esm/api/operations/catalog.d.ts +2 -2
- package/dist/esm/api/operations/catalog.js +1 -1
- package/dist/esm/api/operations/custom.d.ts +1 -1
- package/dist/esm/api/operations/custom.js +1 -1
- package/dist/esm/api/operations/index.d.ts +292 -200
- package/dist/esm/api/operations/index.d.ts.map +1 -1
- package/dist/esm/api/operations/index.js +9 -9
- package/dist/esm/api/operations/manager-contract.d.ts +257 -165
- package/dist/esm/api/operations/manager-contract.d.ts.map +1 -1
- package/dist/esm/api/operations/manager-contract.js +56 -7
- package/dist/esm/api/operations/manager-contract.js.map +1 -1
- package/dist/esm/api/operations/manager-manifest.d.ts +30 -0
- package/dist/esm/api/operations/manager-manifest.d.ts.map +1 -1
- package/dist/esm/api/operations/manager-manifest.js +30 -0
- package/dist/esm/api/operations/manager-manifest.js.map +1 -1
- package/dist/esm/api/operations/manager.d.ts +258 -166
- package/dist/esm/api/operations/manager.d.ts.map +1 -1
- package/dist/esm/api/operations/manager.js +93 -73
- package/dist/esm/api/operations/manager.js.map +1 -1
- package/dist/esm/api/operations/tracing.d.ts +1 -1
- package/dist/esm/api/operations/tracing.js +2 -2
- package/dist/esm/api/operations/types.d.ts +1 -1
- package/dist/esm/api/operations/web-contract.d.ts +26 -26
- package/dist/esm/api/operations/web-contract.js +3 -3
- package/dist/esm/api/operations/web.d.ts +27 -27
- package/dist/esm/api/operations/web.js +11 -11
- package/dist/esm/api/realtime.d.ts +16 -0
- package/dist/esm/api/realtime.d.ts.map +1 -0
- package/dist/esm/api/realtime.js +140 -0
- package/dist/esm/api/realtime.js.map +1 -0
- package/dist/esm/api/routes/manager/apiOperations.d.ts +3 -3
- package/dist/esm/api/routes/manager/apiOperations.js +5 -5
- package/dist/esm/api/routes/manager/auth/accountInfo.d.ts +2 -2
- package/dist/esm/api/routes/manager/auth/accountInfo.js +3 -3
- package/dist/esm/api/routes/manager/auth/deleteSession.d.ts +2 -2
- package/dist/esm/api/routes/manager/auth/deleteSession.js +3 -3
- package/dist/esm/api/routes/manager/auth/externalLogin.d.ts +2 -2
- package/dist/esm/api/routes/manager/auth/externalLogin.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/auth/externalLogin.js +14 -12
- package/dist/esm/api/routes/manager/auth/externalLogin.js.map +1 -1
- package/dist/esm/api/routes/manager/auth/getSession.d.ts +7 -7
- package/dist/esm/api/routes/manager/auth/login.d.ts +2 -2
- package/dist/esm/api/routes/manager/auth/login.js +9 -9
- package/dist/esm/api/routes/manager/auth/logout.d.ts +1 -1
- package/dist/esm/api/routes/manager/auth/logout.js +3 -3
- package/dist/esm/api/routes/manager/auth/markTourSeen.d.ts +8 -8
- package/dist/esm/api/routes/manager/auth/markTourSeen.js +3 -3
- package/dist/esm/api/routes/manager/auth/mfa/regenerateRecoveryCodes.d.ts +2 -2
- package/dist/esm/api/routes/manager/auth/mfa/regenerateRecoveryCodes.js +6 -6
- package/dist/esm/api/routes/manager/auth/mfa/verifyRecoveryCode.d.ts +3 -3
- package/dist/esm/api/routes/manager/auth/mfa/verifyRecoveryCode.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/auth/mfa/verifyRecoveryCode.js +9 -8
- package/dist/esm/api/routes/manager/auth/mfa/verifyRecoveryCode.js.map +1 -1
- package/dist/esm/api/routes/manager/auth/passwordIpBlocks.d.ts +2 -2
- package/dist/esm/api/routes/manager/auth/passwordIpBlocks.js +8 -8
- package/dist/esm/api/routes/manager/auth/passwordRecovery.d.ts +2 -2
- package/dist/esm/api/routes/manager/auth/passwordRecovery.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/auth/passwordRecovery.js +13 -13
- package/dist/esm/api/routes/manager/auth/passwordRecovery.js.map +1 -1
- package/dist/esm/api/routes/manager/auth/totp/confirmTotp.d.ts +2 -2
- package/dist/esm/api/routes/manager/auth/totp/confirmTotp.js +4 -4
- package/dist/esm/api/routes/manager/auth/totp/enrollTotp.d.ts +1 -1
- package/dist/esm/api/routes/manager/auth/totp/enrollTotp.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/auth/totp/enrollTotp.js +5 -5
- package/dist/esm/api/routes/manager/auth/totp/enrollTotp.js.map +1 -1
- package/dist/esm/api/routes/manager/auth/totp/verifyTotp.d.ts +2 -2
- package/dist/esm/api/routes/manager/auth/totp/verifyTotp.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/auth/totp/verifyTotp.js +7 -6
- package/dist/esm/api/routes/manager/auth/totp/verifyTotp.js.map +1 -1
- package/dist/esm/api/routes/manager/auth/updateAccount.d.ts +8 -8
- package/dist/esm/api/routes/manager/auth/updateAccount.js +3 -3
- package/dist/esm/api/routes/manager/auth/updatePassword.d.ts +2 -2
- package/dist/esm/api/routes/manager/auth/updatePassword.js +5 -5
- package/dist/esm/api/routes/manager/auth/updateTutorialPreferences.d.ts +8 -8
- package/dist/esm/api/routes/manager/auth/updateTutorialPreferences.js +3 -3
- package/dist/esm/api/routes/manager/auth/webauthn/webauthnAuthOptions.js +4 -4
- package/dist/esm/api/routes/manager/auth/webauthn/webauthnAuthVerify.d.ts +1 -1
- package/dist/esm/api/routes/manager/auth/webauthn/webauthnAuthVerify.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/auth/webauthn/webauthnAuthVerify.js +8 -7
- package/dist/esm/api/routes/manager/auth/webauthn/webauthnAuthVerify.js.map +1 -1
- package/dist/esm/api/routes/manager/auth/webauthn/webauthnRegisterOptions.d.ts +2 -2
- package/dist/esm/api/routes/manager/auth/webauthn/webauthnRegisterOptions.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/auth/webauthn/webauthnRegisterOptions.js +5 -5
- package/dist/esm/api/routes/manager/auth/webauthn/webauthnRegisterOptions.js.map +1 -1
- package/dist/esm/api/routes/manager/auth/webauthn/webauthnRegisterVerify.d.ts +1 -1
- package/dist/esm/api/routes/manager/auth/webauthn/webauthnRegisterVerify.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/auth/webauthn/webauthnRegisterVerify.js +8 -7
- package/dist/esm/api/routes/manager/auth/webauthn/webauthnRegisterVerify.js.map +1 -1
- package/dist/esm/api/routes/manager/backups/create.d.ts +2 -2
- package/dist/esm/api/routes/manager/backups/create.js +2 -2
- package/dist/esm/api/routes/manager/backups/list.d.ts +2 -2
- package/dist/esm/api/routes/manager/backups/list.js +2 -2
- package/dist/esm/api/routes/manager/backups/restore.d.ts +2 -2
- package/dist/esm/api/routes/manager/backups/restore.js +4 -4
- package/dist/esm/api/routes/manager/collaborationBinary.d.ts +3 -0
- package/dist/esm/api/routes/manager/collaborationBinary.d.ts.map +1 -0
- package/dist/esm/api/routes/manager/collaborationBinary.js +3 -0
- package/dist/esm/api/routes/manager/collaborationBinary.js.map +1 -0
- package/dist/esm/api/routes/manager/comments.d.ts +2 -2
- package/dist/esm/api/routes/manager/comments.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/comments.js +12 -8
- package/dist/esm/api/routes/manager/comments.js.map +1 -1
- package/dist/esm/api/routes/manager/contentCollaboration.d.ts +21 -0
- package/dist/esm/api/routes/manager/contentCollaboration.d.ts.map +1 -0
- package/dist/esm/api/routes/manager/contentCollaboration.js +95 -0
- package/dist/esm/api/routes/manager/contentCollaboration.js.map +1 -0
- package/dist/esm/api/routes/manager/contentType.d.ts +16 -16
- package/dist/esm/api/routes/manager/contentType.js +3 -3
- package/dist/esm/api/routes/manager/contentTypes.d.ts +14 -14
- package/dist/esm/api/routes/manager/contentTypes.js +1 -1
- package/dist/esm/api/routes/manager/contentVersions.d.ts +2 -2
- package/dist/esm/api/routes/manager/contentVersions.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/contentVersions.js +16 -13
- package/dist/esm/api/routes/manager/contentVersions.js.map +1 -1
- package/dist/esm/api/routes/manager/create.d.ts +5 -5
- package/dist/esm/api/routes/manager/create.js +11 -11
- package/dist/esm/api/routes/manager/delete.d.ts +2 -2
- package/dist/esm/api/routes/manager/delete.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/delete.js +27 -12
- package/dist/esm/api/routes/manager/delete.js.map +1 -1
- package/dist/esm/api/routes/manager/duplicate.d.ts +5 -5
- package/dist/esm/api/routes/manager/duplicate.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/duplicate.js +7 -7
- package/dist/esm/api/routes/manager/duplicate.js.map +1 -1
- package/dist/esm/api/routes/manager/favorites.d.ts +2 -2
- package/dist/esm/api/routes/manager/favorites.js +5 -5
- package/dist/esm/api/routes/manager/get.d.ts +2 -2
- package/dist/esm/api/routes/manager/get.js +10 -10
- package/dist/esm/api/routes/manager/languages.d.ts +4 -4
- package/dist/esm/api/routes/manager/languages.js +1 -1
- package/dist/esm/api/routes/manager/list.d.ts +2 -2
- package/dist/esm/api/routes/manager/list.js +15 -15
- package/dist/esm/api/routes/manager/literals/list.d.ts +2 -2
- package/dist/esm/api/routes/manager/literals/list.js +5 -5
- package/dist/esm/api/routes/manager/literals/upsert.d.ts +2 -2
- package/dist/esm/api/routes/manager/literals/upsert.js +6 -6
- package/dist/esm/api/routes/manager/localeVariants.d.ts +49 -49
- package/dist/esm/api/routes/manager/localeVariants.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/localeVariants.js +28 -20
- package/dist/esm/api/routes/manager/localeVariants.js.map +1 -1
- package/dist/esm/api/routes/manager/logs/cleanup.d.ts +2 -2
- package/dist/esm/api/routes/manager/logs/cleanup.js +3 -3
- package/dist/esm/api/routes/manager/logs/list.d.ts +2 -2
- package/dist/esm/api/routes/manager/logs/list.js +2 -2
- package/dist/esm/api/routes/manager/media/createFolder.d.ts +2 -2
- package/dist/esm/api/routes/manager/media/createFolder.js +7 -7
- package/dist/esm/api/routes/manager/media/deleteFolder.d.ts +2 -2
- package/dist/esm/api/routes/manager/media/deleteFolder.js +7 -7
- package/dist/esm/api/routes/manager/media/deleteMediaStorage.js +2 -2
- package/dist/esm/api/routes/manager/media/finalizeUpload.d.ts +2 -2
- package/dist/esm/api/routes/manager/media/finalizeUpload.js +12 -12
- package/dist/esm/api/routes/manager/media/getMediaUrl.d.ts +2 -2
- package/dist/esm/api/routes/manager/media/getMediaUrl.js +6 -6
- package/dist/esm/api/routes/manager/media/listFolders.d.ts +2 -2
- package/dist/esm/api/routes/manager/media/listFolders.js +4 -4
- package/dist/esm/api/routes/manager/media/prepareUpload.d.ts +3 -3
- package/dist/esm/api/routes/manager/media/prepareUpload.js +5 -5
- package/dist/esm/api/routes/manager/media/reimportMedia.d.ts +5 -5
- package/dist/esm/api/routes/manager/media/reimportMedia.js +10 -10
- package/dist/esm/api/routes/manager/media/replaceMedia.d.ts +3 -3
- package/dist/esm/api/routes/manager/media/replaceMedia.js +12 -12
- package/dist/esm/api/routes/manager/media/resolveMediaRecordUrls.js +1 -1
- package/dist/esm/api/routes/manager/media/uploadBinary.d.ts +1 -1
- package/dist/esm/api/routes/manager/media/uploadBinary.js +9 -9
- package/dist/esm/api/routes/manager/migrations/list.d.ts +2 -2
- package/dist/esm/api/routes/manager/migrations/list.js +2 -2
- package/dist/esm/api/routes/manager/notifications.d.ts +2 -2
- package/dist/esm/api/routes/manager/notifications.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/notifications.js +8 -6
- package/dist/esm/api/routes/manager/notifications.js.map +1 -1
- package/dist/esm/api/routes/manager/permissions.d.ts +1 -1
- package/dist/esm/api/routes/manager/permissions.js +2 -2
- package/dist/esm/api/routes/manager/preview/create.d.ts +2 -2
- package/dist/esm/api/routes/manager/preview/create.js +15 -15
- package/dist/esm/api/routes/manager/previewSlugRedirects.d.ts +2 -2
- package/dist/esm/api/routes/manager/previewSlugRedirects.js +3 -3
- package/dist/esm/api/routes/manager/regenerateRoutes.d.ts +1 -1
- package/dist/esm/api/routes/manager/regenerateRoutes.js +2 -2
- package/dist/esm/api/routes/manager/reviewPolicies.d.ts +2 -2
- package/dist/esm/api/routes/manager/reviewPolicies.js +7 -7
- package/dist/esm/api/routes/manager/reviews.d.ts +2 -2
- package/dist/esm/api/routes/manager/reviews.js +8 -8
- package/dist/esm/api/routes/manager/routeLayout.d.ts +2 -2
- package/dist/esm/api/routes/manager/routeLayout.js +6 -6
- package/dist/esm/api/routes/manager/setDefaultLanguage.d.ts +2 -2
- package/dist/esm/api/routes/manager/setDefaultLanguage.js +5 -5
- package/dist/esm/api/routes/manager/template.d.ts +4 -3
- package/dist/esm/api/routes/manager/template.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/template.js +11 -11
- package/dist/esm/api/routes/manager/template.js.map +1 -1
- package/dist/esm/api/routes/manager/templateCollaboration.d.ts +17 -0
- package/dist/esm/api/routes/manager/templateCollaboration.d.ts.map +1 -0
- package/dist/esm/api/routes/manager/templateCollaboration.js +95 -0
- package/dist/esm/api/routes/manager/templateCollaboration.js.map +1 -0
- package/dist/esm/api/routes/manager/translateDocument.d.ts +2 -2
- package/dist/esm/api/routes/manager/translateDocument.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/translateDocument.js +14 -32
- package/dist/esm/api/routes/manager/translateDocument.js.map +1 -1
- package/dist/esm/api/routes/manager/trash.d.ts +3 -3
- package/dist/esm/api/routes/manager/trash.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/trash.js +13 -9
- package/dist/esm/api/routes/manager/trash.js.map +1 -1
- package/dist/esm/api/routes/manager/uiLocales.d.ts +3 -1
- package/dist/esm/api/routes/manager/uiLocales.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/uiLocales.js +16 -5
- package/dist/esm/api/routes/manager/uiLocales.js.map +1 -1
- package/dist/esm/api/routes/manager/update.d.ts +5 -5
- package/dist/esm/api/routes/manager/update.d.ts.map +1 -1
- package/dist/esm/api/routes/manager/update.js +18 -14
- package/dist/esm/api/routes/manager/update.js.map +1 -1
- package/dist/esm/api/routes/manager/users.d.ts +2 -2
- package/dist/esm/api/routes/manager/users.js +2 -2
- package/dist/esm/api/routes/manager/versions/get.d.ts +2 -2
- package/dist/esm/api/routes/manager/versions/get.js +2 -2
- package/dist/esm/api/routes/manager/versions/list.d.ts +2 -2
- package/dist/esm/api/routes/manager/versions/list.js +2 -2
- package/dist/esm/api/routes/manager/versions/restore.d.ts +2 -2
- package/dist/esm/api/routes/manager/versions/restore.js +8 -8
- package/dist/esm/api/routes/web/llms.d.ts +1 -1
- package/dist/esm/api/routes/web/llms.d.ts.map +1 -1
- package/dist/esm/api/routes/web/llms.js +7 -7
- package/dist/esm/api/routes/web/llms.js.map +1 -1
- package/dist/esm/api/routes/web/page.d.ts +5 -5
- package/dist/esm/api/routes/web/page.js +21 -21
- package/dist/esm/api/routes/web/previewPage.d.ts +8 -8
- package/dist/esm/api/routes/web/previewPage.js +9 -9
- package/dist/esm/api/routes/web/robots.d.ts +1 -1
- package/dist/esm/api/routes/web/robots.js +2 -2
- package/dist/esm/api/routes/web/seo.d.ts +1 -1
- package/dist/esm/api/routes/web/seo.d.ts.map +1 -1
- package/dist/esm/api/routes/web/seo.js +1 -1
- package/dist/esm/api/routes/web/seo.js.map +1 -1
- package/dist/esm/api/routes/web/sitemap.d.ts +1 -1
- package/dist/esm/api/routes/web/sitemap.js +4 -4
- package/dist/esm/api/routes/web/staticPaths.d.ts +3 -3
- package/dist/esm/api/routes/web/staticPaths.js +4 -4
- package/dist/esm/api/sessionCookie.d.ts +1 -1
- package/dist/esm/api/utils/authEvents.d.ts +2 -2
- package/dist/esm/api/utils/authEvents.js +2 -2
- package/dist/esm/api/utils/authRateLimit.d.ts +1 -1
- package/dist/esm/api/utils/authRateLimit.js +1 -1
- package/dist/esm/api/utils/breadcrums.d.ts +5 -5
- package/dist/esm/api/utils/breadcrums.js +3 -3
- package/dist/esm/api/utils/checkFailureCase.d.ts +1 -1
- package/dist/esm/api/utils/checkFailureCase.js +1 -1
- package/dist/esm/api/utils/checkOwnership.d.ts +2 -2
- package/dist/esm/api/utils/checkOwnership.js +5 -5
- package/dist/esm/api/utils/checkPermissions.d.ts +2 -2
- package/dist/esm/api/utils/checkPermissions.js +3 -3
- package/dist/esm/api/utils/contentTemplate.d.ts +2 -2
- package/dist/esm/api/utils/contentTemplate.d.ts.map +1 -1
- package/dist/esm/api/utils/contentTemplate.js +8 -11
- package/dist/esm/api/utils/contentTemplate.js.map +1 -1
- package/dist/esm/api/utils/dynamicData.d.ts +5 -5
- package/dist/esm/api/utils/dynamicData.js +11 -11
- package/dist/esm/api/utils/getLanguages.d.ts +2 -2
- package/dist/esm/api/utils/getLanguages.js +2 -2
- package/dist/esm/api/utils/getLink.d.ts +2 -2
- package/dist/esm/api/utils/getLink.js +5 -5
- package/dist/esm/api/utils/getUser.d.ts +7 -7
- package/dist/esm/api/utils/getUser.js +4 -4
- package/dist/esm/api/utils/index.d.ts +25 -25
- package/dist/esm/api/utils/index.js +25 -25
- package/dist/esm/api/utils/iteratorVisibility.d.ts +1 -1
- package/dist/esm/api/utils/iteratorVisibility.d.ts.map +1 -1
- package/dist/esm/api/utils/iteratorVisibility.js +1 -1
- package/dist/esm/api/utils/iteratorVisibility.js.map +1 -1
- package/dist/esm/api/utils/localeVariants.d.ts +1 -1
- package/dist/esm/api/utils/localeVariants.js +8 -8
- package/dist/esm/api/utils/managerNotifications.d.ts +5 -5
- package/dist/esm/api/utils/managerNotifications.d.ts.map +1 -1
- package/dist/esm/api/utils/managerNotifications.js +7 -4
- package/dist/esm/api/utils/managerNotifications.js.map +1 -1
- package/dist/esm/api/utils/mediaUploadToken.d.ts +1 -1
- package/dist/esm/api/utils/mediaUploadToken.d.ts.map +1 -1
- package/dist/esm/api/utils/mediaUploadToken.js +3 -3
- package/dist/esm/api/utils/mediaUploadToken.js.map +1 -1
- package/dist/esm/api/utils/parseId.d.ts +1 -1
- package/dist/esm/api/utils/parseId.js +1 -1
- package/dist/esm/api/utils/passwords.d.ts.map +1 -1
- package/dist/esm/api/utils/passwords.js +14 -1
- package/dist/esm/api/utils/passwords.js.map +1 -1
- package/dist/esm/api/utils/populates/populateLinks.d.ts +2 -2
- package/dist/esm/api/utils/populates/populateLinks.js +5 -5
- package/dist/esm/api/utils/populates/populateRelations.d.ts +2 -2
- package/dist/esm/api/utils/populates/populateRelations.js +7 -7
- package/dist/esm/api/utils/previewToken.d.ts.map +1 -1
- package/dist/esm/api/utils/previewToken.js +2 -2
- package/dist/esm/api/utils/previewToken.js.map +1 -1
- package/dist/esm/api/utils/realtime.d.ts +3 -0
- package/dist/esm/api/utils/realtime.d.ts.map +1 -0
- package/dist/esm/api/utils/realtime.js +15 -0
- package/dist/esm/api/utils/realtime.js.map +1 -0
- package/dist/esm/api/utils/recoveryCodes.d.ts.map +1 -1
- package/dist/esm/api/utils/recoveryCodes.js +7 -4
- package/dist/esm/api/utils/recoveryCodes.js.map +1 -1
- package/dist/esm/api/utils/redirects/createSlugChangeRedirects.d.ts +2 -2
- package/dist/esm/api/utils/redirects/createSlugChangeRedirects.js +6 -6
- package/dist/esm/api/utils/redirects/resolveRedirect.js +2 -2
- package/dist/esm/api/utils/redirects/slugPathChanges.d.ts +1 -1
- package/dist/esm/api/utils/redirects/slugPathChanges.js +4 -4
- package/dist/esm/api/utils/requireContentType.d.ts +1 -1
- package/dist/esm/api/utils/requireContentType.js +2 -2
- package/dist/esm/api/utils/reviews.d.ts +12 -12
- package/dist/esm/api/utils/reviews.js +4 -4
- package/dist/esm/api/utils/routes/revalidatePath.js +5 -5
- package/dist/esm/api/utils/routes/routeDefinitions.d.ts +1 -1
- package/dist/esm/api/utils/routes/routeMapHelpers.d.ts +6 -6
- package/dist/esm/api/utils/routes/routeMapHelpers.js +8 -8
- package/dist/esm/api/utils/routes/syncConfiguredRoutes.d.ts +2 -2
- package/dist/esm/api/utils/routes/syncConfiguredRoutes.js +5 -5
- package/dist/esm/api/utils/routes/updateRoutesMap.d.ts +2 -2
- package/dist/esm/api/utils/routes/updateRoutesMap.js +5 -5
- package/dist/esm/api/utils/safeManagerQuery.d.ts +2 -2
- package/dist/esm/api/utils/safeManagerQuery.d.ts.map +1 -1
- package/dist/esm/api/utils/safeManagerQuery.js +2 -2
- package/dist/esm/api/utils/safeManagerQuery.js.map +1 -1
- package/dist/esm/api/utils/sanitizeManagerOutput.d.ts +1 -1
- package/dist/esm/api/utils/sanitizeManagerOutput.d.ts.map +1 -1
- package/dist/esm/api/utils/sanitizeManagerOutput.js +2 -2
- package/dist/esm/api/utils/sanitizeManagerOutput.js.map +1 -1
- package/dist/esm/api/utils/transformObjectIdsToStrings.js +1 -1
- package/dist/esm/api/utils/transformStringToObjectIds.js +1 -1
- package/dist/esm/api/utils/translate.d.ts +1 -1
- package/dist/esm/api/utils/translate.js +3 -3
- package/dist/esm/api/utils/validateModule.d.ts +1 -1
- package/dist/esm/api/utils/validateModule.js +2 -2
- package/dist/esm/auth/accountRecovery.d.ts +1 -1
- package/dist/esm/auth/completePrimaryAuthentication.d.ts +1 -1
- package/dist/esm/auth/completePrimaryAuthentication.d.ts.map +1 -1
- package/dist/esm/auth/completePrimaryAuthentication.js +6 -6
- package/dist/esm/auth/completePrimaryAuthentication.js.map +1 -1
- package/dist/esm/auth/loginAdapters.d.ts +1 -1
- package/dist/esm/auth/passwordFail2ban.d.ts +2 -2
- package/dist/esm/auth/passwordFail2ban.js +4 -4
- package/dist/esm/auth/passwordResetMailTemplate.d.ts +2 -2
- package/dist/esm/auth/passwordResetMailTemplate.js +1 -1
- package/dist/esm/bootstrapState.d.ts +25 -15
- package/dist/esm/bootstrapState.d.ts.map +1 -1
- package/dist/esm/bootstrapState.js.map +1 -1
- package/dist/esm/client.d.ts +68 -62
- package/dist/esm/client.d.ts.map +1 -1
- package/dist/esm/client.js +36 -33
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/collaboration/document.d.ts +7 -0
- package/dist/esm/collaboration/document.d.ts.map +1 -0
- package/dist/esm/collaboration/document.js +130 -0
- package/dist/esm/collaboration/document.js.map +1 -0
- package/dist/esm/collaboration/index.d.ts +12 -0
- package/dist/esm/collaboration/index.d.ts.map +1 -0
- package/dist/esm/collaboration/index.js +19 -0
- package/dist/esm/collaboration/index.js.map +1 -0
- package/dist/esm/collaboration/memory.d.ts +3 -0
- package/dist/esm/collaboration/memory.d.ts.map +1 -0
- package/dist/esm/collaboration/memory.js +34 -0
- package/dist/esm/collaboration/memory.js.map +1 -0
- package/dist/esm/collaboration/rooms.d.ts +10 -0
- package/dist/esm/collaboration/rooms.d.ts.map +1 -0
- package/dist/esm/collaboration/rooms.js +33 -0
- package/dist/esm/collaboration/rooms.js.map +1 -0
- package/dist/esm/collaboration/service.d.ts +48 -0
- package/dist/esm/collaboration/service.d.ts.map +1 -0
- package/dist/esm/collaboration/service.js +200 -0
- package/dist/esm/collaboration/service.js.map +1 -0
- package/dist/esm/collaboration/types.d.ts +30 -0
- package/dist/esm/collaboration/types.d.ts.map +1 -0
- package/dist/esm/collaboration/types.js +2 -0
- package/dist/esm/collaboration/types.js.map +1 -0
- package/dist/esm/contracts.d.ts +62 -60
- package/dist/esm/contracts.d.ts.map +1 -1
- package/dist/esm/contracts.js +62 -60
- package/dist/esm/contracts.js.map +1 -1
- package/dist/esm/eventLog/index.d.ts +6 -6
- package/dist/esm/eventLog/index.js +4 -4
- package/dist/esm/eventLog/mongo.d.ts +1 -1
- package/dist/esm/eventLog/mongo.js +2 -2
- package/dist/esm/eventLog/service.d.ts +1 -1
- package/dist/esm/index.d.ts +55 -52
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +64 -52
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal-content-types/ApiOperation.d.ts +162 -162
- package/dist/esm/internal-content-types/ApiOperation.js +2 -2
- package/dist/esm/internal-content-types/Backup.d.ts +199 -199
- package/dist/esm/internal-content-types/Backup.js +2 -2
- package/dist/esm/internal-content-types/BackupDocument.d.ts +162 -162
- package/dist/esm/internal-content-types/BackupDocument.js +2 -2
- package/dist/esm/internal-content-types/ContentComment.d.ts +1789 -1789
- package/dist/esm/internal-content-types/ContentComment.js +3 -3
- package/dist/esm/internal-content-types/ContentCommentReadState.d.ts +1253 -1253
- package/dist/esm/internal-content-types/ContentCommentReadState.js +3 -3
- package/dist/esm/internal-content-types/ContentReview.d.ts +5858 -5858
- package/dist/esm/internal-content-types/ContentReview.js +4 -4
- package/dist/esm/internal-content-types/ContentReviewDecision.d.ts +1245 -1245
- package/dist/esm/internal-content-types/ContentReviewDecision.js +3 -3
- package/dist/esm/internal-content-types/ContentReviewPolicy.d.ts +516 -516
- package/dist/esm/internal-content-types/ContentReviewPolicy.js +3 -3
- package/dist/esm/internal-content-types/ContentTemplate.d.ts +106 -106
- package/dist/esm/internal-content-types/ContentTemplate.js +2 -2
- package/dist/esm/internal-content-types/ContentVersion.d.ts +338 -338
- package/dist/esm/internal-content-types/ContentVersion.js +2 -2
- package/dist/esm/internal-content-types/HelloWorld.d.ts +42 -42
- package/dist/esm/internal-content-types/HelloWorld.js +2 -2
- package/dist/esm/internal-content-types/Language.d.ts +81 -81
- package/dist/esm/internal-content-types/Language.js +2 -2
- package/dist/esm/internal-content-types/LiteralTranslation.d.ts +83 -83
- package/dist/esm/internal-content-types/LiteralTranslation.js +2 -2
- package/dist/esm/internal-content-types/LlmsSettings.d.ts +762 -762
- package/dist/esm/internal-content-types/LlmsSettings.js +2 -2
- package/dist/esm/internal-content-types/LoginIpBlock.d.ts +98 -98
- package/dist/esm/internal-content-types/LoginIpBlock.js +2 -2
- package/dist/esm/internal-content-types/ManagerFavorite.d.ts +1213 -1213
- package/dist/esm/internal-content-types/ManagerFavorite.js +3 -3
- package/dist/esm/internal-content-types/ManagerNotification.d.ts +2500 -2500
- package/dist/esm/internal-content-types/ManagerNotification.js +3 -3
- package/dist/esm/internal-content-types/ManagerRole.d.ts +47 -47
- package/dist/esm/internal-content-types/ManagerRole.js +2 -2
- package/dist/esm/internal-content-types/ManagerRoleHooks.d.ts +2 -2
- package/dist/esm/internal-content-types/ManagerRoleHooks.js +3 -3
- package/dist/esm/internal-content-types/ManagerUser.d.ts +532 -532
- package/dist/esm/internal-content-types/ManagerUser.js +3 -3
- package/dist/esm/internal-content-types/ManagerUserHooks.d.ts +2 -2
- package/dist/esm/internal-content-types/ManagerUserHooks.js +3 -3
- package/dist/esm/internal-content-types/Media.d.ts +1187 -1187
- package/dist/esm/internal-content-types/Media.js +3 -3
- package/dist/esm/internal-content-types/MediaFolder.d.ts +192 -192
- package/dist/esm/internal-content-types/MediaFolder.js +2 -2
- package/dist/esm/internal-content-types/MfaChallenge.d.ts +1301 -1301
- package/dist/esm/internal-content-types/MfaChallenge.js +3 -3
- package/dist/esm/internal-content-types/Migration.d.ts +330 -330
- package/dist/esm/internal-content-types/Migration.js +2 -2
- package/dist/esm/internal-content-types/MigrationLock.d.ts +18 -18
- package/dist/esm/internal-content-types/MigrationLock.js +2 -2
- package/dist/esm/internal-content-types/Page.d.ts +121 -121
- package/dist/esm/internal-content-types/Page.js +3 -3
- package/dist/esm/internal-content-types/PasswordResetToken.d.ts +1205 -1205
- package/dist/esm/internal-content-types/PasswordResetToken.js +4 -4
- package/dist/esm/internal-content-types/PreviewSnapshot.d.ts +378 -378
- package/dist/esm/internal-content-types/PreviewSnapshot.js +2 -2
- package/dist/esm/internal-content-types/Redirect.d.ts +378 -378
- package/dist/esm/internal-content-types/Redirect.js +2 -2
- package/dist/esm/internal-content-types/RobotsRule.d.ts +250 -250
- package/dist/esm/internal-content-types/RobotsRule.js +2 -2
- package/dist/esm/internal-content-types/Route.d.ts +232 -232
- package/dist/esm/internal-content-types/Route.js +2 -2
- package/dist/esm/internal-content-types/RouteLayoutModule.d.ts +266 -266
- package/dist/esm/internal-content-types/RouteLayoutModule.js +2 -2
- package/dist/esm/internal-content-types/RouteLayoutModuleOverride.d.ts +242 -242
- package/dist/esm/internal-content-types/RouteLayoutModuleOverride.js +2 -2
- package/dist/esm/internal-content-types/RouteLocaleVariant.d.ts +242 -242
- package/dist/esm/internal-content-types/RouteLocaleVariant.js +2 -2
- package/dist/esm/internal-content-types/RouteMap.d.ts +258 -258
- package/dist/esm/internal-content-types/RouteMap.js +2 -2
- package/dist/esm/internal-content-types/RouteSettings.d.ts +340 -340
- package/dist/esm/internal-content-types/RouteSettings.js +3 -3
- package/dist/esm/internal-content-types/SchemaState.d.ts +82 -82
- package/dist/esm/internal-content-types/SchemaState.js +2 -2
- package/dist/esm/internal-content-types/Seo.d.ts +738 -738
- package/dist/esm/internal-content-types/Seo.js +2 -2
- package/dist/esm/internal-content-types/SeoAudit.d.ts +418 -418
- package/dist/esm/internal-content-types/SeoAudit.js +2 -2
- package/dist/esm/internal-content-types/SeoSettings.d.ts +1982 -1982
- package/dist/esm/internal-content-types/SeoSettings.js +3 -3
- package/dist/esm/internal-content-types/Session.d.ts +1189 -1189
- package/dist/esm/internal-content-types/Session.js +3 -3
- package/dist/esm/internal-content-types/StructuredData.d.ts +694 -694
- package/dist/esm/internal-content-types/StructuredData.js +2 -2
- package/dist/esm/internal-content-types/TemplateContent.d.ts +1 -1
- package/dist/esm/internal-content-types/TemplateContent.js +1 -1
- package/dist/esm/internal-content-types/UserMfa.d.ts +1290 -1290
- package/dist/esm/internal-content-types/UserMfa.js +4 -4
- package/dist/esm/internal-content-types/WebAuthnCredential.d.ts +1317 -1317
- package/dist/esm/internal-content-types/WebAuthnCredential.js +3 -3
- package/dist/esm/internal-content-types/WebAuthnRegChallenge.d.ts +1245 -1245
- package/dist/esm/internal-content-types/WebAuthnRegChallenge.js +3 -3
- package/dist/esm/internal-content-types/index.d.ts +45 -45
- package/dist/esm/internal-content-types/index.js +45 -45
- package/dist/esm/internal-content-types/syncAdminRole.d.ts +4 -4
- package/dist/esm/internal-content-types/syncAdminRole.js +4 -4
- package/dist/esm/lib/ContentType.d.ts +7 -7
- package/dist/esm/lib/ContentType.js +5 -5
- package/dist/esm/lib/Permissions.d.ts +2 -2
- package/dist/esm/lib/Permissions.js +4 -4
- package/dist/esm/lib/Registry.d.ts +6 -6
- package/dist/esm/lib/Registry.js +4 -4
- package/dist/esm/lib/errors/AppError.d.ts +1 -1
- package/dist/esm/lib/errors/AppError.js +1 -1
- package/dist/esm/lib/errors/index.d.ts +4 -4
- package/dist/esm/lib/errors/index.js +3 -3
- package/dist/esm/lib/errors/throwAppError.d.ts +1 -1
- package/dist/esm/lib/errors/throwAppError.js +3 -3
- package/dist/esm/lib/fields/Boolean.d.ts +1 -1
- package/dist/esm/lib/fields/Boolean.js +1 -1
- package/dist/esm/lib/fields/Breadcrums.d.ts +1 -1
- package/dist/esm/lib/fields/Breadcrums.js +1 -1
- package/dist/esm/lib/fields/ContentReference.d.ts +2 -2
- package/dist/esm/lib/fields/ContentReference.js +2 -2
- package/dist/esm/lib/fields/Date.d.ts +1 -1
- package/dist/esm/lib/fields/Date.js +1 -1
- package/dist/esm/lib/fields/Field.d.ts +15 -15
- package/dist/esm/lib/fields/Fields.d.ts +15 -15
- package/dist/esm/lib/fields/Fields.js +15 -15
- package/dist/esm/lib/fields/File.d.ts +1 -1
- package/dist/esm/lib/fields/File.js +2 -2
- package/dist/esm/lib/fields/Iterator.d.ts +3 -3
- package/dist/esm/lib/fields/Iterator.js +3 -3
- package/dist/esm/lib/fields/Link.d.ts +1 -1
- package/dist/esm/lib/fields/Link.js +2 -2
- package/dist/esm/lib/fields/List.d.ts +1 -1
- package/dist/esm/lib/fields/List.js +2 -2
- package/dist/esm/lib/fields/Menu.d.ts +2 -2
- package/dist/esm/lib/fields/Menu.js +2 -2
- package/dist/esm/lib/fields/Number.d.ts +1 -1
- package/dist/esm/lib/fields/Number.js +1 -1
- package/dist/esm/lib/fields/Relation.d.ts +3 -3
- package/dist/esm/lib/fields/Relation.js +3 -3
- package/dist/esm/lib/fields/Select.d.ts +1 -1
- package/dist/esm/lib/fields/Select.js +1 -1
- package/dist/esm/lib/fields/SelfRelation.d.ts +1 -1
- package/dist/esm/lib/fields/SelfRelation.js +2 -2
- package/dist/esm/lib/fields/SimpleList.d.ts +1 -1
- package/dist/esm/lib/fields/SimpleList.js +1 -1
- package/dist/esm/lib/fields/String.d.ts +1 -1
- package/dist/esm/lib/fields/String.js +3 -3
- package/dist/esm/lib/fields/index.d.ts +17 -17
- package/dist/esm/lib/fields/index.js +17 -17
- package/dist/esm/lib/hooks.d.ts +4 -4
- package/dist/esm/lib/routeableContent.js +1 -1
- package/dist/esm/lib/types/index.d.ts +2 -2
- package/dist/esm/lib/utils/getListField.d.ts +1 -1
- package/dist/esm/lib/utils/getSchemas.d.ts +1 -1
- package/dist/esm/lib/utils/getTranslation.d.ts +2 -2
- package/dist/esm/lib/utils/getTranslation.js +1 -1
- package/dist/esm/lib/utils/isRecord.d.ts +2 -0
- package/dist/esm/lib/utils/isRecord.d.ts.map +1 -0
- package/dist/esm/lib/utils/isRecord.js +5 -0
- package/dist/esm/lib/utils/isRecord.js.map +1 -0
- package/dist/esm/lib/utils/isTranslatableObject.d.ts +1 -1
- package/dist/esm/lib/utils/translateObject.d.ts +2 -2
- package/dist/esm/lib/utils/translateObject.js +3 -3
- package/dist/esm/literals/definitions.d.ts +1 -1
- package/dist/esm/literals/definitions.js +1 -1
- package/dist/esm/literals/index.d.ts +2 -2
- package/dist/esm/literals/index.js +2 -2
- package/dist/esm/mail/index.d.ts +6 -6
- package/dist/esm/mail/index.js +5 -5
- package/dist/esm/mail/mailService.d.ts +2 -2
- package/dist/esm/mail/mailService.d.ts.map +1 -1
- package/dist/esm/mail/mailService.js +3 -2
- package/dist/esm/mail/mailService.js.map +1 -1
- package/dist/esm/mail/templates.d.ts +1 -1
- package/dist/esm/mail/templates.js +2 -2
- package/dist/esm/manager.d.ts +33 -3
- package/dist/esm/manager.d.ts.map +1 -1
- package/dist/esm/manager.js +1 -1
- package/dist/esm/media/adapters/index.d.ts +20 -0
- package/dist/esm/media/adapters/index.d.ts.map +1 -1
- package/dist/esm/media/imageOptimization.d.ts +1 -1
- package/dist/esm/media/imageOptimization.d.ts.map +1 -1
- package/dist/esm/media/imageOptimization.js +23 -33
- package/dist/esm/media/imageOptimization.js.map +1 -1
- package/dist/esm/media/index.d.ts +5 -4
- package/dist/esm/media/index.d.ts.map +1 -1
- package/dist/esm/media/index.js +4 -3
- package/dist/esm/media/index.js.map +1 -1
- package/dist/esm/media/mediaOptimization.d.ts +2 -2
- package/dist/esm/media/mediaOptimization.js +2 -2
- package/dist/esm/media/mediaService.d.ts +1 -1
- package/dist/esm/media/mediaService.d.ts.map +1 -1
- package/dist/esm/media/mediaService.js +2 -2
- package/dist/esm/media/mediaService.js.map +1 -1
- package/dist/esm/media/publicMedia.d.ts +7 -0
- package/dist/esm/media/publicMedia.d.ts.map +1 -0
- package/dist/esm/media/publicMedia.js +109 -0
- package/dist/esm/media/publicMedia.js.map +1 -0
- package/dist/esm/media/videoOptimization.d.ts +2 -2
- package/dist/esm/media/videoOptimization.d.ts.map +1 -1
- package/dist/esm/media/videoOptimization.js +13 -26
- package/dist/esm/media/videoOptimization.js.map +1 -1
- package/dist/esm/orm/backups.js +5 -5
- package/dist/esm/orm/createIndexes.js +4 -4
- package/dist/esm/orm/database.js +3 -3
- package/dist/esm/orm/dbService.d.ts +6 -6
- package/dist/esm/orm/index.d.ts +2 -2
- package/dist/esm/orm/index.js +16 -16
- package/dist/esm/orm/migrations.d.ts +1 -1
- package/dist/esm/orm/migrations.js +4 -4
- package/dist/esm/orm/mongodbPeer.js +1 -1
- package/dist/esm/orm/operations/clear.d.ts +2 -2
- package/dist/esm/orm/operations/clear.js +1 -1
- package/dist/esm/orm/operations/create.d.ts +4 -4
- package/dist/esm/orm/operations/create.js +7 -7
- package/dist/esm/orm/operations/delete.d.ts +3 -3
- package/dist/esm/orm/operations/delete.js +5 -5
- package/dist/esm/orm/operations/find.d.ts +2 -2
- package/dist/esm/orm/operations/find.js +3 -3
- package/dist/esm/orm/operations/findDependencies.d.ts +2 -2
- package/dist/esm/orm/operations/findDependencies.js +4 -4
- package/dist/esm/orm/operations/get.d.ts +3 -3
- package/dist/esm/orm/operations/get.js +3 -3
- package/dist/esm/orm/operations/getAll.d.ts +2 -2
- package/dist/esm/orm/operations/getAll.js +2 -2
- package/dist/esm/orm/operations/list.d.ts +2 -2
- package/dist/esm/orm/operations/list.js +3 -3
- package/dist/esm/orm/operations/update.d.ts +5 -5
- package/dist/esm/orm/operations/update.js +8 -8
- package/dist/esm/orm/operations/updateMany.d.ts +4 -4
- package/dist/esm/orm/operations/updateMany.js +4 -4
- package/dist/esm/orm/operations/upsert.d.ts +3 -3
- package/dist/esm/orm/operations/upsert.js +4 -4
- package/dist/esm/orm/utils/deepDeleteNulls.js +1 -1
- package/dist/esm/orm/utils/parseId.d.ts +1 -1
- package/dist/esm/orm/utils/parseId.js +1 -1
- package/dist/esm/orm/utils/transformObjectIdsToStrings.js +1 -1
- package/dist/esm/orm/utils/transformStringToObjectIds.js +1 -1
- package/dist/esm/orm/versions.d.ts +1 -1
- package/dist/esm/orm/versions.js +7 -7
- package/dist/esm/platform/image.d.ts +5 -0
- package/dist/esm/platform/image.d.ts.map +1 -0
- package/dist/esm/platform/image.js +134 -0
- package/dist/esm/platform/image.js.map +1 -0
- package/dist/esm/platform/index.d.ts +13 -0
- package/dist/esm/platform/index.d.ts.map +1 -0
- package/dist/esm/platform/index.js +34 -0
- package/dist/esm/platform/index.js.map +1 -0
- package/dist/esm/platform/node.d.ts +6 -0
- package/dist/esm/platform/node.d.ts.map +1 -0
- package/dist/esm/platform/node.js +43 -0
- package/dist/esm/platform/node.js.map +1 -0
- package/dist/esm/platform/realtime.d.ts +10 -0
- package/dist/esm/platform/realtime.d.ts.map +1 -0
- package/dist/esm/platform/realtime.js +49 -0
- package/dist/esm/platform/realtime.js.map +1 -0
- package/dist/esm/platform/realtimeServer.d.ts +26 -0
- package/dist/esm/platform/realtimeServer.d.ts.map +1 -0
- package/dist/esm/platform/realtimeServer.js +118 -0
- package/dist/esm/platform/realtimeServer.js.map +1 -0
- package/dist/esm/platform/realtimeTopics.d.ts +7 -0
- package/dist/esm/platform/realtimeTopics.d.ts.map +1 -0
- package/dist/esm/platform/realtimeTopics.js +7 -0
- package/dist/esm/platform/realtimeTopics.js.map +1 -0
- package/dist/esm/platform/runtime.d.ts +4 -0
- package/dist/esm/platform/runtime.d.ts.map +1 -0
- package/dist/esm/platform/runtime.js +3 -0
- package/dist/esm/platform/runtime.js.map +1 -0
- package/dist/esm/platform/types.d.ts +94 -0
- package/dist/esm/platform/types.d.ts.map +1 -0
- package/dist/esm/platform/types.js +2 -0
- package/dist/esm/platform/types.js.map +1 -0
- package/dist/esm/plugins.d.ts +11 -11
- package/dist/esm/schemas/manager/auth/externalLogin.js +1 -1
- package/dist/esm/schemas/manager/collaborationPresence.d.ts +20 -0
- package/dist/esm/schemas/manager/collaborationPresence.d.ts.map +1 -0
- package/dist/esm/schemas/manager/collaborationPresence.js +16 -0
- package/dist/esm/schemas/manager/collaborationPresence.js.map +1 -0
- package/dist/esm/schemas/manager/comments.js +1 -1
- package/dist/esm/schemas/manager/contentCollaboration.d.ts +51 -0
- package/dist/esm/schemas/manager/contentCollaboration.d.ts.map +1 -0
- package/dist/esm/schemas/manager/contentCollaboration.js +30 -0
- package/dist/esm/schemas/manager/contentCollaboration.js.map +1 -0
- package/dist/esm/schemas/manager/contentVersions.d.ts +64 -64
- package/dist/esm/schemas/manager/contentVersions.js +3 -3
- package/dist/esm/schemas/manager/literals/upsert.js +1 -1
- package/dist/esm/schemas/manager/localeVariants.d.ts +96 -96
- package/dist/esm/schemas/manager/localeVariants.js +1 -1
- package/dist/esm/schemas/manager/media/finalizeUpload.js +1 -1
- package/dist/esm/schemas/manager/media/getMediaUrl.js +1 -1
- package/dist/esm/schemas/manager/media/listFolders.js +1 -1
- package/dist/esm/schemas/manager/media/reimportMedia.d.ts +1 -1
- package/dist/esm/schemas/manager/media/reimportMedia.js +2 -2
- package/dist/esm/schemas/manager/media/replaceMedia.js +1 -1
- package/dist/esm/schemas/manager/notifications.js +1 -1
- package/dist/esm/schemas/manager/reviews.js +1 -1
- package/dist/esm/schemas/manager/templateCollaboration.d.ts +54 -0
- package/dist/esm/schemas/manager/templateCollaboration.d.ts.map +1 -0
- package/dist/esm/schemas/manager/templateCollaboration.js +30 -0
- package/dist/esm/schemas/manager/templateCollaboration.js.map +1 -0
- package/dist/esm/schemas/manager/uiLocales.d.ts +9 -0
- package/dist/esm/schemas/manager/uiLocales.d.ts.map +1 -1
- package/dist/esm/schemas/manager/uiLocales.js +13 -1
- package/dist/esm/schemas/manager/uiLocales.js.map +1 -1
- package/dist/esm/schemas/web/page.d.ts +40 -40
- package/dist/esm/schemas/web/page.js +1 -1
- package/dist/esm/schemas/web/previewPage.d.ts +28 -28
- package/dist/esm/schemas/web/previewPage.js +1 -1
- package/dist/esm/translation/document.d.ts +3 -3
- package/dist/esm/translation/document.d.ts.map +1 -1
- package/dist/esm/translation/document.js +1 -1
- package/dist/esm/translation/document.js.map +1 -1
- package/dist/esm/translation/index.d.ts +4 -4
- package/dist/esm/translation/index.js +3 -3
- package/dist/esm/translation/translationService.d.ts +1 -1
- package/dist/esm/web/client.d.ts +1 -1
- package/dist/esm/web/client.js +1 -1
- package/dist/esm/web/index.d.ts +2 -2
- package/dist/esm/web/index.js +2 -2
- package/dist/esm/web/page.d.ts +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +150 -140
package/README.md
CHANGED
|
@@ -1,1280 +1,1395 @@
|
|
|
1
|
-
# @rakun-kit/core
|
|
2
|
-
|
|
3
|
-
`@rakun-kit/core` contains Rakun's shared domain model and runtime. It defines content types, fields, Zod schemas, manager/web operations, request context, MongoDB connection handling, media service, permissions, translations, and typed contracts used by adapters (`@rakun-kit/next`, `@rakun-kit/express`, `@rakun-kit/trpc`) and the manager client.
|
|
4
|
-
|
|
5
|
-
## Main Entry
|
|
6
|
-
|
|
7
|
-
Typical imports:
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
import { ContentType, f, rakunBootstrap, ensureRakunInitialized } from '@rakun-kit/core'
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
The main entrypoint exports:
|
|
14
|
-
|
|
15
|
-
- Bootstrap: `rakunBootstrap`, `ensureRakunBootstrap`, `ensureRakunInitialized`, `getRakunBootstrapOptions`.
|
|
16
|
-
- Context: `createRequestContext`, `getSessionCookie`, `setSessionCookie`.
|
|
17
|
-
- Operations: manager/web contracts and definitions.
|
|
18
|
-
- Media: `createMediaService`, `getMediaService`, adapters, and types.
|
|
19
|
-
- Mail: `createMailService`, `sendMail`, typed template registries, adapters, and types.
|
|
20
|
-
- Permissions, translations, errors, contracts, and public types.
|
|
21
|
-
- Basic internal content types: `Language`, `ManagerUser`, `Seo`.
|
|
22
|
-
|
|
23
|
-
Relevant subpaths:
|
|
24
|
-
|
|
25
|
-
- `@rakun-kit/core/manager`: manager operation metadata and types.
|
|
26
|
-
- `@rakun-kit/core/contracts`: shared manager/web payload schemas.
|
|
27
|
-
- `@rakun-kit/core/client`: client-facing types and utilities.
|
|
28
|
-
- `@rakun-kit/core/logger`: logger.
|
|
29
|
-
- `@rakun-kit/core/errors`: application errors.
|
|
30
|
-
- `@rakun-kit/core/types`: types derived from content types.
|
|
31
|
-
|
|
32
|
-
## Bootstrap
|
|
33
|
-
|
|
34
|
-
`rakunBootstrap(options)` registers global configuration and content types:
|
|
35
|
-
|
|
36
|
-
```ts
|
|
37
|
-
rakunBootstrap({
|
|
38
|
-
literals,
|
|
39
|
-
contentTypes: [Page, Post],
|
|
40
|
-
routes,
|
|
41
|
-
apiOperations,
|
|
42
|
-
mongo: {
|
|
43
|
-
MONGO_URI: process.env.MONGO_URI!,
|
|
44
|
-
ENVIRONMENT: process.env.NODE_ENV === 'test' ? 'test' : 'production',
|
|
45
|
-
},
|
|
46
|
-
media,
|
|
47
|
-
logger: {
|
|
48
|
-
level: 'info',
|
|
49
|
-
prettify: true,
|
|
50
|
-
},
|
|
51
|
-
syncRoutes: true,
|
|
52
|
-
})
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
Options:
|
|
56
|
-
|
|
57
|
-
- `literals`: text/translation catalog.
|
|
58
|
-
- `contentTypes`: application content types.
|
|
59
|
-
- `internalContentTypes`: optional overrides for Rakun internal content types, currently `Page`.
|
|
60
|
-
- `routes`: configured routes used to resolve pages.
|
|
61
|
-
- `apiOperations`: custom API operations added to the Rakun operation registry.
|
|
62
|
-
- `mongo`: MongoDB connection. Required before serving Rakun requests.
|
|
63
|
-
- `media`: media adapter/configuration. Optional.
|
|
64
|
-
- `mail`: outbound mail adapter and default sender configuration. Optional.
|
|
65
|
-
- `
|
|
66
|
-
|
|
67
|
-
- `
|
|
68
|
-
|
|
69
|
-
- `
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
})
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
```ts
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
},
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
`
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
`
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
`
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
},
|
|
660
|
-
}
|
|
661
|
-
```
|
|
662
|
-
|
|
663
|
-
The manager
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
},
|
|
688
|
-
})
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
- `
|
|
824
|
-
- `
|
|
825
|
-
- `
|
|
826
|
-
- `
|
|
827
|
-
- `
|
|
828
|
-
- `
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
- `
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
`
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
`
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
- `
|
|
898
|
-
- `
|
|
899
|
-
- `
|
|
900
|
-
- `
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
`@rakun-kit/core/
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
```ts
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
- `
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
`
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
`
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1
|
+
# @rakun-kit/core
|
|
2
|
+
|
|
3
|
+
`@rakun-kit/core` contains Rakun's shared domain model and runtime. It defines content types, fields, Zod schemas, manager/web operations, request context, MongoDB connection handling, media service, permissions, translations, and typed contracts used by adapters (`@rakun-kit/next`, `@rakun-kit/express`, `@rakun-kit/trpc`) and the manager client.
|
|
4
|
+
|
|
5
|
+
## Main Entry
|
|
6
|
+
|
|
7
|
+
Typical imports:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { ContentType, f, rakunBootstrap, ensureRakunInitialized } from '@rakun-kit/core'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The main entrypoint exports:
|
|
14
|
+
|
|
15
|
+
- Bootstrap: `rakunBootstrap`, `ensureRakunBootstrap`, `ensureRakunInitialized`, `getRakunBootstrapOptions`.
|
|
16
|
+
- Context: `createRequestContext`, `getSessionCookie`, `setSessionCookie`.
|
|
17
|
+
- Operations: manager/web contracts and definitions.
|
|
18
|
+
- Media: `createMediaService`, `getMediaService`, adapters, and types.
|
|
19
|
+
- Mail: `createMailService`, `sendMail`, typed template registries, adapters, and types.
|
|
20
|
+
- Permissions, translations, errors, contracts, and public types.
|
|
21
|
+
- Basic internal content types: `Language`, `ManagerUser`, `Seo`.
|
|
22
|
+
|
|
23
|
+
Relevant subpaths:
|
|
24
|
+
|
|
25
|
+
- `@rakun-kit/core/manager`: manager operation metadata and types.
|
|
26
|
+
- `@rakun-kit/core/contracts`: shared manager/web payload schemas.
|
|
27
|
+
- `@rakun-kit/core/client`: client-facing types and utilities.
|
|
28
|
+
- `@rakun-kit/core/logger`: logger.
|
|
29
|
+
- `@rakun-kit/core/errors`: application errors.
|
|
30
|
+
- `@rakun-kit/core/types`: types derived from content types.
|
|
31
|
+
|
|
32
|
+
## Bootstrap
|
|
33
|
+
|
|
34
|
+
`rakunBootstrap(options)` registers global configuration and content types:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
rakunBootstrap({
|
|
38
|
+
literals,
|
|
39
|
+
contentTypes: [Page, Post],
|
|
40
|
+
routes,
|
|
41
|
+
apiOperations,
|
|
42
|
+
mongo: {
|
|
43
|
+
MONGO_URI: process.env.MONGO_URI!,
|
|
44
|
+
ENVIRONMENT: process.env.NODE_ENV === 'test' ? 'test' : 'production',
|
|
45
|
+
},
|
|
46
|
+
media,
|
|
47
|
+
logger: {
|
|
48
|
+
level: 'info',
|
|
49
|
+
prettify: true,
|
|
50
|
+
},
|
|
51
|
+
syncRoutes: true,
|
|
52
|
+
})
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Options:
|
|
56
|
+
|
|
57
|
+
- `literals`: text/translation catalog.
|
|
58
|
+
- `contentTypes`: application content types.
|
|
59
|
+
- `internalContentTypes`: optional overrides for Rakun internal content types, currently `Page`.
|
|
60
|
+
- `routes`: configured routes used to resolve pages.
|
|
61
|
+
- `apiOperations`: custom API operations added to the Rakun operation registry.
|
|
62
|
+
- `mongo`: MongoDB connection. Required before serving Rakun requests.
|
|
63
|
+
- `media`: media adapter/configuration. Optional.
|
|
64
|
+
- `mail`: outbound mail adapter and default sender configuration. Optional.
|
|
65
|
+
- `collaboration`: storage adapter for unsaved Yjs content working documents.
|
|
66
|
+
Optional; defaults to process memory.
|
|
67
|
+
- `accountRecovery`: password-reset URL builder, expiry, and optional custom
|
|
68
|
+
mail template. Requires `mail`; core provides the default template.
|
|
69
|
+
- `login`: manager password-login toggle and external login adapters.
|
|
70
|
+
- `logger`: logger configuration. If omitted, an `info` logger with `prettify` is created.
|
|
71
|
+
- `syncRoutes`: syncs configured routes during initialization. Enabled by default.
|
|
72
|
+
|
|
73
|
+
## Runtime Platform
|
|
74
|
+
|
|
75
|
+
`rakunBootstrap` accepts an optional resolved `platform`. Without one, Rakun
|
|
76
|
+
detects Bun through `process.versions.bun` and otherwise uses Node.js defaults.
|
|
77
|
+
Runtime, framework, and deployment are separate values, and every capability
|
|
78
|
+
can be overridden without configuring the rest:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { createPlatform, pollingRealtime, sharpImage } from '@rakun-kit/core'
|
|
82
|
+
|
|
83
|
+
rakunBootstrap({
|
|
84
|
+
...options,
|
|
85
|
+
platform: createPlatform({
|
|
86
|
+
deployment: 'serverless',
|
|
87
|
+
image: sharpImage(),
|
|
88
|
+
realtime: pollingRealtime({ intervalMs: 5_000 }),
|
|
89
|
+
}),
|
|
90
|
+
})
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The default image processor is native `Bun.Image` when available and `sharp`
|
|
94
|
+
otherwise. Node.js image optimization therefore requires the optional `sharp`
|
|
95
|
+
peer. Bun also falls back to it when an OS-dependent codec cannot handle the
|
|
96
|
+
requested format. Custom `ImageProcessor` implementations provide
|
|
97
|
+
`metadata`, `transform`, and `placeholder`; the latter returns an inline
|
|
98
|
+
`{ dataUrl, mime }` LQIP. Bun uses native `Bun.Image.placeholder()`, while
|
|
99
|
+
Sharp produces the placeholder through its normal reduced transform and serves
|
|
100
|
+
as the fallback when the Bun method is unavailable. The
|
|
101
|
+
platform resolves crypto, filesystem, compression,
|
|
102
|
+
workers, and realtime capabilities. Polling is the safe realtime default when
|
|
103
|
+
the host cannot keep persistent connections open. The Next and Express
|
|
104
|
+
adapters automatically serve configured SSE streams.
|
|
105
|
+
Calling `sseRealtime()` uses the API-relative `/realtime` endpoint; pass an
|
|
106
|
+
explicit `endpoint` only when the public route differs.
|
|
107
|
+
|
|
108
|
+
The manager bootstrap exposes only the safe transport metadata from this
|
|
109
|
+
provider. Manager mutations publish invalidation topics for collaborative
|
|
110
|
+
documents, locale variants, versions, comments, and notifications. Event
|
|
111
|
+
transports therefore refresh matching queries on demand; polling keeps the
|
|
112
|
+
same behavior through its configured interval.
|
|
113
|
+
|
|
114
|
+
Server adapters share `parseRealtimeTopics`, `isRealtimeEndpointRequest`,
|
|
115
|
+
`createRealtimeSseStream`, and `authorizeRealtimeSubscription` from core. A
|
|
116
|
+
custom HTTP framework can use these primitives without importing either the
|
|
117
|
+
Next or Express adapter.
|
|
118
|
+
|
|
119
|
+
The built-in SSE provider uses an in-process topic broker. For multiple server
|
|
120
|
+
processes or replicas, provide a `RealtimeProvider` backed by a shared broker
|
|
121
|
+
while keeping the same transport metadata and subscription contract.
|
|
122
|
+
|
|
123
|
+
## Collaborative content documents
|
|
124
|
+
|
|
125
|
+
Every saved content document and draft has an independent Yjs working document
|
|
126
|
+
keyed by its content type and `_id`. Editor updates synchronize through the
|
|
127
|
+
authenticated `manager.contentCollaboration.sync` operation without changing
|
|
128
|
+
the MongoDB content snapshot or triggering revalidation. Save calls
|
|
129
|
+
`manager.contentCollaboration.save`, which materializes and validates the
|
|
130
|
+
server-side CRDT state before using the normal update and revalidation flow.
|
|
131
|
+
Draft promotion remains separate and promotes only a saved draft snapshot.
|
|
132
|
+
`manager.contentCollaboration.discard` restores the room from that persisted
|
|
133
|
+
snapshot, publishes the reset to connected editors, and marks the restored Yjs
|
|
134
|
+
state as saved without creating a new content revision. Shared templates expose
|
|
135
|
+
the equivalent `manager.templateCollaboration.discard` operation.
|
|
136
|
+
|
|
137
|
+
The default adapter keeps working documents in process memory. Configure a
|
|
138
|
+
shared, durable implementation for replicated or restart-durable deployments:
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
rakunBootstrap({
|
|
142
|
+
// ...
|
|
143
|
+
collaboration: {
|
|
144
|
+
adapter: {
|
|
145
|
+
load: async (roomId) => loadRoom(roomId),
|
|
146
|
+
save: async (roomId, state) => saveRoom(roomId, state),
|
|
147
|
+
loadPresence: async (roomId) => loadRoomPresence(roomId),
|
|
148
|
+
savePresence: async (roomId, presence) => saveRoomPresence(roomId, presence),
|
|
149
|
+
delete: async (roomId) => deleteRoom(roomId),
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
})
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
`state.update` and `state.savedStateVector` are opaque `Uint8Array` values.
|
|
156
|
+
Store them outside the public content record. The built-in manager applies this
|
|
157
|
+
to saved content edit screens and to each content type's shared Template.
|
|
158
|
+
Templates use their own `template:<contentType>` room rather than an individual
|
|
159
|
+
document room. Settings, route-layout overrides, and other administrative forms
|
|
160
|
+
remain local. Translation changes join the working document and are persisted
|
|
161
|
+
only by Save.
|
|
162
|
+
|
|
163
|
+
The sync response also includes ephemeral viewers keyed by browser-tab client
|
|
164
|
+
id, including the focused field. Presence expires automatically and is not
|
|
165
|
+
part of `state.update`, `state.savedStateVector`, or the persistent event log.
|
|
166
|
+
With SSE, the authenticated subscription owns the tab presence: server
|
|
167
|
+
heartbeats renew it and closing the last stream for that tab removes it, so the
|
|
168
|
+
manager does not send a periodic collaboration sync request just to stay
|
|
169
|
+
visible. Polling refreshes presence through its normal sync cycle.
|
|
170
|
+
`loadPresence` and `savePresence` are optional; implement both in replicated
|
|
171
|
+
deployments that need presence shared across processes.
|
|
172
|
+
|
|
173
|
+
`@rakun-kit/manager-react` additionally stores these Yjs rooms per user in
|
|
174
|
+
IndexedDB, allowing cached content and Template fields to remain editable during
|
|
175
|
+
temporary connection loss. Reconnection exchanges the local updates with core;
|
|
176
|
+
only an online Save commits them to the public content snapshot.
|
|
177
|
+
|
|
178
|
+
## External manager login
|
|
179
|
+
|
|
180
|
+
Configure external login methods in `rakunBootstrap`. The callback URL is the
|
|
181
|
+
manager's public `/login/callback` route.
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
import {
|
|
185
|
+
createGitHubLoginAdapter,
|
|
186
|
+
createGoogleLoginAdapter,
|
|
187
|
+
createMicrosoftLoginAdapter,
|
|
188
|
+
rakunBootstrap,
|
|
189
|
+
} from '@rakun-kit/core'
|
|
190
|
+
|
|
191
|
+
const callbackUrl = 'https://cms.example.com/backend/login/callback'
|
|
192
|
+
|
|
193
|
+
rakunBootstrap({
|
|
194
|
+
// ...
|
|
195
|
+
login: {
|
|
196
|
+
password: true,
|
|
197
|
+
adapters: [
|
|
198
|
+
createGitHubLoginAdapter({
|
|
199
|
+
clientId: process.env.GITHUB_CLIENT_ID!,
|
|
200
|
+
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
201
|
+
redirectUri: callbackUrl,
|
|
202
|
+
}),
|
|
203
|
+
createGoogleLoginAdapter({
|
|
204
|
+
clientId: process.env.GOOGLE_CLIENT_ID!,
|
|
205
|
+
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
|
|
206
|
+
redirectUri: callbackUrl,
|
|
207
|
+
}),
|
|
208
|
+
createMicrosoftLoginAdapter({
|
|
209
|
+
clientId: process.env.MICROSOFT_CLIENT_ID!,
|
|
210
|
+
clientSecret: process.env.MICROSOFT_CLIENT_SECRET!,
|
|
211
|
+
redirectUri: callbackUrl,
|
|
212
|
+
tenant: 'common',
|
|
213
|
+
}),
|
|
214
|
+
],
|
|
215
|
+
},
|
|
216
|
+
})
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Register the exact callback URL in each provider console. External identities
|
|
220
|
+
must return a verified email matching an
|
|
221
|
+
existing manager user. Rakun does not create manager accounts automatically.
|
|
222
|
+
The flow uses an HttpOnly state cookie and PKCE and preserves the existing MFA
|
|
223
|
+
step. Set `password: false` only when at least one adapter is configured.
|
|
224
|
+
Custom providers can be implemented with `defineLoginAdapter`.
|
|
225
|
+
|
|
226
|
+
### Persistent password-login IP blocking
|
|
227
|
+
|
|
228
|
+
Password login enables persistent fail2ban-style IP blocking by default. Five
|
|
229
|
+
failed attempts block the IP indefinitely; a successful login before reaching
|
|
230
|
+
the limit clears its failed-attempt counter. Configure or disable it through
|
|
231
|
+
`login.fail2ban`:
|
|
232
|
+
|
|
233
|
+
```ts
|
|
234
|
+
rakunBootstrap({
|
|
235
|
+
// ...
|
|
236
|
+
login: {
|
|
237
|
+
password: true,
|
|
238
|
+
fail2ban: {
|
|
239
|
+
maxAttempts: 5,
|
|
240
|
+
// Optional when the deployment uses a custom trusted proxy:
|
|
241
|
+
// resolveIp: (ctx) => ctx.req?.headers?.['your-trusted-ip-header'] as string,
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
})
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Users with the `auth.ipBlocks.manage` permission can inspect and remove blocks
|
|
248
|
+
under Manager Settings → Security. Admin roles receive this built-in permission
|
|
249
|
+
automatically. A block can also be removed directly from MongoDB by deleting
|
|
250
|
+
the matching document from the `LoginIpBlock` collection. Set `fail2ban: false`
|
|
251
|
+
to disable this behavior. External login adapters are not affected.
|
|
252
|
+
|
|
253
|
+
## Account recovery and MFA recovery
|
|
254
|
+
|
|
255
|
+
Password recovery is enabled when both `mail` and `accountRecovery` are
|
|
256
|
+
configured. The reset URL must point to the manager's public
|
|
257
|
+
`/reset-password` screen and preserve the token as the `token` query parameter:
|
|
258
|
+
|
|
259
|
+
```ts
|
|
260
|
+
import { rakunBootstrap } from '@rakun-kit/core'
|
|
261
|
+
import { createResendMailServiceConfig } from '@rakun-kit/resend'
|
|
262
|
+
|
|
263
|
+
rakunBootstrap({
|
|
264
|
+
// ...
|
|
265
|
+
mail: createResendMailServiceConfig({
|
|
266
|
+
apiKey: process.env.RESEND_API_KEY!,
|
|
267
|
+
defaultFrom: process.env.RAKUN_MAIL_FROM!,
|
|
268
|
+
}),
|
|
269
|
+
accountRecovery: {
|
|
270
|
+
passwordReset: {
|
|
271
|
+
expiresInMs: 60 * 60 * 1000,
|
|
272
|
+
createUrl: (token) =>
|
|
273
|
+
`https://cms.example.com/backend/reset-password?token=${encodeURIComponent(token)}`,
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
})
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Core uses its branded HTML and plain-text password-reset template by default.
|
|
280
|
+
Pass `accountRecovery.passwordReset.template` only when the application needs
|
|
281
|
+
to replace it with custom branding or copy.
|
|
282
|
+
|
|
283
|
+
Reset tokens are random, stored only as SHA-256 hashes, expire, and are consumed
|
|
284
|
+
once. A successful reset closes every existing session but never disables MFA.
|
|
285
|
+
The request endpoint always returns the same result for known and unknown email
|
|
286
|
+
addresses.
|
|
287
|
+
|
|
288
|
+
Enabling TOTP or the first WebAuthn device returns one-time recovery codes to
|
|
289
|
+
the manager UI. Only their hashes are persisted, each code is consumed after
|
|
290
|
+
one login, and users can replace the entire set from their account after
|
|
291
|
+
confirming their current password. MFA state cannot be disabled through generic
|
|
292
|
+
manager content operations. If a user loses all MFA methods and recovery codes,
|
|
293
|
+
recovery must be handled by an authorized person through a channel outside the
|
|
294
|
+
CMS.
|
|
295
|
+
|
|
296
|
+
Content types can define lifecycle `hooks` and opt into manager-selected
|
|
297
|
+
`dynamicData` sources.
|
|
298
|
+
|
|
299
|
+
Routes can define fixed layout module slots. Rakun syncs those slots and the
|
|
300
|
+
manager lets users select an existing entry for each route:
|
|
301
|
+
|
|
302
|
+
```ts
|
|
303
|
+
rakunBootstrap({
|
|
304
|
+
// ...
|
|
305
|
+
routes: [
|
|
306
|
+
{
|
|
307
|
+
key: 'pages',
|
|
308
|
+
contentType: 'Page',
|
|
309
|
+
field: 'slug',
|
|
310
|
+
hasPage: true,
|
|
311
|
+
dynamic: false,
|
|
312
|
+
defaultBasePath: '',
|
|
313
|
+
layout: [
|
|
314
|
+
{ key: 'header', contentType: 'Header' },
|
|
315
|
+
{ type: 'content' },
|
|
316
|
+
{ key: 'footer', contentType: 'Footer' },
|
|
317
|
+
],
|
|
318
|
+
},
|
|
319
|
+
],
|
|
320
|
+
})
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
The web page response includes an ordered `layout` array containing module slots
|
|
324
|
+
plus the content slot. This is the only module collection in the response:
|
|
325
|
+
content modules live in the `modules` property of the `content` layout item and
|
|
326
|
+
are not duplicated at the top level.
|
|
327
|
+
|
|
328
|
+
The response `info` object contains the page's normal resolved fields plus
|
|
329
|
+
route context such as `locale` and `variantGroupId`. Translated website literals
|
|
330
|
+
live in the separate top-level `literals` property. Composition-only fields
|
|
331
|
+
(`_iterator`, `_seo`, and the legacy `_iteratorUnlinked` marker) are removed
|
|
332
|
+
recursively from the page and all populated relations before `info` is sent.
|
|
333
|
+
|
|
334
|
+
## Module picker
|
|
335
|
+
|
|
336
|
+
Content types used as iterator modules can customize their card in the manager's
|
|
337
|
+
add-module dialog. `modulePicker.preview` accepts an image URL available to the
|
|
338
|
+
manager browser; relative URLs are also supported:
|
|
339
|
+
|
|
340
|
+
```ts
|
|
341
|
+
const Hero = new ContentType({
|
|
342
|
+
name: 'Hero',
|
|
343
|
+
modulePicker: {
|
|
344
|
+
title: 'Hero section',
|
|
345
|
+
description: 'Large introduction with heading, copy, and CTA.',
|
|
346
|
+
category: 'Marketing',
|
|
347
|
+
icon: 'PanelTop',
|
|
348
|
+
preview: '/images/modules/hero.webp',
|
|
349
|
+
keywords: ['banner', 'cover'],
|
|
350
|
+
},
|
|
351
|
+
fields: {
|
|
352
|
+
title: f.string().help('content.heroTitleHelp').required(),
|
|
353
|
+
},
|
|
354
|
+
})
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
When `preview` is omitted or cannot be loaded, the picker displays a neutral
|
|
358
|
+
placeholder so module cards keep a consistent height.
|
|
359
|
+
|
|
360
|
+
Use field `.help(text)` for longer, optional guidance. The manager places a help
|
|
361
|
+
icon beside that field and opens the text on demand, including inside iterator
|
|
362
|
+
and blocks modules. `text` may be direct copy or a manager translation key
|
|
363
|
+
supplied by the application locale packs. Use `.description(...)` instead for
|
|
364
|
+
short guidance that should remain visible below the field label.
|
|
365
|
+
|
|
366
|
+
`ensureRakunInitialized()` prepares logger, MongoDB, media, and route syncing. It uses a singleton promise to avoid concurrent initialization; if initialization fails, the promise is cleared so the next call can retry.
|
|
367
|
+
|
|
368
|
+
`ensureRakunBootstrap(options)` only calls `rakunBootstrap` if the runtime has not been bootstrapped yet.
|
|
369
|
+
|
|
370
|
+
English is built into `@rakun-kit/manager-react`. Install only the extra
|
|
371
|
+
manager UI locales an application needs:
|
|
372
|
+
|
|
373
|
+
```sh
|
|
374
|
+
bun add @rakun-kit/manager-locales
|
|
375
|
+
# or: npm install @rakun-kit/manager-locales
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Import the required language subpath and register it with `managerLanguages`;
|
|
379
|
+
the public `manager.uiLocales` operation returns configured packs to the
|
|
380
|
+
manager client. Its safe runtime configuration also includes the public SEO
|
|
381
|
+
`siteUrl` and the configured home-page variant group, when available, so the
|
|
382
|
+
manager can expose its Visit site action and classify SEO fallbacks correctly:
|
|
383
|
+
|
|
384
|
+
```ts
|
|
385
|
+
import { esManagerLocalePack } from '@rakun-kit/manager-locales/es'
|
|
386
|
+
|
|
387
|
+
rakunBootstrap({
|
|
388
|
+
// ...
|
|
389
|
+
managerLanguages: [esManagerLocalePack],
|
|
390
|
+
})
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
`managerLanguages` may also extend locales with arbitrary project keys. This is
|
|
394
|
+
useful for translatable content-type titles and categories without adding host
|
|
395
|
+
keys to the manager's static `ManagerMessageKey` union:
|
|
396
|
+
|
|
397
|
+
```ts
|
|
398
|
+
import { extendManagerLanguagePack } from '@rakun-kit/core/contracts'
|
|
399
|
+
import { esManagerLocalePack } from '@rakun-kit/manager-locales/es'
|
|
400
|
+
|
|
401
|
+
rakunBootstrap({
|
|
402
|
+
// ...
|
|
403
|
+
managerLanguages: [
|
|
404
|
+
{
|
|
405
|
+
code: 'en',
|
|
406
|
+
name: 'English',
|
|
407
|
+
messages: {
|
|
408
|
+
'field.title': 'Title',
|
|
409
|
+
'layoutModule.header': 'Header',
|
|
410
|
+
'project.contentTypes.article.menu': 'Articles',
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
extendManagerLanguagePack(esManagerLocalePack, {
|
|
414
|
+
'field.title': 'Título',
|
|
415
|
+
'layoutModule.header': 'Cabecera',
|
|
416
|
+
'project.contentTypes.article.menu': 'Artículos',
|
|
417
|
+
}),
|
|
418
|
+
],
|
|
419
|
+
})
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
Content-type field labels automatically use `field.<fieldName>` from these
|
|
423
|
+
project messages. Missing translations fall back to a built-in manager label
|
|
424
|
+
when available and otherwise to the humanized field name.
|
|
425
|
+
|
|
426
|
+
Route layout module labels use `layoutModule.<layoutKey>`, so a slot configured
|
|
427
|
+
with `key: 'header'` resolves `layoutModule.header`.
|
|
428
|
+
|
|
429
|
+
## Plugins
|
|
430
|
+
|
|
431
|
+
Trusted server plugins contribute to the same bootstrap registry without coupling
|
|
432
|
+
core to React:
|
|
433
|
+
|
|
434
|
+
```ts
|
|
435
|
+
import { defineRakunPlugin, rakunBootstrap } from '@rakun-kit/core'
|
|
436
|
+
|
|
437
|
+
export const analyticsPlugin = defineRakunPlugin({
|
|
438
|
+
id: '@acme/rakun-analytics',
|
|
439
|
+
contentTypes: [AnalyticsEvent],
|
|
440
|
+
routes: analyticsRoutes,
|
|
441
|
+
apiOperations: analyticsOperations,
|
|
442
|
+
permissions: ['plugin.analytics.view'],
|
|
443
|
+
literals: {},
|
|
444
|
+
initialize: async ({ db }) => {
|
|
445
|
+
// Services and migrations are ready here. Keep initialization idempotent.
|
|
446
|
+
},
|
|
447
|
+
})
|
|
448
|
+
|
|
449
|
+
rakunBootstrap({
|
|
450
|
+
plugins: [analyticsPlugin],
|
|
451
|
+
contentTypes: [],
|
|
452
|
+
literals: {},
|
|
453
|
+
mongo,
|
|
454
|
+
})
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
Plugin ids and contributed content types, routes, operations, literals, and
|
|
458
|
+
custom field editor ids must be unique. Rakun reports both owners on conflicts.
|
|
459
|
+
Visual manager and web facets are registered separately in their browser
|
|
460
|
+
runtimes.
|
|
461
|
+
|
|
462
|
+
Custom field factories can use `createPluginField`. Their serializable
|
|
463
|
+
`meta.editor` must match a field declaration in the server plugin and a React
|
|
464
|
+
editor registered by its manager facet. Each field also declares capabilities
|
|
465
|
+
that shared systems consume instead of branching on its built-in type:
|
|
466
|
+
|
|
467
|
+
```ts
|
|
468
|
+
const externalLink = createPluginField({
|
|
469
|
+
meta: {
|
|
470
|
+
type: 'Link',
|
|
471
|
+
ui: 'Link',
|
|
472
|
+
editor: '@acme/external-link',
|
|
473
|
+
capabilities: {
|
|
474
|
+
valueKind: 'object',
|
|
475
|
+
dynamic: {
|
|
476
|
+
properties: { title: 'string', href: 'string' },
|
|
477
|
+
mapProperties: true,
|
|
478
|
+
},
|
|
479
|
+
},
|
|
480
|
+
},
|
|
481
|
+
schemas: sameSchemas(() => ExternalLinkSchema),
|
|
482
|
+
runtime: {
|
|
483
|
+
populate: (value, { populateLink }) => populateLink(value),
|
|
484
|
+
},
|
|
485
|
+
})
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
`valueKind` controls Dynamic Data compatibility. `dynamic.properties` exposes
|
|
489
|
+
nested source paths, `mapProperties` makes those paths independent mapping
|
|
490
|
+
targets, `relation` enables content-type traversal, and `collection` describes
|
|
491
|
+
`homogeneous` or `heterogeneous` per-item mapping. Capabilities are encoded for
|
|
492
|
+
the manager. `runtime.populate` remains server-only and receives the database,
|
|
493
|
+
recursive `populate`, and built-in `populateLink` helpers. The web pipeline
|
|
494
|
+
exports this generic phase as `populateFields`; `populateLinks` remains a
|
|
495
|
+
deprecated compatibility alias.
|
|
496
|
+
|
|
497
|
+
## Content Types
|
|
498
|
+
|
|
499
|
+
A `ContentType` defines a logical collection:
|
|
500
|
+
|
|
501
|
+
```ts
|
|
502
|
+
const Post = new ContentType({
|
|
503
|
+
name: 'Post',
|
|
504
|
+
menu: {
|
|
505
|
+
title: 'Posts',
|
|
506
|
+
icon: 'newspaper',
|
|
507
|
+
category: 'Content',
|
|
508
|
+
},
|
|
509
|
+
fields: {
|
|
510
|
+
title: f.string(),
|
|
511
|
+
slug: f.string().type('Slug'),
|
|
512
|
+
body: f.string().type('RichText').optional(),
|
|
513
|
+
published: f.boolean().optional(),
|
|
514
|
+
},
|
|
515
|
+
uniques: [['slug']],
|
|
516
|
+
listFields: ['title', 'slug', 'published'],
|
|
517
|
+
})
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
Page-like content types can define ordered page modules with `iterator` outside
|
|
521
|
+
`fields`. Rakun persists this generated field as `_iterator`:
|
|
522
|
+
|
|
523
|
+
```ts
|
|
524
|
+
import { StructuredData } from '@rakun-kit/core/internal-content-types'
|
|
525
|
+
|
|
526
|
+
const Page = new ContentType({
|
|
527
|
+
name: 'Page',
|
|
528
|
+
fields: {
|
|
529
|
+
title: f.string(),
|
|
530
|
+
slug: f.string().type('Slug'),
|
|
531
|
+
},
|
|
532
|
+
iterator: [
|
|
533
|
+
{ contentType: PageSection, type: 'new' },
|
|
534
|
+
{ contentType: Hero, type: 'new' },
|
|
535
|
+
{ contentType: LayoutWithInfo, type: 'new' },
|
|
536
|
+
{ contentType: Newsletter, type: 'new' },
|
|
537
|
+
{ contentType: StructuredData, type: 'new' },
|
|
538
|
+
],
|
|
539
|
+
})
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
`StructuredData` is a built-in iterator module for JSON-LD. It provides typed
|
|
543
|
+
Product, Article, Organization, WebSite, and BreadcrumbList forms plus a Custom
|
|
544
|
+
JSON form. Add it to a shared Template and map its fields from the current
|
|
545
|
+
document to reuse one schema across every page of the content type. The official
|
|
546
|
+
React and Next renderers handle this module natively, so applications do not
|
|
547
|
+
create a matching component file.
|
|
548
|
+
|
|
549
|
+
`iterator` always belongs to the individual document and is edited in the
|
|
550
|
+
manager's Content tab. When the content type has a configured `hasPage: true`
|
|
551
|
+
route, Rakun automatically enables a separate shared Template tab with the
|
|
552
|
+
same module picker as Content. The manager also offers one special Content slot
|
|
553
|
+
at the template root and inside every `f.blocks(...)` field. The template must
|
|
554
|
+
contain that slot exactly once; web output replaces it with the current
|
|
555
|
+
document's iterator modules. This supports compositions such as a shared hero,
|
|
556
|
+
a `LayoutWithInfo` wrapper containing the unique content, and a shared
|
|
557
|
+
newsletter. Route layout modules such as header and footer still wrap the
|
|
558
|
+
assembled result.
|
|
559
|
+
|
|
560
|
+
Iterator and template modules can also be made conditional from the manager. A
|
|
561
|
+
condition is stored on the module entry and evaluated against the current
|
|
562
|
+
document:
|
|
563
|
+
|
|
564
|
+
```ts
|
|
565
|
+
{
|
|
566
|
+
name: "Credits",
|
|
567
|
+
value: { /* module relation */ },
|
|
568
|
+
visibleWhen: {
|
|
569
|
+
field: "credits",
|
|
570
|
+
operator: "notEmpty",
|
|
571
|
+
},
|
|
572
|
+
}
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
Supported operators are `notEmpty` and `empty`. Conditional modules remain in
|
|
576
|
+
their stored Content or Template composition but are omitted from web and
|
|
577
|
+
preview output when their condition does not match.
|
|
578
|
+
|
|
579
|
+
Main properties:
|
|
580
|
+
|
|
581
|
+
- `name`: stable type name. Also used as `_type`.
|
|
582
|
+
- `fields`: field map.
|
|
583
|
+
- `iterator`: page module entries. Generates the reserved `_iterator` field.
|
|
584
|
+
- `menu`: manager metadata.
|
|
585
|
+
- `uniques`: unique field groups.
|
|
586
|
+
- `listFields`: preferred fields in lists and relations.
|
|
587
|
+
- `hideFromManager()`: hides the content type from manager content type lists.
|
|
588
|
+
- `apiOnly()`: applies `.apiOnly()` to every field in the content type.
|
|
589
|
+
- `managerOnly()`: applies `.managerOnly()` to every field in the content type.
|
|
590
|
+
- Saved manager documents support comments and user mentions by default.
|
|
591
|
+
- `withHooks()`: attaches lifecycle hooks such as `beforeInsert`, `beforeUpdate`, and `onGet`.
|
|
592
|
+
- Dynamic data bindings are available on manager-visible fields by default; use
|
|
593
|
+
field-level `.noDynamic()` to opt out.
|
|
594
|
+
- A string field can initialize a new document's SEO dynamic data with
|
|
595
|
+
`.seo('title')`, `.seo('description')`, or another string field from Rakun's
|
|
596
|
+
built-in SEO model. This does not change existing documents.
|
|
597
|
+
|
|
598
|
+
When a content type has a configured route with `hasPage: true`, Rakun adds an
|
|
599
|
+
optional reserved `_seo` relation automatically. If that content type has an
|
|
600
|
+
`iterator`, Rakun also enables its shared Template editor automatically.
|
|
601
|
+
|
|
602
|
+
Hooks run around DB mutations and public output resolution:
|
|
603
|
+
|
|
604
|
+
```ts
|
|
605
|
+
const User = new ContentType({
|
|
606
|
+
name: 'User',
|
|
607
|
+
fields: {
|
|
608
|
+
email: f.string().type('Email').required(),
|
|
609
|
+
password: f.string().type('Password').required().managerOnly(),
|
|
610
|
+
},
|
|
611
|
+
}).withHooks({
|
|
612
|
+
beforeInsert: ({ data }) => ({
|
|
613
|
+
...data,
|
|
614
|
+
password: hashPassword(String(data.password)),
|
|
615
|
+
}),
|
|
616
|
+
onGet: ({ data }) => ({
|
|
617
|
+
...data,
|
|
618
|
+
displayName: String(data.email).split('@')[0],
|
|
619
|
+
}),
|
|
620
|
+
})
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
Dynamic data turns a content type into a reusable layout. The manager can bind
|
|
624
|
+
manager-visible fields to another content item field, or to a generated `href`
|
|
625
|
+
when a source content type has a page route. Fields are dynamic by default; call
|
|
626
|
+
`.noDynamic()` on fields that should not accept bindings or be exported as
|
|
627
|
+
source paths. Source content types are hidden by default; set
|
|
628
|
+
`dynamicDataSource: true` on content types that should appear in the manager
|
|
629
|
+
source selector. Field bindings can also select `Current document` to read values
|
|
630
|
+
from the document being edited without marking its content type as a source.
|
|
631
|
+
|
|
632
|
+
Source field selectors are type-aware. A string target only offers string-like
|
|
633
|
+
source paths, number targets only offer numbers, and boolean targets only offer
|
|
634
|
+
booleans. Object-like source fields are traversed so nested leaf fields can be
|
|
635
|
+
selected, while reserved SEO metadata is omitted from dynamic data mappings.
|
|
636
|
+
The generated `href` source is only shown for content types that have a
|
|
637
|
+
configured route with `hasPage: true`.
|
|
638
|
+
|
|
639
|
+
In list mappings, a target `f.link()` is exposed as two independent target
|
|
640
|
+
paths, `<field>.title` and `<field>.href`. Mapping those paths reconstructs the
|
|
641
|
+
target link object instead of assigning a URL string to the complete field.
|
|
642
|
+
|
|
643
|
+
Homogeneous `f.array(f.link())` and `f.array(f.relation(...))` targets can keep
|
|
644
|
+
using a direct array field binding or switch to per-item list mapping.
|
|
645
|
+
`f.relation(...).multiple()` is the same relation-array model and has the same
|
|
646
|
+
mapping support. Link arrays expose `title` and `href` for every item; relation
|
|
647
|
+
arrays expose the related content type's fields. Their resolved items stay flat,
|
|
648
|
+
whereas heterogeneous `f.blocks(...)` items keep their `{ name, value }`
|
|
649
|
+
wrapper.
|
|
650
|
+
|
|
651
|
+
For example, a routeable category can pre-link its SEO title when a new category
|
|
652
|
+
is created:
|
|
653
|
+
|
|
654
|
+
```ts
|
|
655
|
+
const Category = new ContentType({
|
|
656
|
+
name: 'Category',
|
|
657
|
+
fields: {
|
|
658
|
+
title: f.string().required().seo('title'),
|
|
659
|
+
},
|
|
660
|
+
})
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
The manager stores this as a normal editable dynamic data binding from
|
|
664
|
+
`seo.title` to `Current document · title`.
|
|
665
|
+
|
|
666
|
+
```ts
|
|
667
|
+
const Project = new ContentType({
|
|
668
|
+
name: 'Project',
|
|
669
|
+
dynamicDataSource: true,
|
|
670
|
+
fields: {
|
|
671
|
+
title: f.string().required(),
|
|
672
|
+
slug: f.string().type('Slug').required(),
|
|
673
|
+
},
|
|
674
|
+
})
|
|
675
|
+
|
|
676
|
+
const Carousel = new ContentType({
|
|
677
|
+
name: 'Carousel',
|
|
678
|
+
fields: {
|
|
679
|
+
title: f.string().required(),
|
|
680
|
+
internalNote: f.string().noDynamic(),
|
|
681
|
+
items: f.blocks([
|
|
682
|
+
{
|
|
683
|
+
name: 'CarouselItem',
|
|
684
|
+
field: f.relation(CarouselItem, 'new'),
|
|
685
|
+
},
|
|
686
|
+
]),
|
|
687
|
+
},
|
|
688
|
+
})
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
List bindings append dynamic items to manually stored items instead of replacing
|
|
692
|
+
the list. If the same stable item id appears in both sources, the dynamically
|
|
693
|
+
resolved item wins and the duplicate manual copy is skipped.
|
|
694
|
+
|
|
695
|
+
A list inside a nested module can also use a compatible relation or blocks array
|
|
696
|
+
from the current document. The manager exposes these sources as
|
|
697
|
+
`Current document · <field>`, infers the content type of each array item, and
|
|
698
|
+
lets each item be mapped with the same field mapping UI used for collections.
|
|
699
|
+
These bindings store a `currentDocument` source alongside the inferred item
|
|
700
|
+
content type:
|
|
701
|
+
|
|
702
|
+
```ts
|
|
703
|
+
const headerBindings = {
|
|
704
|
+
lists: {
|
|
705
|
+
categories: {
|
|
706
|
+
contentType: LinkItem.name,
|
|
707
|
+
source: {
|
|
708
|
+
kind: 'currentDocument',
|
|
709
|
+
contentType: Project.name,
|
|
710
|
+
path: 'categories',
|
|
711
|
+
itemName: 'Category',
|
|
712
|
+
},
|
|
713
|
+
itemName: 'Category',
|
|
714
|
+
map: {
|
|
715
|
+
title: { contentType: LinkItem.name, path: 'title' },
|
|
716
|
+
href: { contentType: LinkItem.name, path: 'href' },
|
|
717
|
+
},
|
|
718
|
+
},
|
|
719
|
+
},
|
|
720
|
+
}
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
List query conditions can compare a source field with a value from the current
|
|
724
|
+
context. At the top level this is the current document; inside a nested list it
|
|
725
|
+
is the parent source item and the manager labels it `Current item`. Programmatic
|
|
726
|
+
bindings use `{ $current: "path.to.field" }`. For example, a category can query
|
|
727
|
+
only the projects whose related category has the same slug:
|
|
728
|
+
|
|
729
|
+
```ts
|
|
730
|
+
query: {
|
|
731
|
+
filter: {
|
|
732
|
+
"category.slug": { $current: "slug" },
|
|
733
|
+
},
|
|
734
|
+
options: { limit: 10 },
|
|
735
|
+
}
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
Nested conditions can still read the root document by selecting `Current
|
|
739
|
+
document`, which stores `{ $document: "path.to.field" }`. Current-item and
|
|
740
|
+
current-document paths are checked against their respective content type's
|
|
741
|
+
dynamic field rules before the query runs. `_id` is also available for relation
|
|
742
|
+
queries.
|
|
743
|
+
|
|
744
|
+
List mappings can be nested recursively when a mapped target field is itself a
|
|
745
|
+
`blocks` list, link array, or relation array. Use `kind: "list"` for that map
|
|
746
|
+
entry and configure its source, query, item type, and field map exactly like a
|
|
747
|
+
top-level list binding. Inside the nested query, `$current` refers to the source
|
|
748
|
+
item being mapped by the parent list:
|
|
749
|
+
|
|
750
|
+
```ts
|
|
751
|
+
map: {
|
|
752
|
+
title: { contentType: Category.name, path: "title" },
|
|
753
|
+
images: {
|
|
754
|
+
kind: "list",
|
|
755
|
+
contentType: Project.name,
|
|
756
|
+
itemName: "CategoriesGalleryItemImage",
|
|
757
|
+
query: {
|
|
758
|
+
filter: { "category._id": { $current: "_id" } },
|
|
759
|
+
options: { limit: 10, sort: { title: "asc" } },
|
|
760
|
+
},
|
|
761
|
+
map: {
|
|
762
|
+
title: { contentType: Project.name, path: "title" },
|
|
763
|
+
href: { contentType: Project.name, virtual: "href" },
|
|
764
|
+
image: { contentType: Project.name, path: "image" },
|
|
765
|
+
},
|
|
766
|
+
},
|
|
767
|
+
}
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
The manager exposes this as the `Nested list` mapping mode. Nested mappings
|
|
771
|
+
apply the same source opt-in, field compatibility, query validation, and
|
|
772
|
+
`.noDynamic()` rules at every level.
|
|
773
|
+
|
|
774
|
+
A list mapping can also collect an array through a reverse relation without
|
|
775
|
+
persisting that relation on the source document. For example, a category gallery
|
|
776
|
+
can create one item per `Category` and collect the images of its related
|
|
777
|
+
`Project` documents:
|
|
778
|
+
|
|
779
|
+
```ts
|
|
780
|
+
const Category = new ContentType({
|
|
781
|
+
name: 'Category',
|
|
782
|
+
dynamicDataSource: true,
|
|
783
|
+
fields: {
|
|
784
|
+
title: f.string().required(),
|
|
785
|
+
},
|
|
786
|
+
})
|
|
787
|
+
|
|
788
|
+
const Project = new ContentType({
|
|
789
|
+
name: 'Project',
|
|
790
|
+
dynamicDataSource: true,
|
|
791
|
+
fields: {
|
|
792
|
+
category: f.relation(Category, 'existing').required(),
|
|
793
|
+
images: f.file().type('Image').multiple().required(),
|
|
794
|
+
},
|
|
795
|
+
})
|
|
796
|
+
|
|
797
|
+
const galleryBindings = {
|
|
798
|
+
lists: {
|
|
799
|
+
items: {
|
|
800
|
+
contentType: Category.name,
|
|
801
|
+
itemName: 'CategoriesGalleryItem',
|
|
802
|
+
map: {
|
|
803
|
+
title: { contentType: Category.name, path: 'title' },
|
|
804
|
+
images: {
|
|
805
|
+
kind: 'relatedCollection',
|
|
806
|
+
contentType: Project.name,
|
|
807
|
+
relation: 'category',
|
|
808
|
+
path: 'images',
|
|
809
|
+
limit: 10,
|
|
810
|
+
},
|
|
811
|
+
},
|
|
812
|
+
},
|
|
813
|
+
},
|
|
814
|
+
}
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
The related collection query matches `Project.category._id` against the current
|
|
818
|
+
category, preserves project and image order, and flattens the selected array by
|
|
819
|
+
one level. Its numeric limit applies to related projects and is capped at 100.
|
|
820
|
+
|
|
821
|
+
Schema and validation methods:
|
|
822
|
+
|
|
823
|
+
- `getInputSchema()`: write schema. Includes `_type`, `createdBy`, and `updatedBy`.
|
|
824
|
+
- `getSchema()`: persisted schema.
|
|
825
|
+
- `getPopulatedSchema()`: output with populated relations and `_id`.
|
|
826
|
+
- `getOutputSchema()`: public API output.
|
|
827
|
+
- `getOutputSchemaWithoutIterators()`: output variant without iterator fields.
|
|
828
|
+
- `validate`, `partialValidate`, `validateOutput`: Zod helpers.
|
|
829
|
+
|
|
830
|
+
The registry lives in `lib/Registry`:
|
|
831
|
+
|
|
832
|
+
- `registerContentType`, `registerInternalContentType`.
|
|
833
|
+
- `getContentTypes`, `getExternalContentTypes`, `getInternalContentTypes`.
|
|
834
|
+
- `getContentTypesForManager`: returns serializable content types without Zod schemas and without content types marked with `hideFromManager()`.
|
|
835
|
+
- `getContentTypeByName`.
|
|
836
|
+
|
|
837
|
+
## Fields
|
|
838
|
+
|
|
839
|
+
Use the concise `f` namespace for field factories. `Fields` remains exported as
|
|
840
|
+
a backward-compatible alias and references the same object.
|
|
841
|
+
|
|
842
|
+
Main factories:
|
|
843
|
+
|
|
844
|
+
```ts
|
|
845
|
+
f.string()
|
|
846
|
+
f.number()
|
|
847
|
+
f.boolean()
|
|
848
|
+
f.date()
|
|
849
|
+
f.select(['draft', 'published'])
|
|
850
|
+
f.relation(Post)
|
|
851
|
+
f.contentReference('Post')
|
|
852
|
+
f.selfRelation()
|
|
853
|
+
f.blocks([{ name: 'title', field: f.string() }])
|
|
854
|
+
f.array(f.string())
|
|
855
|
+
f.link()
|
|
856
|
+
f.menu()
|
|
857
|
+
f.file()
|
|
858
|
+
f.breadcrums()
|
|
859
|
+
```
|
|
860
|
+
|
|
861
|
+
Common modifiers:
|
|
862
|
+
|
|
863
|
+
- Fields are required by default. Use `.optional()` when a value may be omitted.
|
|
864
|
+
- `.required()` explicitly marks a field as required. It remains available for
|
|
865
|
+
clarity and backward compatibility.
|
|
866
|
+
- `.translatable()`: stores values per language with shape `{ _tag: "Translatable", ... }`.
|
|
867
|
+
- `.apiOnly()`: available for API/persistence, hidden from manager.
|
|
868
|
+
- `.managerOnly()`: visible to manager, excluded from API output.
|
|
869
|
+
|
|
870
|
+
Notable fields:
|
|
871
|
+
|
|
872
|
+
- `StringField`: UI `Text`, `Textarea`, `RichText`, `Email`, `Slug`, `Password`, `Id`, `Url`; supports `.min()` and `.max()`.
|
|
873
|
+
- `NumberField`: supports `.min()` and `.max()`.
|
|
874
|
+
- `DateField`: supports `.type("Date")`, `.type("DateTime")` and
|
|
875
|
+
`.type("Time")`. Date and datetime writes accept JavaScript `Date` values or
|
|
876
|
+
their ISO datetime JSON representation and normalize them to `Date`; time
|
|
877
|
+
values remain ISO time strings.
|
|
878
|
+
- `RelationField`: relation to another `ContentType`; accepts existing references or inline creation. `f.relation(Post, "existing")` restricts to existing records; `"new"` restricts to new records. `.multiple()` returns a homogeneous array of relations.
|
|
879
|
+
- `ContentReferenceField`: reference by content type name.
|
|
880
|
+
- `LinkField`: the manager stores a direct `{ href, title }` value or an
|
|
881
|
+
internal `{ routeId, contentTypeId, title }` reference. Titled links resolve
|
|
882
|
+
to `{ href, title }` in web output, with internal `href` values localized by
|
|
883
|
+
route. New input and web output always use an object shape. Persisted legacy
|
|
884
|
+
direct URL strings remain readable and receive an empty `title` when loaded
|
|
885
|
+
by the manager or normalized for web output.
|
|
886
|
+
- `MenuField`: `f.menu()` stores an ordered navigation tree. Every node is an
|
|
887
|
+
internal or direct link plus `children`, for example
|
|
888
|
+
`{ title, href, children: [...] }`. Internal references use `routeId` and
|
|
889
|
+
`contentTypeId` while persisted and resolve recursively to localized `href`
|
|
890
|
+
values in web output. The manager supports drag-and-drop ordering and
|
|
891
|
+
unlimited nested levels.
|
|
892
|
+
- `BreadcrumsField`: `f.breadcrums()` is a computed, API-only field for page
|
|
893
|
+
modules. In web and preview output it returns the localized route hierarchy as
|
|
894
|
+
`{ label, href }[]`, ordered from the highest ancestor to the current page. It
|
|
895
|
+
returns `null` when the content is resolved outside a routable page and is
|
|
896
|
+
never accepted as input, persisted, or rendered in the manager.
|
|
897
|
+
- `FileField`: integrates media and optimization options.
|
|
898
|
+
- `f.blocks(...)`: heterogeneous ordered list. Each item stores a `name` and a `value`, and the value can match one of the named field shapes. Use it for block-like content where different item types can appear in the same list.
|
|
899
|
+
- `f.array(...)`: homogeneous ordered list. Every item uses the same field shape. Chain `.min(count)` and `.max(count)` to validate its item count. The same limits are available after `.multiple()` on relation, file, select, and content-reference fields, for example `f.file().multiple().min(1).max(4)`.
|
|
900
|
+
- `IteratorField`: repeatable structure based on content type entries.
|
|
901
|
+
|
|
902
|
+
## Derived Types
|
|
903
|
+
|
|
904
|
+
`@rakun-kit/core/types` and `lib/types` derive types from `ContentType`:
|
|
905
|
+
|
|
906
|
+
- `DataInput<T>`: accepted shape for create/update.
|
|
907
|
+
- `DBOutput<T>`: persisted shape with metadata (`_id`, `_type`, timestamps, authorship).
|
|
908
|
+
- `DataPopulated<T>`: shape with populated relations.
|
|
909
|
+
- `DataFront<T>`: public output without `apiOnly` fields.
|
|
910
|
+
- `Filter<T>`, `Query<T>`, `ListInput<T>`, `GetAllInput<T>`: typed filters and list inputs.
|
|
911
|
+
- `MaybeTranslatableValue<T>`, `TranslatableValue<T>`.
|
|
912
|
+
|
|
913
|
+
## ORM and Mongo
|
|
914
|
+
|
|
915
|
+
`core/src/orm` implements `DBService` on top of MongoDB:
|
|
916
|
+
|
|
917
|
+
```ts
|
|
918
|
+
const db = await getMongoService()
|
|
919
|
+
|
|
920
|
+
const post = await db.create(Post, {
|
|
921
|
+
_type: 'Post',
|
|
922
|
+
title: 'Hello',
|
|
923
|
+
slug: 'hello',
|
|
924
|
+
})
|
|
925
|
+
```
|
|
926
|
+
|
|
927
|
+
Operations:
|
|
928
|
+
|
|
929
|
+
- `get(contentType, id, fields?)`
|
|
930
|
+
- `list(contentType, query)`
|
|
931
|
+
- `create(contentType, data)`
|
|
932
|
+
- `update(contentType, id, data)`
|
|
933
|
+
- `updateMany(contentType, filter, data)`
|
|
934
|
+
- `delete(contentType, filter)`
|
|
935
|
+
- `find(contentType, filter, fields?)`
|
|
936
|
+
- `clear(contentType)`
|
|
937
|
+
- `findDependencies(contentType, id)`
|
|
938
|
+
- `upsert(contentType, filter, data)`
|
|
939
|
+
- `getAll(contentType, query?)`
|
|
940
|
+
|
|
941
|
+
Connection:
|
|
942
|
+
|
|
943
|
+
- `createMongoConnection(config)`: stores config.
|
|
944
|
+
- `createMongoService(config)`: connects and creates handlers.
|
|
945
|
+
- `getMongoService()`: returns the singleton or creates it from config.
|
|
946
|
+
- `closeMongoService()`: closes the connection and clears the singleton.
|
|
947
|
+
|
|
948
|
+
`MongoConfig`:
|
|
949
|
+
|
|
950
|
+
```ts
|
|
951
|
+
type MongoConfig = {
|
|
952
|
+
MONGO_URI: string
|
|
953
|
+
ENVIRONMENT?: 'local' | 'development' | 'test' | 'production'
|
|
954
|
+
}
|
|
955
|
+
```
|
|
956
|
+
|
|
957
|
+
In environments other than `test`, the connection creates indexes defined by `createIndexes`.
|
|
958
|
+
|
|
959
|
+
## API Operations
|
|
960
|
+
|
|
961
|
+
`api/operations` defines typed contracts and handlers for endpoints:
|
|
962
|
+
|
|
963
|
+
- Manager: CRUD, auth, MFA, media, literals, settings.
|
|
964
|
+
- Manager comments and mentions: `manager.comments.list`,
|
|
965
|
+
`manager.comments.create`, `manager.comments.toggleReaction`,
|
|
966
|
+
`manager.comments.markRead`, `manager.comments.unreadCount`,
|
|
967
|
+
`manager.users.mentions`,
|
|
968
|
+
`manager.notifications.list`, and `manager.notifications.markRead`.
|
|
969
|
+
- Web: page resolution, static paths, sitemap, robots, `llms.txt`, and preview.
|
|
970
|
+
|
|
971
|
+
`web.staticPaths` returns `{ path, ttl }` only for route-map entries backed by
|
|
972
|
+
page routes configured with `dynamic: false`. Adapters can use this operation
|
|
973
|
+
for static generation without querying Rakun's database directly. Monolithic
|
|
974
|
+
server adapters can instead call `getRakunWebStaticPaths`, `getRakunWebPage`,
|
|
975
|
+
and `getRakunWebPreviewPage` after bootstrapping and initializing core.
|
|
976
|
+
|
|
977
|
+
`web.llms` returns the optional site-level `llms.txt` document configured in
|
|
978
|
+
Manager Settings. Rakun renders a curated Markdown title, summary, guidance,
|
|
979
|
+
sections, and links; it does not dump the sitemap automatically. Internal links
|
|
980
|
+
are resolved for the requested language and become absolute when SEO `siteUrl`
|
|
981
|
+
is configured. Links without a public route are omitted without hiding their
|
|
982
|
+
section heading. Optional sections retain their titles beneath the conventional
|
|
983
|
+
`## Optional` heading. The llms title and summary fall back to SEO `siteName` and the
|
|
984
|
+
default SEO description. The result is `null` while publishing is disabled or
|
|
985
|
+
there is no usable title. Server adapters can call `getRakunWebLlmsTxt`
|
|
986
|
+
directly after initialization.
|
|
987
|
+
|
|
988
|
+
`manager.localeVariants.list` includes an optional `path` on each language
|
|
989
|
+
assignment when that exact assigned document is published and has a generated
|
|
990
|
+
page route. Manager clients can use it for a contextual public-page link without
|
|
991
|
+
granting editors direct access to internal `RouteMap` records.
|
|
992
|
+
|
|
993
|
+
Routeable content with document visibility is public only when `_visibility`
|
|
994
|
+
is explicitly `published` or `hidden`. Missing visibility is treated as draft,
|
|
995
|
+
both while generating route maps and when resolving a public page, so legacy or
|
|
996
|
+
incomplete records fail closed even if an obsolete route-map entry remains.
|
|
997
|
+
|
|
998
|
+
Main helpers:
|
|
999
|
+
|
|
1000
|
+
- `defineOperationContract`: declares a contract with Zod input/output, method, path, and metadata.
|
|
1001
|
+
- `defineOperation`: combines a contract with its implementation.
|
|
1002
|
+
- `createRakunApiClient`: creates a browser/server HTTP client for custom operations.
|
|
1003
|
+
- `GetClient`: derives a typed client from an operation map.
|
|
1004
|
+
- `createManagerOperationContracts`, `createWebOperationContracts`.
|
|
1005
|
+
- `createManagerOperationDefinitions`, `createWebOperationDefinitions`.
|
|
1006
|
+
- `createRakunOperationDefinitions`: combines manager + web.
|
|
1007
|
+
- `createOperationManifest`: serializable metadata for clients.
|
|
1008
|
+
- `createOperationPath`: HTTP path from operation name.
|
|
1009
|
+
- `mergeOperationContracts`: combines maps.
|
|
1010
|
+
|
|
1011
|
+
`@rakun-kit/core/manager` exposes the manifest and name-based types:
|
|
1012
|
+
|
|
1013
|
+
```ts
|
|
1014
|
+
import {
|
|
1015
|
+
managerOperationManifest,
|
|
1016
|
+
getManagerOperationMeta,
|
|
1017
|
+
type ManagerOperationInput,
|
|
1018
|
+
type ManagerOperationOutput,
|
|
1019
|
+
} from '@rakun-kit/core/manager'
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
### Custom Operations
|
|
1023
|
+
|
|
1024
|
+
Applications can define operations in a separate object, pass that object to
|
|
1025
|
+
bootstrap, and reuse its type on the frontend:
|
|
1026
|
+
|
|
1027
|
+
```ts
|
|
1028
|
+
// server/api-operations.ts
|
|
1029
|
+
import { defineOperation } from '@rakun-kit/core'
|
|
1030
|
+
import { z } from 'zod'
|
|
1031
|
+
|
|
1032
|
+
export const apiOperations = {
|
|
1033
|
+
'demo.helloWorld': defineOperation<
|
|
1034
|
+
{ text: string },
|
|
1035
|
+
{ message: string },
|
|
1036
|
+
'query',
|
|
1037
|
+
'get',
|
|
1038
|
+
'public'
|
|
1039
|
+
>({
|
|
1040
|
+
access: 'public',
|
|
1041
|
+
kind: 'query',
|
|
1042
|
+
method: 'get',
|
|
1043
|
+
description: 'Return a hello world message with the provided text',
|
|
1044
|
+
input: z.object({
|
|
1045
|
+
text: z.string().default('world'),
|
|
1046
|
+
}),
|
|
1047
|
+
output: z.object({
|
|
1048
|
+
message: z.string(),
|
|
1049
|
+
}),
|
|
1050
|
+
resolve: ({ input }) => ({
|
|
1051
|
+
message: `Hello ${input.text}`,
|
|
1052
|
+
}),
|
|
1053
|
+
}),
|
|
1054
|
+
}
|
|
1055
|
+
```
|
|
1056
|
+
|
|
1057
|
+
```ts
|
|
1058
|
+
// bootstrap
|
|
1059
|
+
import { apiOperations } from './server/api-operations'
|
|
1060
|
+
|
|
1061
|
+
rakunBootstrap({
|
|
1062
|
+
// ...
|
|
1063
|
+
apiOperations,
|
|
1064
|
+
})
|
|
1065
|
+
```
|
|
1066
|
+
|
|
1067
|
+
Operation names define their HTTP path: `demo.helloWorld` becomes
|
|
1068
|
+
`/demo/helloWorld`.
|
|
1069
|
+
|
|
1070
|
+
Rules:
|
|
1071
|
+
|
|
1072
|
+
- Names must not collide with built-in operations.
|
|
1073
|
+
- Operations prefixed with `manager.` are included in manager operation routers.
|
|
1074
|
+
- Operations prefixed with `web.` are included in web operation routers.
|
|
1075
|
+
- Operations with any other prefix are included when using the combined operation registry.
|
|
1076
|
+
- Use `access: "public"` for operations called from public web pages.
|
|
1077
|
+
- Use `access: "auth"` for operations that require a manager session.
|
|
1078
|
+
|
|
1079
|
+
The manager route `manager.apiOperations` returns a JSON-serializable operation
|
|
1080
|
+
catalog for manager API docs/playgrounds. Input and output Zod schemas are
|
|
1081
|
+
converted to JSON Schema for display.
|
|
1082
|
+
|
|
1083
|
+
### Typed API Client
|
|
1084
|
+
|
|
1085
|
+
`@rakun-kit/core/web` exposes a small typed HTTP client for operation maps:
|
|
1086
|
+
|
|
1087
|
+
```ts
|
|
1088
|
+
import { createRakunApiClient, type GetClient } from '@rakun-kit/core/web'
|
|
1089
|
+
import type { apiOperations } from './server/api-operations'
|
|
1090
|
+
|
|
1091
|
+
type ApiClient = GetClient<typeof apiOperations>
|
|
1092
|
+
|
|
1093
|
+
const client: ApiClient = createRakunApiClient<typeof apiOperations>({
|
|
1094
|
+
baseUrl: '/api',
|
|
1095
|
+
})
|
|
1096
|
+
|
|
1097
|
+
const result = await client.query('demo.helloWorld', {
|
|
1098
|
+
text: 'Rakun',
|
|
1099
|
+
})
|
|
1100
|
+
|
|
1101
|
+
result.message
|
|
1102
|
+
```
|
|
1103
|
+
|
|
1104
|
+
The client exposes:
|
|
1105
|
+
|
|
1106
|
+
- `query(name, input?, options?)`: only accepts operations with `kind: "query"`.
|
|
1107
|
+
- `mutation(name, input?, options?)`: only accepts operations with `kind: "mutation"`.
|
|
1108
|
+
|
|
1109
|
+
The client derives input and output types from the Zod schemas in
|
|
1110
|
+
`apiOperations`.
|
|
1111
|
+
|
|
1112
|
+
## Request Context and Auth
|
|
1113
|
+
|
|
1114
|
+
`createRequestContext(input)` normalizes headers, cookies, and response:
|
|
1115
|
+
|
|
1116
|
+
```ts
|
|
1117
|
+
const ctx = await createRequestContext({
|
|
1118
|
+
headers: req.headers,
|
|
1119
|
+
cookies,
|
|
1120
|
+
res: {
|
|
1121
|
+
setHeader: res.setHeader.bind(res),
|
|
1122
|
+
cookie: res.cookie.bind(res),
|
|
1123
|
+
},
|
|
1124
|
+
})
|
|
1125
|
+
```
|
|
1126
|
+
|
|
1127
|
+
The resulting context includes:
|
|
1128
|
+
|
|
1129
|
+
- `req.headers`, `req.cookies`
|
|
1130
|
+
- `res.setHeader`, `res.cookie`
|
|
1131
|
+
- `user`: manager user or `null`
|
|
1132
|
+
- `getUser()`: returns the user or throws `AUTH_REQUIRED`
|
|
1133
|
+
|
|
1134
|
+
Session cookies are managed with `getSessionCookie` and `setSessionCookie`.
|
|
1135
|
+
|
|
1136
|
+
## Media
|
|
1137
|
+
|
|
1138
|
+
Media uses a storage adapter:
|
|
1139
|
+
|
|
1140
|
+
```ts
|
|
1141
|
+
createMediaService({
|
|
1142
|
+
adapter,
|
|
1143
|
+
defaultAccess: 'private',
|
|
1144
|
+
defaultGetExpiresInSeconds: 300,
|
|
1145
|
+
uploadUrl: '/api/rakun/manager/media/upload',
|
|
1146
|
+
})
|
|
1147
|
+
```
|
|
1148
|
+
|
|
1149
|
+
APIs:
|
|
1150
|
+
|
|
1151
|
+
- `createMediaConnection(config)`: stores config without creating the service.
|
|
1152
|
+
- `createMediaService(config)`: creates the singleton with an adapter.
|
|
1153
|
+
- `getMediaService()`: returns the singleton or creates it from config.
|
|
1154
|
+
- `handleMediaBinaryUpload`: processes manager binary uploads.
|
|
1155
|
+
|
|
1049
1156
|
The service supports prepare/finalize upload, URL generation, folders, and media optimization depending on adapter/configuration. Manager uploads encode original file names for transport, so Unicode names (including accents, non-Latin scripts, and emoji) are preserved without placing invalid characters in HTTP headers.
|
|
1050
1157
|
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
with
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
`
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
})
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
- `
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
- `
|
|
1255
|
-
- `
|
|
1256
|
-
- `
|
|
1257
|
-
- `
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
The
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
The
|
|
1158
|
+
Adapters can implement `getPublicObject` to let every Rakun server adapter proxy
|
|
1159
|
+
public media at its normal `/media/public/<key>` API route. This keeps browser
|
|
1160
|
+
URLs stable even when the object store is private or only supports expiring
|
|
1161
|
+
presigned URLs. The core handler validates the key under `public/`, forwards
|
|
1162
|
+
byte ranges, preserves object metadata, and applies long-lived caching by
|
|
1163
|
+
default. The storage adapter receives server-side credentials; never expose its
|
|
1164
|
+
presigned storage URL as the public media URL.
|
|
1165
|
+
|
|
1166
|
+
Optimized video uploads use the `ffmpeg-static` peer dependency and produce an MP4 primary object plus MP4 and WebM entries in `sources`. Existing image-only optimize options remain compatible; use `video: { quality: 80 }` to configure video quality explicitly.
|
|
1167
|
+
|
|
1168
|
+
Existing images and videos can be reimported from the media manager with the selected optimization settings. The replacement uses new storage keys and updates the existing `Media` record only after every requested variant has been written, preserving its ID and content references. Preview generation stores a compact `data:image/...` string on `previewUrl` for LQIP use in `@rakun-kit/react` `Image`, instead of writing a separate preview object to storage.
|
|
1169
|
+
|
|
1170
|
+
The `manager.media.replace` mutation accepts a newly uploaded image and swaps it into an existing `Media` record. It preserves the media ID, name, title, alt text, folder, status, and all content references; after the database points to the new storage keys, Rakun removes the previous primary object and generated variants and revalidates directly dependent documents when route revalidation is configured.
|
|
1171
|
+
|
|
1172
|
+
## Persistent Event Log
|
|
1173
|
+
|
|
1174
|
+
Rakun keeps business/audit events separate from its technical console logger.
|
|
1175
|
+
The event log keeps events immutable and defaults to a MongoDB collection
|
|
1176
|
+
with indexes for time, type, category, outcome, severity, correlation and tags:
|
|
1177
|
+
|
|
1178
|
+
```ts
|
|
1179
|
+
import { recordEvent, queryEvents } from '@rakun-kit/core'
|
|
1180
|
+
|
|
1181
|
+
await recordEvent({
|
|
1182
|
+
type: 'content.article.published',
|
|
1183
|
+
category: 'content',
|
|
1184
|
+
outcome: 'success',
|
|
1185
|
+
actor: { type: 'manager-user', id: userId },
|
|
1186
|
+
resource: { type: 'Article', id: articleId },
|
|
1187
|
+
correlationId: requestId,
|
|
1188
|
+
tags: ['editorial'],
|
|
1189
|
+
data: {
|
|
1190
|
+
locale: 'es',
|
|
1191
|
+
changedFields: 3,
|
|
1192
|
+
},
|
|
1193
|
+
})
|
|
1194
|
+
|
|
1195
|
+
const page = await queryEvents({
|
|
1196
|
+
categories: ['content'],
|
|
1197
|
+
outcomes: ['success'],
|
|
1198
|
+
from: new Date('2026-01-01T00:00:00.000Z'),
|
|
1199
|
+
limit: 50,
|
|
1200
|
+
})
|
|
1201
|
+
```
|
|
1202
|
+
|
|
1203
|
+
`data` accepts nested JSON values. Event queries use cursor pagination and can
|
|
1204
|
+
filter by types, categories, severities, outcomes, sources, correlation,
|
|
1205
|
+
required tags and a date range. A custom persistence implementation can be
|
|
1206
|
+
plugged in globally:
|
|
1207
|
+
|
|
1208
|
+
```ts
|
|
1209
|
+
import type { EventLogAdapter } from '@rakun-kit/core'
|
|
1210
|
+
|
|
1211
|
+
const adapter: EventLogAdapter = {
|
|
1212
|
+
async append(event) {
|
|
1213
|
+
return customStore.append(event)
|
|
1214
|
+
},
|
|
1215
|
+
async query(filters) {
|
|
1216
|
+
return customStore.query(filters)
|
|
1217
|
+
},
|
|
1218
|
+
async deleteBefore(before) {
|
|
1219
|
+
return customStore.deleteBefore(before)
|
|
1220
|
+
},
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
rakunBootstrap({
|
|
1224
|
+
// ...
|
|
1225
|
+
eventLog: { adapter },
|
|
1226
|
+
})
|
|
1227
|
+
```
|
|
1228
|
+
|
|
1229
|
+
Plugins receive the resolved `eventLog` service in their initialization
|
|
1230
|
+
context. Reading a shared event stream should be protected with the built-in
|
|
1231
|
+
`system.eventLog.read` permission. The built-in `manager.logs.list` operation and the
|
|
1232
|
+
manager Settings → Logs screen both enforce it.
|
|
1233
|
+
|
|
1234
|
+
Retention cleanup is available from the manager Logs screen to users with the
|
|
1235
|
+
built-in `system.eventLog.manage` permission. It deletes events strictly older
|
|
1236
|
+
than the selected cutoff. Custom adapters must implement `deleteBefore` to
|
|
1237
|
+
support this action. The cleanup mutation itself is logged after deletion.
|
|
1238
|
+
|
|
1239
|
+
Failed API operations are persisted automatically as `api.operation.failed`
|
|
1240
|
+
events. This includes expected 4xx application errors and unexpected 5xx
|
|
1241
|
+
failures across the core operation wrapper and the Express, Next.js, and tRPC
|
|
1242
|
+
adapters. Events include the operation, status, method, kind, correlation ID,
|
|
1243
|
+
and authenticated actor when available. Request payloads, application error
|
|
1244
|
+
causes, and raw internal error messages are not persisted.
|
|
1245
|
+
|
|
1246
|
+
Every successful API mutation is also persisted with an operation-specific
|
|
1247
|
+
event type such as `manager.create.succeeded` or
|
|
1248
|
+
`manager.backups.restore.succeeded`. Successful queries are not recorded by
|
|
1249
|
+
default, which keeps the event stream focused on state changes. Mutation
|
|
1250
|
+
events contain operation metadata and actor/correlation context, but never
|
|
1251
|
+
copy the input payload or result.
|
|
1252
|
+
|
|
1253
|
+
## Mail
|
|
1254
|
+
|
|
1255
|
+
Mail providers receive normalized, already-rendered messages through
|
|
1256
|
+
`MailAdapter`, so neither `core` nor an adapter depends on React or a template
|
|
1257
|
+
engine:
|
|
1258
|
+
|
|
1259
|
+
```ts
|
|
1260
|
+
import type { MailAdapter } from '@rakun-kit/core'
|
|
1261
|
+
|
|
1262
|
+
const adapter: MailAdapter = {
|
|
1263
|
+
async send(message) {
|
|
1264
|
+
const result = await provider.send(message)
|
|
1265
|
+
return { id: result.id }
|
|
1266
|
+
},
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
rakunBootstrap({
|
|
1270
|
+
// ...
|
|
1271
|
+
mail: {
|
|
1272
|
+
adapter,
|
|
1273
|
+
defaultFrom: 'hello@example.com',
|
|
1274
|
+
defaultReplyTo: 'support@example.com',
|
|
1275
|
+
},
|
|
1276
|
+
})
|
|
1277
|
+
```
|
|
1278
|
+
|
|
1279
|
+
Send rendered content directly:
|
|
1280
|
+
|
|
1281
|
+
```ts
|
|
1282
|
+
import { sendMail } from '@rakun-kit/core'
|
|
1283
|
+
|
|
1284
|
+
await sendMail({
|
|
1285
|
+
to: 'ada@example.com',
|
|
1286
|
+
subject: 'Welcome',
|
|
1287
|
+
html: '<p>Hello Ada</p>',
|
|
1288
|
+
text: 'Hello Ada',
|
|
1289
|
+
})
|
|
1290
|
+
```
|
|
1291
|
+
|
|
1292
|
+
Or create a typed application template registry:
|
|
1293
|
+
|
|
1294
|
+
```ts
|
|
1295
|
+
import { createMailSender, defineMailTemplate } from '@rakun-kit/core'
|
|
1296
|
+
|
|
1297
|
+
const mail = createMailSender({
|
|
1298
|
+
templates: {
|
|
1299
|
+
welcome: defineMailTemplate<{ name: string }>({
|
|
1300
|
+
subject: ({ name }) => `Welcome, ${name}`,
|
|
1301
|
+
render: ({ name }) => ({
|
|
1302
|
+
html: `<p>Hello ${name}</p>`,
|
|
1303
|
+
text: `Hello ${name}`,
|
|
1304
|
+
}),
|
|
1305
|
+
}),
|
|
1306
|
+
},
|
|
1307
|
+
})
|
|
1308
|
+
|
|
1309
|
+
await mail.send({
|
|
1310
|
+
template: 'welcome',
|
|
1311
|
+
props: { name: 'Ada' },
|
|
1312
|
+
to: 'ada@example.com',
|
|
1313
|
+
})
|
|
1314
|
+
```
|
|
1315
|
+
|
|
1316
|
+
The common contract supports To/CC/BCC/Reply-To, custom headers and in-memory
|
|
1317
|
+
`Uint8Array` attachments. Sending is immediate; queues, retries and delivery
|
|
1318
|
+
events belong to application infrastructure.
|
|
1319
|
+
|
|
1320
|
+
Every mail sent through a bootstrapped Rakun mail service creates append-only
|
|
1321
|
+
`mail.send.attempted` and `mail.send.succeeded` or `mail.send.failed` events.
|
|
1322
|
+
They share a correlation id and include only operational counts, provider,
|
|
1323
|
+
template and duration. Recipient addresses, subject, HTML/text, headers,
|
|
1324
|
+
attachment names/content, credentials and raw provider errors are never copied
|
|
1325
|
+
to the persistent event log. If the initial attempt event cannot be persisted,
|
|
1326
|
+
the provider is not called.
|
|
1327
|
+
|
|
1328
|
+
## Literals and Translation
|
|
1329
|
+
|
|
1330
|
+
Bootstrap receives `literals`. Related utilities:
|
|
1331
|
+
|
|
1332
|
+
- `getTranslation`: resolves translatable values.
|
|
1333
|
+
- `translateObject`: translates objects with translatable fields.
|
|
1334
|
+
- Manager schemas for listing/upserting website literals (not manager UI chrome).
|
|
1335
|
+
|
|
1336
|
+
Translatable values use this shape:
|
|
1337
|
+
|
|
1338
|
+
```ts
|
|
1339
|
+
{
|
|
1340
|
+
_tag: "Translatable",
|
|
1341
|
+
en: "Title",
|
|
1342
|
+
es: "Titulo"
|
|
1343
|
+
}
|
|
1344
|
+
```
|
|
1345
|
+
|
|
1346
|
+
## Permissions
|
|
1347
|
+
|
|
1348
|
+
`lib/Permissions` exposes:
|
|
1349
|
+
|
|
1350
|
+
- `getPermissionList`: generates a permission list.
|
|
1351
|
+
- `hasPermissions`: validates user/role permissions.
|
|
1352
|
+
- `mapPermissions`: transforms permissions.
|
|
1353
|
+
- `Permission`: public type.
|
|
1354
|
+
|
|
1355
|
+
Manager routes apply permissions, ownership, and auth through utilities in `api/utils`.
|
|
1356
|
+
|
|
1357
|
+
## Errors
|
|
1358
|
+
|
|
1359
|
+
Application errors live in `lib/errors`:
|
|
1360
|
+
|
|
1361
|
+
- `AppError`
|
|
1362
|
+
- `throwAppError`
|
|
1363
|
+
- `errors`
|
|
1364
|
+
- `instanceofAppErrorShape`
|
|
1365
|
+
|
|
1366
|
+
Database errors live in `orm/dbService`:
|
|
1367
|
+
|
|
1368
|
+
- `DbError`
|
|
1369
|
+
- `DbErrorUnknown`
|
|
1370
|
+
- `DbErrorNotFound`
|
|
1371
|
+
- `DbErrorInvalidData`
|
|
1372
|
+
- `DbErrorConflict`
|
|
1373
|
+
- `DbErrorSimulatedFailure`
|
|
1374
|
+
|
|
1375
|
+
## Runtime Flow
|
|
1376
|
+
|
|
1377
|
+
1. The app defines content types with `ContentType` and `f`.
|
|
1378
|
+
2. The app calls `rakunBootstrap(options)`.
|
|
1379
|
+
3. The HTTP adapter calls `ensureRakunInitialized()` before serving Rakun routes.
|
|
1380
|
+
4. `ensureRakunInitialized()` configures logger, MongoDB, the persistent event
|
|
1381
|
+
log, media, mail, and route syncing.
|
|
1382
|
+
5. Each request creates a `RakunRequestContext`.
|
|
1383
|
+
6. Manager/web operations validate input, run logic, validate output, and return typed contracts.
|
|
1384
|
+
|
|
1385
|
+
## Tests and Development Notes
|
|
1386
|
+
|
|
1387
|
+
The package includes targeted tests next to modules (`*.test.ts`), for example ORM, translation, routes, redirects, and populated relations.
|
|
1388
|
+
|
|
1389
|
+
Package build:
|
|
1390
|
+
|
|
1391
|
+
```sh
|
|
1392
|
+
bun run build --workspace @rakun-kit/core
|
|
1393
|
+
```
|
|
1394
|
+
|
|
1395
|
+
The script generates ESM and CJS in `dist/`, adjusting imports and the CJS `package.json` through repo scripts.
|