@trokky/trokky 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/filesystem/filesystem-adapter.d.ts +80 -0
- package/dist/adapters/filesystem/filesystem-adapter.d.ts.map +1 -0
- package/dist/adapters/filesystem/filesystem-adapter.js +1370 -0
- package/dist/adapters/filesystem/filesystem-adapter.js.map +1 -0
- package/dist/adapters/filesystem/index.d.ts +29 -0
- package/dist/adapters/filesystem/index.d.ts.map +1 -0
- package/dist/adapters/filesystem/index.js +31 -0
- package/dist/adapters/filesystem/index.js.map +1 -0
- package/dist/adapters/filesystem/types.d.ts +111 -0
- package/dist/adapters/filesystem/types.d.ts.map +1 -0
- package/dist/adapters/filesystem/types.js +2 -0
- package/dist/adapters/filesystem/types.js.map +1 -0
- package/dist/adapters/filesystem-data/filesystem-data-adapter.d.ts +111 -0
- package/dist/adapters/filesystem-data/filesystem-data-adapter.d.ts.map +1 -0
- package/dist/adapters/filesystem-data/filesystem-data-adapter.js +1363 -0
- package/dist/adapters/filesystem-data/filesystem-data-adapter.js.map +1 -0
- package/dist/adapters/filesystem-data/index.d.ts +3 -0
- package/dist/adapters/filesystem-data/index.d.ts.map +1 -0
- package/dist/adapters/filesystem-data/index.js +13 -0
- package/dist/adapters/filesystem-data/index.js.map +1 -0
- package/dist/adapters/filesystem-data/types.d.ts +147 -0
- package/dist/adapters/filesystem-data/types.d.ts.map +1 -0
- package/dist/adapters/filesystem-data/types.js +2 -0
- package/dist/adapters/filesystem-data/types.js.map +1 -0
- package/dist/adapters/filesystem-media/filesystem-media-adapter.d.ts +32 -0
- package/dist/adapters/filesystem-media/filesystem-media-adapter.d.ts.map +1 -0
- package/dist/adapters/filesystem-media/filesystem-media-adapter.js +639 -0
- package/dist/adapters/filesystem-media/filesystem-media-adapter.js.map +1 -0
- package/dist/adapters/filesystem-media/index.d.ts +3 -0
- package/dist/adapters/filesystem-media/index.d.ts.map +1 -0
- package/dist/adapters/filesystem-media/index.js +13 -0
- package/dist/adapters/filesystem-media/index.js.map +1 -0
- package/dist/adapters/filesystem-media/types.d.ts +76 -0
- package/dist/adapters/filesystem-media/types.d.ts.map +1 -0
- package/dist/adapters/filesystem-media/types.js +2 -0
- package/dist/adapters/filesystem-media/types.js.map +1 -0
- package/dist/adapters/postgres-data/index.d.ts +3 -0
- package/dist/adapters/postgres-data/index.d.ts.map +1 -0
- package/dist/adapters/postgres-data/index.js +13 -0
- package/dist/adapters/postgres-data/index.js.map +1 -0
- package/dist/adapters/postgres-data/postgres-data-adapter.d.ts +154 -0
- package/dist/adapters/postgres-data/postgres-data-adapter.d.ts.map +1 -0
- package/dist/adapters/postgres-data/postgres-data-adapter.js +1432 -0
- package/dist/adapters/postgres-data/postgres-data-adapter.js.map +1 -0
- package/dist/adapters/postgres-data/types.d.ts +139 -0
- package/dist/adapters/postgres-data/types.d.ts.map +1 -0
- package/dist/adapters/postgres-data/types.js +2 -0
- package/dist/adapters/postgres-data/types.js.map +1 -0
- package/dist/core/adapters/registry.d.ts +79 -0
- package/dist/core/adapters/registry.d.ts.map +1 -0
- package/dist/core/adapters/registry.js +149 -0
- package/dist/core/adapters/registry.js.map +1 -0
- package/dist/core/core/engine.d.ts +551 -0
- package/dist/core/core/engine.d.ts.map +1 -0
- package/dist/core/core/engine.js +1074 -0
- package/dist/core/core/engine.js.map +1 -0
- package/dist/core/crypto/adapter.d.ts +63 -0
- package/dist/core/crypto/adapter.d.ts.map +1 -0
- package/dist/core/crypto/adapter.js +63 -0
- package/dist/core/crypto/adapter.js.map +1 -0
- package/dist/core/crypto/fallback-adapter.d.ts +23 -0
- package/dist/core/crypto/fallback-adapter.d.ts.map +1 -0
- package/dist/core/crypto/fallback-adapter.js +195 -0
- package/dist/core/crypto/fallback-adapter.js.map +1 -0
- package/dist/core/crypto/node-adapter.d.ts +20 -0
- package/dist/core/crypto/node-adapter.d.ts.map +1 -0
- package/dist/core/crypto/node-adapter.js +85 -0
- package/dist/core/crypto/node-adapter.js.map +1 -0
- package/dist/core/crypto/password-hash.d.ts +73 -0
- package/dist/core/crypto/password-hash.d.ts.map +1 -0
- package/dist/core/crypto/password-hash.js +244 -0
- package/dist/core/crypto/password-hash.js.map +1 -0
- package/dist/core/crypto/webcrypto-adapter.d.ts +24 -0
- package/dist/core/crypto/webcrypto-adapter.d.ts.map +1 -0
- package/dist/core/crypto/webcrypto-adapter.js +158 -0
- package/dist/core/crypto/webcrypto-adapter.js.map +1 -0
- package/dist/core/errors/index.d.ts +30 -0
- package/dist/core/errors/index.d.ts.map +1 -0
- package/dist/core/errors/index.js +61 -0
- package/dist/core/errors/index.js.map +1 -0
- package/dist/core/events/event-bus.d.ts +121 -0
- package/dist/core/events/event-bus.d.ts.map +1 -0
- package/dist/core/events/event-bus.js +631 -0
- package/dist/core/events/event-bus.js.map +1 -0
- package/dist/core/events/index.d.ts +17 -0
- package/dist/core/events/index.d.ts.map +1 -0
- package/dist/core/events/index.js +22 -0
- package/dist/core/events/index.js.map +1 -0
- package/dist/core/events/memory-storage.d.ts +57 -0
- package/dist/core/events/memory-storage.d.ts.map +1 -0
- package/dist/core/events/memory-storage.js +175 -0
- package/dist/core/events/memory-storage.js.map +1 -0
- package/dist/core/events/types.d.ts +434 -0
- package/dist/core/events/types.d.ts.map +1 -0
- package/dist/core/events/types.js +9 -0
- package/dist/core/events/types.js.map +1 -0
- package/dist/core/events/utils.d.ts +134 -0
- package/dist/core/events/utils.d.ts.map +1 -0
- package/dist/core/events/utils.js +333 -0
- package/dist/core/events/utils.js.map +1 -0
- package/dist/core/fields/conditional.d.ts +115 -0
- package/dist/core/fields/conditional.d.ts.map +1 -0
- package/dist/core/fields/conditional.js +296 -0
- package/dist/core/fields/conditional.js.map +1 -0
- package/dist/core/fields/field-type.d.ts +218 -0
- package/dist/core/fields/field-type.d.ts.map +1 -0
- package/dist/core/fields/field-type.js +17 -0
- package/dist/core/fields/field-type.js.map +1 -0
- package/dist/core/fields/helpers.d.ts +86 -0
- package/dist/core/fields/helpers.d.ts.map +1 -0
- package/dist/core/fields/helpers.js +260 -0
- package/dist/core/fields/helpers.js.map +1 -0
- package/dist/core/fields/index.d.ts +5 -0
- package/dist/core/fields/index.d.ts.map +1 -0
- package/dist/core/fields/index.js +6 -0
- package/dist/core/fields/index.js.map +1 -0
- package/dist/core/fields/registry.d.ts +78 -0
- package/dist/core/fields/registry.d.ts.map +1 -0
- package/dist/core/fields/registry.js +185 -0
- package/dist/core/fields/registry.js.map +1 -0
- package/dist/core/index.d.ts +39 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +57 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/media/image-processor.d.ts +24 -0
- package/dist/core/media/image-processor.d.ts.map +1 -0
- package/dist/core/media/image-processor.js +69 -0
- package/dist/core/media/image-processor.js.map +1 -0
- package/dist/core/media/processors/cloudflare-images.d.ts +83 -0
- package/dist/core/media/processors/cloudflare-images.d.ts.map +1 -0
- package/dist/core/media/processors/cloudflare-images.js +241 -0
- package/dist/core/media/processors/cloudflare-images.js.map +1 -0
- package/dist/core/media/processors/cloudflare-transform-store.d.ts +127 -0
- package/dist/core/media/processors/cloudflare-transform-store.d.ts.map +1 -0
- package/dist/core/media/processors/cloudflare-transform-store.js +237 -0
- package/dist/core/media/processors/cloudflare-transform-store.js.map +1 -0
- package/dist/core/media/processors/cloudflare-transformations.d.ts +81 -0
- package/dist/core/media/processors/cloudflare-transformations.d.ts.map +1 -0
- package/dist/core/media/processors/cloudflare-transformations.js +144 -0
- package/dist/core/media/processors/cloudflare-transformations.js.map +1 -0
- package/dist/core/media/processors/index.d.ts +9 -0
- package/dist/core/media/processors/index.d.ts.map +1 -0
- package/dist/core/media/processors/index.js +13 -0
- package/dist/core/media/processors/index.js.map +1 -0
- package/dist/core/media/processors/noop.d.ts +22 -0
- package/dist/core/media/processors/noop.d.ts.map +1 -0
- package/dist/core/media/processors/noop.js +38 -0
- package/dist/core/media/processors/noop.js.map +1 -0
- package/dist/core/media/processors/sharp.d.ts +30 -0
- package/dist/core/media/processors/sharp.d.ts.map +1 -0
- package/dist/core/media/processors/sharp.js +126 -0
- package/dist/core/media/processors/sharp.js.map +1 -0
- package/dist/core/media/processors/types.d.ts +67 -0
- package/dist/core/media/processors/types.d.ts.map +1 -0
- package/dist/core/media/processors/types.js +42 -0
- package/dist/core/media/processors/types.js.map +1 -0
- package/dist/core/media/processors/workers-images.d.ts +112 -0
- package/dist/core/media/processors/workers-images.d.ts.map +1 -0
- package/dist/core/media/processors/workers-images.js +257 -0
- package/dist/core/media/processors/workers-images.js.map +1 -0
- package/dist/core/schema/registry.d.ts +41 -0
- package/dist/core/schema/registry.d.ts.map +1 -0
- package/dist/core/schema/registry.js +248 -0
- package/dist/core/schema/registry.js.map +1 -0
- package/dist/core/schema/singleton.d.ts +107 -0
- package/dist/core/schema/singleton.d.ts.map +1 -0
- package/dist/core/schema/singleton.js +180 -0
- package/dist/core/schema/singleton.js.map +1 -0
- package/dist/core/security/auth.d.ts +120 -0
- package/dist/core/security/auth.d.ts.map +1 -0
- package/dist/core/security/auth.js +274 -0
- package/dist/core/security/auth.js.map +1 -0
- package/dist/core/security/captcha/index.d.ts +21 -0
- package/dist/core/security/captcha/index.d.ts.map +1 -0
- package/dist/core/security/captcha/index.js +34 -0
- package/dist/core/security/captcha/index.js.map +1 -0
- package/dist/core/security/captcha/recaptcha.d.ts +41 -0
- package/dist/core/security/captcha/recaptcha.d.ts.map +1 -0
- package/dist/core/security/captcha/recaptcha.js +89 -0
- package/dist/core/security/captcha/recaptcha.js.map +1 -0
- package/dist/core/security/captcha/turnstile.d.ts +41 -0
- package/dist/core/security/captcha/turnstile.d.ts.map +1 -0
- package/dist/core/security/captcha/turnstile.js +90 -0
- package/dist/core/security/captcha/turnstile.js.map +1 -0
- package/dist/core/security/captcha/types.d.ts +66 -0
- package/dist/core/security/captcha/types.d.ts.map +1 -0
- package/dist/core/security/captcha/types.js +7 -0
- package/dist/core/security/captcha/types.js.map +1 -0
- package/dist/core/security/mfa/email-otp.d.ts +91 -0
- package/dist/core/security/mfa/email-otp.d.ts.map +1 -0
- package/dist/core/security/mfa/email-otp.js +264 -0
- package/dist/core/security/mfa/email-otp.js.map +1 -0
- package/dist/core/security/mfa/index.d.ts +8 -0
- package/dist/core/security/mfa/index.d.ts.map +1 -0
- package/dist/core/security/mfa/index.js +8 -0
- package/dist/core/security/mfa/index.js.map +1 -0
- package/dist/core/security/mfa/totp.d.ts +87 -0
- package/dist/core/security/mfa/totp.d.ts.map +1 -0
- package/dist/core/security/mfa/totp.js +293 -0
- package/dist/core/security/mfa/totp.js.map +1 -0
- package/dist/core/security/middleware.d.ts +102 -0
- package/dist/core/security/middleware.d.ts.map +1 -0
- package/dist/core/security/middleware.js +261 -0
- package/dist/core/security/middleware.js.map +1 -0
- package/dist/core/security/oauth/google.d.ts +76 -0
- package/dist/core/security/oauth/google.d.ts.map +1 -0
- package/dist/core/security/oauth/google.js +154 -0
- package/dist/core/security/oauth/google.js.map +1 -0
- package/dist/core/security/oauth/index.d.ts +8 -0
- package/dist/core/security/oauth/index.d.ts.map +1 -0
- package/dist/core/security/oauth/index.js +7 -0
- package/dist/core/security/oauth/index.js.map +1 -0
- package/dist/core/security/oauth2/authorization-server.d.ts +195 -0
- package/dist/core/security/oauth2/authorization-server.d.ts.map +1 -0
- package/dist/core/security/oauth2/authorization-server.js +569 -0
- package/dist/core/security/oauth2/authorization-server.js.map +1 -0
- package/dist/core/security/oauth2/index.d.ts +9 -0
- package/dist/core/security/oauth2/index.d.ts.map +1 -0
- package/dist/core/security/oauth2/index.js +9 -0
- package/dist/core/security/oauth2/index.js.map +1 -0
- package/dist/core/security/rate-limiter.d.ts +15 -0
- package/dist/core/security/rate-limiter.d.ts.map +1 -0
- package/dist/core/security/rate-limiter.js +48 -0
- package/dist/core/security/rate-limiter.js.map +1 -0
- package/dist/core/security/validation.d.ts +20 -0
- package/dist/core/security/validation.d.ts.map +1 -0
- package/dist/core/security/validation.js +273 -0
- package/dist/core/security/validation.js.map +1 -0
- package/dist/core/services/auth-service.d.ts +128 -0
- package/dist/core/services/auth-service.d.ts.map +1 -0
- package/dist/core/services/auth-service.js +530 -0
- package/dist/core/services/auth-service.js.map +1 -0
- package/dist/core/services/captcha-service.d.ts +44 -0
- package/dist/core/services/captcha-service.d.ts.map +1 -0
- package/dist/core/services/captcha-service.js +82 -0
- package/dist/core/services/captcha-service.js.map +1 -0
- package/dist/core/services/document-service.d.ts +59 -0
- package/dist/core/services/document-service.d.ts.map +1 -0
- package/dist/core/services/document-service.js +269 -0
- package/dist/core/services/document-service.js.map +1 -0
- package/dist/core/services/media-service.d.ts +40 -0
- package/dist/core/services/media-service.d.ts.map +1 -0
- package/dist/core/services/media-service.js +396 -0
- package/dist/core/services/media-service.js.map +1 -0
- package/dist/core/services/mfa-service.d.ts +123 -0
- package/dist/core/services/mfa-service.d.ts.map +1 -0
- package/dist/core/services/mfa-service.js +606 -0
- package/dist/core/services/mfa-service.js.map +1 -0
- package/dist/core/services/oauth-service.d.ts +58 -0
- package/dist/core/services/oauth-service.d.ts.map +1 -0
- package/dist/core/services/oauth-service.js +253 -0
- package/dist/core/services/oauth-service.js.map +1 -0
- package/dist/core/services/oauth2-server-service.d.ts +61 -0
- package/dist/core/services/oauth2-server-service.d.ts.map +1 -0
- package/dist/core/services/oauth2-server-service.js +259 -0
- package/dist/core/services/oauth2-server-service.js.map +1 -0
- package/dist/core/services/passkey-service.d.ts +59 -0
- package/dist/core/services/passkey-service.d.ts.map +1 -0
- package/dist/core/services/passkey-service.js +238 -0
- package/dist/core/services/passkey-service.js.map +1 -0
- package/dist/core/services/token-service.d.ts +31 -0
- package/dist/core/services/token-service.d.ts.map +1 -0
- package/dist/core/services/token-service.js +132 -0
- package/dist/core/services/token-service.js.map +1 -0
- package/dist/core/services/trusted-device-service.d.ts +39 -0
- package/dist/core/services/trusted-device-service.d.ts.map +1 -0
- package/dist/core/services/trusted-device-service.js +123 -0
- package/dist/core/services/trusted-device-service.js.map +1 -0
- package/dist/core/services/user-service.d.ts +38 -0
- package/dist/core/services/user-service.d.ts.map +1 -0
- package/dist/core/services/user-service.js +265 -0
- package/dist/core/services/user-service.js.map +1 -0
- package/dist/core/studio/integration.d.ts +54 -0
- package/dist/core/studio/integration.d.ts.map +1 -0
- package/dist/core/studio/integration.js +326 -0
- package/dist/core/studio/integration.js.map +1 -0
- package/dist/core/types/index.d.ts +282 -0
- package/dist/core/types/index.d.ts.map +1 -0
- package/dist/core/types/index.js +83 -0
- package/dist/core/types/index.js.map +1 -0
- package/dist/core/types/mail.d.ts +90 -0
- package/dist/core/types/mail.d.ts.map +1 -0
- package/dist/core/types/mail.js +7 -0
- package/dist/core/types/mail.js.map +1 -0
- package/dist/core/types/oauth2.d.ts +9 -0
- package/dist/core/types/oauth2.d.ts.map +1 -0
- package/dist/core/types/oauth2.js +7 -0
- package/dist/core/types/oauth2.js.map +1 -0
- package/dist/core/types/storage-adapters.d.ts +611 -0
- package/dist/core/types/storage-adapters.d.ts.map +1 -0
- package/dist/core/types/storage-adapters.js +14 -0
- package/dist/core/types/storage-adapters.js.map +1 -0
- package/dist/core/types/user.d.ts +10 -0
- package/dist/core/types/user.d.ts.map +1 -0
- package/dist/core/types/user.js +45 -0
- package/dist/core/types/user.js.map +1 -0
- package/dist/core/utils/id-generator.d.ts +16 -0
- package/dist/core/utils/id-generator.d.ts.map +1 -0
- package/dist/core/utils/id-generator.js +61 -0
- package/dist/core/utils/id-generator.js.map +1 -0
- package/dist/core/utils/logger.d.ts +100 -0
- package/dist/core/utils/logger.d.ts.map +1 -0
- package/dist/core/utils/logger.js +212 -0
- package/dist/core/utils/logger.js.map +1 -0
- package/dist/core/utils/reference-expander.d.ts +57 -0
- package/dist/core/utils/reference-expander.d.ts.map +1 -0
- package/dist/core/utils/reference-expander.js +192 -0
- package/dist/core/utils/reference-expander.js.map +1 -0
- package/dist/core/utils/universal-crypto.d.ts +46 -0
- package/dist/core/utils/universal-crypto.d.ts.map +1 -0
- package/dist/core/utils/universal-crypto.js +171 -0
- package/dist/core/utils/universal-crypto.js.map +1 -0
- package/dist/core/validation/validator.d.ts +11 -0
- package/dist/core/validation/validator.d.ts.map +1 -0
- package/dist/core/validation/validator.js +164 -0
- package/dist/core/validation/validator.js.map +1 -0
- package/dist/i18n/config.d.ts +4077 -0
- package/dist/i18n/config.d.ts.map +1 -0
- package/dist/i18n/config.js +116 -0
- package/dist/i18n/config.js.map +1 -0
- package/dist/i18n/hooks.d.ts +86 -0
- package/dist/i18n/hooks.d.ts.map +1 -0
- package/dist/i18n/hooks.js +122 -0
- package/dist/i18n/hooks.js.map +1 -0
- package/dist/i18n/index.d.ts +39 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +40 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/locales/en/auth.json +108 -0
- package/dist/i18n/locales/en/common.json +100 -0
- package/dist/i18n/locales/en/errors.json +55 -0
- package/dist/i18n/locales/en/fields.json +456 -0
- package/dist/i18n/locales/en/studio.json +1329 -0
- package/dist/i18n/locales/fr/auth.json +108 -0
- package/dist/i18n/locales/fr/common.json +100 -0
- package/dist/i18n/locales/fr/errors.json +55 -0
- package/dist/i18n/locales/fr/fields.json +456 -0
- package/dist/i18n/locales/fr/studio.json +1274 -0
- package/dist/i18n/provider.d.ts +45 -0
- package/dist/i18n/provider.d.ts.map +1 -0
- package/dist/i18n/provider.js +49 -0
- package/dist/i18n/provider.js.map +1 -0
- package/dist/i18n/types.d.ts +8 -0
- package/dist/i18n/types.d.ts.map +1 -0
- package/dist/i18n/types.js +7 -0
- package/dist/i18n/types.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/express/adapter.d.ts +33 -0
- package/dist/integrations/express/adapter.d.ts.map +1 -0
- package/dist/integrations/express/adapter.js +203 -0
- package/dist/integrations/express/adapter.js.map +1 -0
- package/dist/integrations/express/config.d.ts +599 -0
- package/dist/integrations/express/config.d.ts.map +1 -0
- package/dist/integrations/express/config.js +166 -0
- package/dist/integrations/express/config.js.map +1 -0
- package/dist/integrations/express/index.d.ts +10 -0
- package/dist/integrations/express/index.d.ts.map +1 -0
- package/dist/integrations/express/index.js +9 -0
- package/dist/integrations/express/index.js.map +1 -0
- package/dist/integrations/express/integration.d.ts +111 -0
- package/dist/integrations/express/integration.d.ts.map +1 -0
- package/dist/integrations/express/integration.js +730 -0
- package/dist/integrations/express/integration.js.map +1 -0
- package/dist/integrations/express/media-rewrite-middleware.d.ts +78 -0
- package/dist/integrations/express/media-rewrite-middleware.d.ts.map +1 -0
- package/dist/integrations/express/media-rewrite-middleware.js +211 -0
- package/dist/integrations/express/media-rewrite-middleware.js.map +1 -0
- package/dist/integrations/express/media-url-generator.d.ts +52 -0
- package/dist/integrations/express/media-url-generator.d.ts.map +1 -0
- package/dist/integrations/express/media-url-generator.js +107 -0
- package/dist/integrations/express/media-url-generator.js.map +1 -0
- package/dist/integrations/express/middleware.d.ts +25 -0
- package/dist/integrations/express/middleware.d.ts.map +1 -0
- package/dist/integrations/express/middleware.js +130 -0
- package/dist/integrations/express/middleware.js.map +1 -0
- package/dist/integrations/express/server.d.ts +99 -0
- package/dist/integrations/express/server.d.ts.map +1 -0
- package/dist/integrations/express/server.js +597 -0
- package/dist/integrations/express/server.js.map +1 -0
- package/dist/integrations/express/types.d.ts +106 -0
- package/dist/integrations/express/types.d.ts.map +1 -0
- package/dist/integrations/express/types.js +2 -0
- package/dist/integrations/express/types.js.map +1 -0
- package/dist/mail/adapters/console.d.ts +30 -0
- package/dist/mail/adapters/console.d.ts.map +1 -0
- package/dist/mail/adapters/console.js +169 -0
- package/dist/mail/adapters/console.js.map +1 -0
- package/dist/mail/adapters/resend.d.ts +18 -0
- package/dist/mail/adapters/resend.d.ts.map +1 -0
- package/dist/mail/adapters/resend.js +148 -0
- package/dist/mail/adapters/resend.js.map +1 -0
- package/dist/mail/adapters/smtp.d.ts +22 -0
- package/dist/mail/adapters/smtp.d.ts.map +1 -0
- package/dist/mail/adapters/smtp.js +180 -0
- package/dist/mail/adapters/smtp.js.map +1 -0
- package/dist/mail/index.d.ts +15 -0
- package/dist/mail/index.d.ts.map +1 -0
- package/dist/mail/index.js +13 -0
- package/dist/mail/index.js.map +1 -0
- package/dist/mail/mail-service.d.ts +180 -0
- package/dist/mail/mail-service.d.ts.map +1 -0
- package/dist/mail/mail-service.js +370 -0
- package/dist/mail/mail-service.js.map +1 -0
- package/dist/mail/notification-service.d.ts +82 -0
- package/dist/mail/notification-service.d.ts.map +1 -0
- package/dist/mail/notification-service.js +262 -0
- package/dist/mail/notification-service.js.map +1 -0
- package/dist/mail/templates/built-in-templates.d.ts +47 -0
- package/dist/mail/templates/built-in-templates.d.ts.map +1 -0
- package/dist/mail/templates/built-in-templates.js +416 -0
- package/dist/mail/templates/built-in-templates.js.map +1 -0
- package/dist/mail/templates/custom-template-renderer.d.ts +115 -0
- package/dist/mail/templates/custom-template-renderer.d.ts.map +1 -0
- package/dist/mail/templates/custom-template-renderer.js +225 -0
- package/dist/mail/templates/custom-template-renderer.js.map +1 -0
- package/dist/mail/types.d.ts +7 -0
- package/dist/mail/types.d.ts.map +1 -0
- package/dist/mail/types.js +7 -0
- package/dist/mail/types.js.map +1 -0
- package/dist/routes/auth/captcha.d.ts +33 -0
- package/dist/routes/auth/captcha.d.ts.map +1 -0
- package/dist/routes/auth/captcha.js +102 -0
- package/dist/routes/auth/captcha.js.map +1 -0
- package/dist/routes/auth/change-password.d.ts +17 -0
- package/dist/routes/auth/change-password.d.ts.map +1 -0
- package/dist/routes/auth/change-password.js +121 -0
- package/dist/routes/auth/change-password.js.map +1 -0
- package/dist/routes/auth/index.d.ts +13 -0
- package/dist/routes/auth/index.d.ts.map +1 -0
- package/dist/routes/auth/index.js +35 -0
- package/dist/routes/auth/index.js.map +1 -0
- package/dist/routes/auth/mfa.d.ts +121 -0
- package/dist/routes/auth/mfa.d.ts.map +1 -0
- package/dist/routes/auth/mfa.js +1143 -0
- package/dist/routes/auth/mfa.js.map +1 -0
- package/dist/routes/auth/oauth.d.ts +37 -0
- package/dist/routes/auth/oauth.d.ts.map +1 -0
- package/dist/routes/auth/oauth.js +420 -0
- package/dist/routes/auth/oauth.js.map +1 -0
- package/dist/routes/auth/oauth2-server.d.ts +70 -0
- package/dist/routes/auth/oauth2-server.d.ts.map +1 -0
- package/dist/routes/auth/oauth2-server.js +775 -0
- package/dist/routes/auth/oauth2-server.js.map +1 -0
- package/dist/routes/auth/passkey.d.ts +65 -0
- package/dist/routes/auth/passkey.d.ts.map +1 -0
- package/dist/routes/auth/passkey.js +910 -0
- package/dist/routes/auth/passkey.js.map +1 -0
- package/dist/routes/auth/password-reset.d.ts +23 -0
- package/dist/routes/auth/password-reset.d.ts.map +1 -0
- package/dist/routes/auth/password-reset.js +336 -0
- package/dist/routes/auth/password-reset.js.map +1 -0
- package/dist/routes/handlers/audit.d.ts +21 -0
- package/dist/routes/handlers/audit.d.ts.map +1 -0
- package/dist/routes/handlers/audit.js +124 -0
- package/dist/routes/handlers/audit.js.map +1 -0
- package/dist/routes/handlers/auth.d.ts +150 -0
- package/dist/routes/handlers/auth.d.ts.map +1 -0
- package/dist/routes/handlers/auth.js +512 -0
- package/dist/routes/handlers/auth.js.map +1 -0
- package/dist/routes/handlers/base.d.ts +34 -0
- package/dist/routes/handlers/base.d.ts.map +1 -0
- package/dist/routes/handlers/base.js +366 -0
- package/dist/routes/handlers/base.js.map +1 -0
- package/dist/routes/handlers/config.d.ts +31 -0
- package/dist/routes/handlers/config.d.ts.map +1 -0
- package/dist/routes/handlers/config.js +483 -0
- package/dist/routes/handlers/config.js.map +1 -0
- package/dist/routes/handlers/documents.d.ts +50 -0
- package/dist/routes/handlers/documents.d.ts.map +1 -0
- package/dist/routes/handlers/documents.js +708 -0
- package/dist/routes/handlers/documents.js.map +1 -0
- package/dist/routes/handlers/index.d.ts +12 -0
- package/dist/routes/handlers/index.d.ts.map +1 -0
- package/dist/routes/handlers/index.js +11 -0
- package/dist/routes/handlers/index.js.map +1 -0
- package/dist/routes/handlers/media.d.ts +24 -0
- package/dist/routes/handlers/media.d.ts.map +1 -0
- package/dist/routes/handlers/media.js +432 -0
- package/dist/routes/handlers/media.js.map +1 -0
- package/dist/routes/handlers/search.d.ts +10 -0
- package/dist/routes/handlers/search.d.ts.map +1 -0
- package/dist/routes/handlers/search.js +153 -0
- package/dist/routes/handlers/search.js.map +1 -0
- package/dist/routes/handlers/tokens.d.ts +14 -0
- package/dist/routes/handlers/tokens.d.ts.map +1 -0
- package/dist/routes/handlers/tokens.js +109 -0
- package/dist/routes/handlers/tokens.js.map +1 -0
- package/dist/routes/handlers/types.d.ts +13 -0
- package/dist/routes/handlers/types.d.ts.map +1 -0
- package/dist/routes/handlers/types.js +5 -0
- package/dist/routes/handlers/types.js.map +1 -0
- package/dist/routes/handlers/users.d.ts +16 -0
- package/dist/routes/handlers/users.d.ts.map +1 -0
- package/dist/routes/handlers/users.js +198 -0
- package/dist/routes/handlers/users.js.map +1 -0
- package/dist/routes/handlers/webhooks.d.ts +37 -0
- package/dist/routes/handlers/webhooks.d.ts.map +1 -0
- package/dist/routes/handlers/webhooks.js +343 -0
- package/dist/routes/handlers/webhooks.js.map +1 -0
- package/dist/routes/index.d.ts +5 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +5 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/routes.d.ts +29 -0
- package/dist/routes/routes.d.ts.map +1 -0
- package/dist/routes/routes.js +531 -0
- package/dist/routes/routes.js.map +1 -0
- package/dist/routes/slug-processor.d.ts +32 -0
- package/dist/routes/slug-processor.d.ts.map +1 -0
- package/dist/routes/slug-processor.js +328 -0
- package/dist/routes/slug-processor.js.map +1 -0
- package/dist/routes/types.d.ts +31 -0
- package/dist/routes/types.d.ts.map +1 -0
- package/dist/routes/types.js +7 -0
- package/dist/routes/types.js.map +1 -0
- package/dist/routes/users/index.d.ts +7 -0
- package/dist/routes/users/index.d.ts.map +1 -0
- package/dist/routes/users/index.js +7 -0
- package/dist/routes/users/index.js.map +1 -0
- package/dist/structure/builder/StructureBuilder.d.ts +209 -0
- package/dist/structure/builder/StructureBuilder.d.ts.map +1 -0
- package/dist/structure/builder/StructureBuilder.js +425 -0
- package/dist/structure/builder/StructureBuilder.js.map +1 -0
- package/dist/structure/builder/index.d.ts +8 -0
- package/dist/structure/builder/index.d.ts.map +1 -0
- package/dist/structure/builder/index.js +6 -0
- package/dist/structure/builder/index.js.map +1 -0
- package/dist/structure/builder/navigation-tree-builder.d.ts +33 -0
- package/dist/structure/builder/navigation-tree-builder.d.ts.map +1 -0
- package/dist/structure/builder/navigation-tree-builder.js +284 -0
- package/dist/structure/builder/navigation-tree-builder.js.map +1 -0
- package/dist/structure/errors/index.d.ts +72 -0
- package/dist/structure/errors/index.d.ts.map +1 -0
- package/dist/structure/errors/index.js +136 -0
- package/dist/structure/errors/index.js.map +1 -0
- package/dist/structure/index.d.ts +14 -0
- package/dist/structure/index.d.ts.map +1 -0
- package/dist/structure/index.js +16 -0
- package/dist/structure/index.js.map +1 -0
- package/dist/structure/types/filters.d.ts +167 -0
- package/dist/structure/types/filters.d.ts.map +1 -0
- package/dist/structure/types/filters.js +38 -0
- package/dist/structure/types/filters.js.map +1 -0
- package/dist/structure/types/index.d.ts +11 -0
- package/dist/structure/types/index.d.ts.map +1 -0
- package/dist/structure/types/index.js +7 -0
- package/dist/structure/types/index.js.map +1 -0
- package/dist/structure/types/permissions.d.ts +159 -0
- package/dist/structure/types/permissions.d.ts.map +1 -0
- package/dist/structure/types/permissions.js +49 -0
- package/dist/structure/types/permissions.js.map +1 -0
- package/dist/structure/types/structure.d.ts +342 -0
- package/dist/structure/types/structure.d.ts.map +1 -0
- package/dist/structure/types/structure.js +6 -0
- package/dist/structure/types/structure.js.map +1 -0
- package/dist/structure/types/views.d.ts +278 -0
- package/dist/structure/types/views.d.ts.map +1 -0
- package/dist/structure/types/views.js +6 -0
- package/dist/structure/types/views.js.map +1 -0
- package/dist/structure/utils/hash.d.ts +61 -0
- package/dist/structure/utils/hash.d.ts.map +1 -0
- package/dist/structure/utils/hash.js +118 -0
- package/dist/structure/utils/hash.js.map +1 -0
- package/dist/structure/utils/index.d.ts +10 -0
- package/dist/structure/utils/index.d.ts.map +1 -0
- package/dist/structure/utils/index.js +7 -0
- package/dist/structure/utils/index.js.map +1 -0
- package/dist/structure/utils/permission-checker.d.ts +57 -0
- package/dist/structure/utils/permission-checker.d.ts.map +1 -0
- package/dist/structure/utils/permission-checker.js +286 -0
- package/dist/structure/utils/permission-checker.js.map +1 -0
- package/dist/structure/utils/query-builder.d.ts +82 -0
- package/dist/structure/utils/query-builder.d.ts.map +1 -0
- package/dist/structure/utils/query-builder.js +489 -0
- package/dist/structure/utils/query-builder.js.map +1 -0
- package/dist/structure/utils/structure-merger.d.ts +91 -0
- package/dist/structure/utils/structure-merger.d.ts.map +1 -0
- package/dist/structure/utils/structure-merger.js +445 -0
- package/dist/structure/utils/structure-merger.js.map +1 -0
- package/dist/structure/validation/schemas.d.ts +3107 -0
- package/dist/structure/validation/schemas.d.ts.map +1 -0
- package/dist/structure/validation/schemas.js +436 -0
- package/dist/structure/validation/schemas.js.map +1 -0
- package/dist/types/api-requests.d.ts +334 -0
- package/dist/types/api-requests.d.ts.map +1 -0
- package/dist/types/api-requests.js +8 -0
- package/dist/types/api-requests.js.map +1 -0
- package/dist/types/auth.d.ts +394 -0
- package/dist/types/auth.d.ts.map +1 -0
- package/dist/types/auth.js +8 -0
- package/dist/types/auth.js.map +1 -0
- package/dist/types/document.d.ts +49 -0
- package/dist/types/document.d.ts.map +1 -0
- package/dist/types/document.js +6 -0
- package/dist/types/document.js.map +1 -0
- package/dist/types/field-system.d.ts +197 -0
- package/dist/types/field-system.d.ts.map +1 -0
- package/dist/types/field-system.js +8 -0
- package/dist/types/field-system.js.map +1 -0
- package/dist/types/fields.d.ts +17 -0
- package/dist/types/fields.d.ts.map +1 -0
- package/dist/types/fields.js +21 -0
- package/dist/types/fields.js.map +1 -0
- package/dist/types/http.d.ts +162 -0
- package/dist/types/http.d.ts.map +1 -0
- package/dist/types/http.js +8 -0
- package/dist/types/http.js.map +1 -0
- package/dist/types/i18n.d.ts +56 -0
- package/dist/types/i18n.d.ts.map +1 -0
- package/dist/types/i18n.js +25 -0
- package/dist/types/i18n.js.map +1 -0
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +10 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/mail.d.ts +224 -0
- package/dist/types/mail.d.ts.map +1 -0
- package/dist/types/mail.js +8 -0
- package/dist/types/mail.js.map +1 -0
- package/dist/types/media.d.ts +56 -0
- package/dist/types/media.d.ts.map +1 -0
- package/dist/types/media.js +6 -0
- package/dist/types/media.js.map +1 -0
- package/dist/types/oauth2.d.ts +287 -0
- package/dist/types/oauth2.d.ts.map +1 -0
- package/dist/types/oauth2.js +43 -0
- package/dist/types/oauth2.js.map +1 -0
- package/dist/types/passkey.d.ts +217 -0
- package/dist/types/passkey.d.ts.map +1 -0
- package/dist/types/passkey.js +8 -0
- package/dist/types/passkey.js.map +1 -0
- package/dist/types/slug.d.ts +99 -0
- package/dist/types/slug.d.ts.map +1 -0
- package/dist/types/slug.js +8 -0
- package/dist/types/slug.js.map +1 -0
- package/package.json +183 -0
|
@@ -0,0 +1,730 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import cors from 'cors';
|
|
3
|
+
import { TrokkyRoutes } from '../../routes/index.js';
|
|
4
|
+
import { ExpressAdapter } from './adapter.js';
|
|
5
|
+
import { TrokkyExpressMiddleware } from './middleware.js';
|
|
6
|
+
import { createLogger, TrokkyCore, } from '../../core/index.js';
|
|
7
|
+
import { withDefaults } from './config.js';
|
|
8
|
+
import { assertSingletonConsistency, checkSingletonStoredIds } from '../../core/schema/singleton.js';
|
|
9
|
+
/**
|
|
10
|
+
* Main Express integration class for Trokky CMS
|
|
11
|
+
*
|
|
12
|
+
* Creates an Express router with all Trokky routes and middleware
|
|
13
|
+
*/
|
|
14
|
+
export class TrokkyExpress {
|
|
15
|
+
routes; // Make public for debugging
|
|
16
|
+
adapter;
|
|
17
|
+
middleware;
|
|
18
|
+
config;
|
|
19
|
+
logger = createLogger('express', 'TrokkyExpress');
|
|
20
|
+
mountedApiPath = null;
|
|
21
|
+
mountedStudioPath = null;
|
|
22
|
+
studioConfig = null;
|
|
23
|
+
i18nConfig = null;
|
|
24
|
+
structureConfig = null;
|
|
25
|
+
constructor(config) {
|
|
26
|
+
if (!config.core) {
|
|
27
|
+
throw new Error('TrokkyExpress requires config.core. Use TrokkyExpress.create() instead of constructing directly.');
|
|
28
|
+
}
|
|
29
|
+
this.config = config;
|
|
30
|
+
// Validate configuration to prevent common mounting issues
|
|
31
|
+
if (config.basePath && config.basePath.startsWith('/api')) {
|
|
32
|
+
this.logger.warn('basePath starts with "/api" but routes will be mounted on a path. ' +
|
|
33
|
+
'This may cause double paths like "/api/api/v1/*". ' +
|
|
34
|
+
'Consider using basePath: "" and mounting the router on your desired path.', { basePath: config.basePath });
|
|
35
|
+
}
|
|
36
|
+
this.routes = new TrokkyRoutes(config);
|
|
37
|
+
this.adapter = new ExpressAdapter({
|
|
38
|
+
maxFileSize: config.fileUpload?.maxFileSize || 50 * 1024 * 1024,
|
|
39
|
+
});
|
|
40
|
+
this.middleware = new TrokkyExpressMiddleware(config);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Create complete Express integration with router and middleware
|
|
44
|
+
*/
|
|
45
|
+
async createIntegration() {
|
|
46
|
+
const router = this.createRouter();
|
|
47
|
+
const staticRouter = this.createStaticRouter();
|
|
48
|
+
const middleware = this.middleware.getMiddleware();
|
|
49
|
+
// Create Studio router if enabled
|
|
50
|
+
let studioRouter;
|
|
51
|
+
if (this.config.studio?.enabled !== false) {
|
|
52
|
+
studioRouter = await this.createStudioRouter();
|
|
53
|
+
}
|
|
54
|
+
// Create auto-mount function
|
|
55
|
+
const mount = (app, options) => {
|
|
56
|
+
const apiPath = options?.apiPath ?? '/api';
|
|
57
|
+
const studioPath = options?.studioPath ?? '/studio';
|
|
58
|
+
// Store the mounted paths for Studio config and external access
|
|
59
|
+
this.mountedApiPath = apiPath;
|
|
60
|
+
this.mountedStudioPath = studioPath;
|
|
61
|
+
// Update Studio config with correct apiBasePath if Studio is enabled
|
|
62
|
+
if (this.config.studio?.enabled && this.studioConfig) {
|
|
63
|
+
this.studioConfig.apiBasePath = apiPath;
|
|
64
|
+
if (this.studioConfig.mediaUrlGenerator) {
|
|
65
|
+
this.studioConfig.mediaUrlGenerator.options.apiBasePath = apiPath;
|
|
66
|
+
}
|
|
67
|
+
this.logger.debug('Updated Studio config with apiBasePath', {
|
|
68
|
+
apiBasePath: apiPath,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
// Trust the first proxy hop (common for SSL termination)
|
|
72
|
+
// This allows Express to respect X-Forwarded-Proto for generating secure URLs
|
|
73
|
+
app.set('trust proxy', 1);
|
|
74
|
+
this.logger.info('Express trust proxy enabled to handle x-forwarded-proto');
|
|
75
|
+
// Apply CORS middleware FIRST (before any routes)
|
|
76
|
+
if (this.config.server?.cors) {
|
|
77
|
+
this.logger.debug('Applying CORS middleware', {
|
|
78
|
+
cors: this.config.server.cors,
|
|
79
|
+
});
|
|
80
|
+
app.use(cors(this.config.server.cors));
|
|
81
|
+
}
|
|
82
|
+
this.logger.info('Auto-mounting Trokky routers', {
|
|
83
|
+
apiPath,
|
|
84
|
+
studioPath,
|
|
85
|
+
hasStudio: !!studioRouter,
|
|
86
|
+
});
|
|
87
|
+
// Mount API routes
|
|
88
|
+
app.use(apiPath, router);
|
|
89
|
+
// Mount static routes at root level (no authentication)
|
|
90
|
+
app.use('/', staticRouter);
|
|
91
|
+
// Mount Studio if enabled
|
|
92
|
+
if (studioRouter) {
|
|
93
|
+
app.use(studioPath, studioRouter);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
return {
|
|
97
|
+
router,
|
|
98
|
+
staticRouter,
|
|
99
|
+
studioRouter,
|
|
100
|
+
middleware,
|
|
101
|
+
config: this.config,
|
|
102
|
+
core: this.config.core, // Expose core for mail and other integrations
|
|
103
|
+
mount,
|
|
104
|
+
getMountedApiPath: () => this.getMountedApiPath(),
|
|
105
|
+
getMountedStudioPath: () => this.getMountedStudioPath(),
|
|
106
|
+
getMountedPaths: () => this.getMountedPaths(),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Create Express router with API routes only (excludes static routes)
|
|
111
|
+
*/
|
|
112
|
+
createRouter() {
|
|
113
|
+
const router = Router();
|
|
114
|
+
// Apply middleware to router first
|
|
115
|
+
const middleware = this.middleware.getMiddleware();
|
|
116
|
+
for (const middlewareFn of middleware) {
|
|
117
|
+
router.use(middlewareFn);
|
|
118
|
+
}
|
|
119
|
+
// Get only API routes from TrokkyRoutes (not static routes)
|
|
120
|
+
const routeDefinitions = this.routes.getApiRoutes();
|
|
121
|
+
this.logger.info('Creating Express router', {
|
|
122
|
+
routeCount: routeDefinitions.length,
|
|
123
|
+
});
|
|
124
|
+
// Add each route to Express router
|
|
125
|
+
for (const routeDef of routeDefinitions) {
|
|
126
|
+
this.logger.debug('Registering route', {
|
|
127
|
+
method: routeDef.method,
|
|
128
|
+
path: routeDef.path,
|
|
129
|
+
});
|
|
130
|
+
const expressHandler = this.adapter.handleRoute(routeDef.handler);
|
|
131
|
+
// Map HTTP methods to Express router methods - cast to any to handle type compatibility
|
|
132
|
+
switch (routeDef.method) {
|
|
133
|
+
case 'GET':
|
|
134
|
+
router.get(routeDef.path, expressHandler);
|
|
135
|
+
break;
|
|
136
|
+
case 'POST':
|
|
137
|
+
router.post(routeDef.path, expressHandler);
|
|
138
|
+
break;
|
|
139
|
+
case 'PUT':
|
|
140
|
+
router.put(routeDef.path, expressHandler);
|
|
141
|
+
break;
|
|
142
|
+
case 'DELETE':
|
|
143
|
+
router.delete(routeDef.path, expressHandler);
|
|
144
|
+
break;
|
|
145
|
+
case 'PATCH':
|
|
146
|
+
router.patch(routeDef.path, expressHandler);
|
|
147
|
+
break;
|
|
148
|
+
case 'OPTIONS':
|
|
149
|
+
router.options(routeDef.path, expressHandler);
|
|
150
|
+
break;
|
|
151
|
+
default:
|
|
152
|
+
this.logger.warn('Unsupported HTTP method', {
|
|
153
|
+
method: routeDef.method,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return router;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Create Express router with static routes only (excludes API routes)
|
|
161
|
+
*/
|
|
162
|
+
createStaticRouter() {
|
|
163
|
+
const router = Router();
|
|
164
|
+
// Get only static routes from TrokkyRoutes
|
|
165
|
+
const staticRoutes = this.routes.getStaticRoutes();
|
|
166
|
+
this.logger.info('Creating static router', {
|
|
167
|
+
routeCount: staticRoutes.length,
|
|
168
|
+
});
|
|
169
|
+
// Add each static route to Express router
|
|
170
|
+
for (const routeDef of staticRoutes) {
|
|
171
|
+
this.logger.debug('Registering static route', {
|
|
172
|
+
method: routeDef.method,
|
|
173
|
+
path: routeDef.path,
|
|
174
|
+
});
|
|
175
|
+
const expressHandler = this.adapter.handleRoute(routeDef.handler);
|
|
176
|
+
// Static routes are typically GET only
|
|
177
|
+
router.get(routeDef.path, expressHandler);
|
|
178
|
+
}
|
|
179
|
+
return router;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Create Studio router if Studio integration is enabled
|
|
183
|
+
*/
|
|
184
|
+
async createStudioRouter() {
|
|
185
|
+
if (!this.config.studio) {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
this.logger.info('Creating Studio router with dynamic config injection');
|
|
189
|
+
const router = Router();
|
|
190
|
+
try {
|
|
191
|
+
// Import Studio assets utilities (separate @trokky/studio package)
|
|
192
|
+
const { getStudioHTML, getStudioAsset } = await import(
|
|
193
|
+
// @ts-ignore - @trokky/studio is an optional peer dependency resolved at runtime
|
|
194
|
+
'@trokky/studio/dist/server/assets.js');
|
|
195
|
+
// Serve Studio HTML with dynamic config injection
|
|
196
|
+
router.get('/', (req, res) => {
|
|
197
|
+
try {
|
|
198
|
+
const studioConfig = {
|
|
199
|
+
mode: 'production',
|
|
200
|
+
apiBasePath: this.getMountedApiPath(), // Use dynamic API path
|
|
201
|
+
basePath: this.getMountedStudioPath(), // Set the base path for routing
|
|
202
|
+
backendUrl: req.protocol + '://' + req.get('host') + this.getMountedApiPath(), // Full backend URL for integrated Studio
|
|
203
|
+
schemas: this.config.core?.getAllSchemas() || [],
|
|
204
|
+
branding: this.config.studio?.branding,
|
|
205
|
+
structure: this.config.studio?.structure,
|
|
206
|
+
config: this.config.studio?.config || {},
|
|
207
|
+
customFields: this.config.studio?.customFields || [],
|
|
208
|
+
mediaUrlGenerator: this.config.media?.mediaUrlGenerator,
|
|
209
|
+
i18n: this.i18nConfig || undefined,
|
|
210
|
+
};
|
|
211
|
+
const html = getStudioHTML(studioConfig, this.getMountedStudioPath());
|
|
212
|
+
res.setHeader('Content-Type', 'text/html');
|
|
213
|
+
res.send(html);
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
this.logger.error('Failed to serve Studio HTML', error);
|
|
217
|
+
res.status(500).send('Studio temporarily unavailable');
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
// Serve Studio assets
|
|
221
|
+
router.get('/assets/:filename', (req, res) => {
|
|
222
|
+
try {
|
|
223
|
+
const asset = getStudioAsset(req.params.filename);
|
|
224
|
+
if (!asset) {
|
|
225
|
+
return res.status(404).send('Asset not found');
|
|
226
|
+
}
|
|
227
|
+
res.setHeader('Content-Type', asset.contentType);
|
|
228
|
+
res.send(asset.content);
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
this.logger.error('Failed to serve Studio asset', error);
|
|
232
|
+
res.status(500).send('Asset unavailable');
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
// SPA catch-all route - serve Studio HTML for any unmatched Studio routes
|
|
236
|
+
// This enables client-side routing to work on page refresh
|
|
237
|
+
router.get('*', (req, res) => {
|
|
238
|
+
try {
|
|
239
|
+
const studioConfig = {
|
|
240
|
+
mode: 'production',
|
|
241
|
+
apiBasePath: this.getMountedApiPath(), // Use dynamic API path
|
|
242
|
+
basePath: this.getMountedStudioPath(), // Set the base path for routing
|
|
243
|
+
backendUrl: req.protocol + '://' + req.get('host') + this.getMountedApiPath(), // Full backend URL for integrated Studio
|
|
244
|
+
schemas: this.config.core?.getAllSchemas() || [],
|
|
245
|
+
branding: this.config.studio?.branding,
|
|
246
|
+
structure: this.config.studio?.structure,
|
|
247
|
+
config: this.config.studio?.config || {},
|
|
248
|
+
customFields: this.config.studio?.customFields || [],
|
|
249
|
+
mediaUrlGenerator: this.config.media?.mediaUrlGenerator,
|
|
250
|
+
i18n: this.i18nConfig || undefined,
|
|
251
|
+
};
|
|
252
|
+
const html = getStudioHTML(studioConfig, this.getMountedStudioPath());
|
|
253
|
+
res.setHeader('Content-Type', 'text/html');
|
|
254
|
+
res.send(html);
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
this.logger.error('Failed to serve Studio HTML for SPA route', error);
|
|
258
|
+
res.status(500).send('Studio temporarily unavailable');
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
return router;
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
this.logger.error('Failed to create Studio router - Studio assets not available', error);
|
|
265
|
+
return undefined;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Get just the middleware array
|
|
270
|
+
*/
|
|
271
|
+
getMiddleware() {
|
|
272
|
+
return this.middleware.getMiddleware();
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Get the error handler middleware
|
|
276
|
+
*/
|
|
277
|
+
static getErrorHandler() {
|
|
278
|
+
return TrokkyExpressMiddleware.createErrorHandler();
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Get the currently mounted API path (useful for dynamic URL construction)
|
|
282
|
+
*/
|
|
283
|
+
getMountedApiPath() {
|
|
284
|
+
return this.mountedApiPath || '/api';
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Get the currently mounted Studio path
|
|
288
|
+
*/
|
|
289
|
+
getMountedStudioPath() {
|
|
290
|
+
return this.mountedStudioPath || '/studio';
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Get both mounted paths for easy access
|
|
294
|
+
*/
|
|
295
|
+
getMountedPaths() {
|
|
296
|
+
return {
|
|
297
|
+
apiPath: this.getMountedApiPath(),
|
|
298
|
+
studioPath: this.getMountedStudioPath(),
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* PROFESSIONAL SETUP - Clean, type-safe configuration
|
|
303
|
+
*
|
|
304
|
+
* Uses the new professional configuration system with:
|
|
305
|
+
* - Organized config sections (storage, media, security, server, studio)
|
|
306
|
+
* - Environment-aware defaults
|
|
307
|
+
* - Better TypeScript auto-completion
|
|
308
|
+
* - Integration with trokky.config.ts
|
|
309
|
+
*
|
|
310
|
+
* @example
|
|
311
|
+
* ```typescript
|
|
312
|
+
* const trokky = await TrokkyExpress.create({
|
|
313
|
+
* schemas: blogSchemas,
|
|
314
|
+
* storage: {
|
|
315
|
+
* data: { adapter: 'filesystem-data', options: { contentDir: './content' } },
|
|
316
|
+
* media: { adapter: 'filesystem-media', options: { mediaDir: './media' } }
|
|
317
|
+
* },
|
|
318
|
+
* security: { adminUser: { username: 'admin', email: 'admin@demo.com', password: 'demo123' } }
|
|
319
|
+
* })
|
|
320
|
+
*
|
|
321
|
+
* trokky.mount(app)
|
|
322
|
+
* ```
|
|
323
|
+
*/
|
|
324
|
+
static async create(config) {
|
|
325
|
+
const logger = createLogger('express', 'ProfessionalSetup');
|
|
326
|
+
logger.info('Starting professional Trokky setup');
|
|
327
|
+
try {
|
|
328
|
+
// Apply smart defaults based on environment
|
|
329
|
+
const fullConfig = withDefaults(config);
|
|
330
|
+
// 1. Create split storage adapters
|
|
331
|
+
const storageAdapters = await this.createStorageAdaptersFromConfig(fullConfig.storage);
|
|
332
|
+
// 2. Create TrokkyCore config (legacy format) - simplified since adapters are handled separately
|
|
333
|
+
const coreConfig = {
|
|
334
|
+
storage: {
|
|
335
|
+
adapter: 'split',
|
|
336
|
+
options: {},
|
|
337
|
+
},
|
|
338
|
+
schemas: fullConfig.schemas,
|
|
339
|
+
media: {
|
|
340
|
+
imageProcessor: fullConfig.media.processor,
|
|
341
|
+
imageVariants: fullConfig.media.variants || [],
|
|
342
|
+
validation: {
|
|
343
|
+
maxFileSize: fullConfig.media.upload?.maxFileSize,
|
|
344
|
+
allowedTypes: fullConfig.media.upload?.allowedMimeTypes,
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
security: {
|
|
348
|
+
validateInput: fullConfig.security.validation?.input,
|
|
349
|
+
rateLimitEnabled: fullConfig.security.rateLimit?.enabled,
|
|
350
|
+
passkey: fullConfig.security.passkey,
|
|
351
|
+
},
|
|
352
|
+
// OAuth configuration (auto-enabled when credentials are set)
|
|
353
|
+
oauth: fullConfig.oauth,
|
|
354
|
+
// CAPTCHA configuration (auto-enabled when credentials are set)
|
|
355
|
+
captcha: fullConfig.captcha,
|
|
356
|
+
// Schema enhancement features (autoThumbnail, autoSlug)
|
|
357
|
+
features: fullConfig.features,
|
|
358
|
+
};
|
|
359
|
+
// 3. Create and initialize TrokkyCore with split adapters
|
|
360
|
+
const coreOptions = {
|
|
361
|
+
enableSecurity: fullConfig.security.enabled,
|
|
362
|
+
jwtSecret: fullConfig.security.jwtSecret,
|
|
363
|
+
cryptoOptions: fullConfig.security.cryptoOptions,
|
|
364
|
+
oauth2: fullConfig.oauth2,
|
|
365
|
+
};
|
|
366
|
+
const core = new TrokkyCore(coreConfig, storageAdapters, coreOptions);
|
|
367
|
+
await core.init();
|
|
368
|
+
logger.info('TrokkyCore initialized with professional config');
|
|
369
|
+
// Build studio, structure, and i18n configs for the instance
|
|
370
|
+
let resolvedStudioConfig = null;
|
|
371
|
+
let resolvedStructureConfig = null;
|
|
372
|
+
let resolvedI18nConfig = null;
|
|
373
|
+
if (fullConfig.studio) {
|
|
374
|
+
resolvedStudioConfig = {
|
|
375
|
+
...fullConfig.studio,
|
|
376
|
+
mediaUrlGenerator: {
|
|
377
|
+
options: {
|
|
378
|
+
apiBasePath: fullConfig.server.basePath || '/api',
|
|
379
|
+
mediaConfig: {
|
|
380
|
+
serving: {
|
|
381
|
+
mode: fullConfig.media.serving?.mode || 'api',
|
|
382
|
+
},
|
|
383
|
+
},
|
|
384
|
+
},
|
|
385
|
+
},
|
|
386
|
+
media: {
|
|
387
|
+
variants: fullConfig.media.variants || [],
|
|
388
|
+
},
|
|
389
|
+
};
|
|
390
|
+
if (fullConfig.studio.structure) {
|
|
391
|
+
resolvedStructureConfig = fullConfig.studio.structure;
|
|
392
|
+
}
|
|
393
|
+
logger.debug('Studio configuration resolved');
|
|
394
|
+
}
|
|
395
|
+
if (fullConfig.i18n) {
|
|
396
|
+
resolvedI18nConfig = fullConfig.i18n;
|
|
397
|
+
logger.debug('i18n configuration resolved', {
|
|
398
|
+
defaultLocale: fullConfig.i18n.defaultLocale,
|
|
399
|
+
supportedLocales: fullConfig.i18n.supportedLocales,
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
// 4. Create admin user if specified
|
|
403
|
+
if (fullConfig.security.adminUser) {
|
|
404
|
+
try {
|
|
405
|
+
await core.createUser({
|
|
406
|
+
username: fullConfig.security.adminUser.username,
|
|
407
|
+
email: fullConfig.security.adminUser.email,
|
|
408
|
+
password: fullConfig.security.adminUser.password,
|
|
409
|
+
firstName: fullConfig.security.adminUser.firstName,
|
|
410
|
+
lastName: fullConfig.security.adminUser.lastName,
|
|
411
|
+
role: fullConfig.security.adminUser.role || 'admin',
|
|
412
|
+
});
|
|
413
|
+
logger.info('Admin user created');
|
|
414
|
+
}
|
|
415
|
+
catch (error) {
|
|
416
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
417
|
+
if (errorMessage.includes('already exists')) {
|
|
418
|
+
logger.info('Admin user already exists');
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
logger.warn('Failed to create admin user', error);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
// 5. Map professional config to Express integration config
|
|
426
|
+
const expressConfig = {
|
|
427
|
+
core,
|
|
428
|
+
basePath: fullConfig.server.basePath,
|
|
429
|
+
server: fullConfig.server, // Pass the entire server config including CORS
|
|
430
|
+
staticRoutes: fullConfig.server.static.media || fullConfig.server.static.assets
|
|
431
|
+
? {
|
|
432
|
+
...(fullConfig.server.static.media && {
|
|
433
|
+
media: {
|
|
434
|
+
mountPath: fullConfig.server.static.media.path,
|
|
435
|
+
directory: fullConfig.server.static.media.directory,
|
|
436
|
+
maxAge: fullConfig.server.static.media.maxAge,
|
|
437
|
+
},
|
|
438
|
+
}),
|
|
439
|
+
...(fullConfig.server.static.assets && {
|
|
440
|
+
assets: {
|
|
441
|
+
mountPath: fullConfig.server.static.assets.path,
|
|
442
|
+
directory: fullConfig.server.static.assets.directory,
|
|
443
|
+
maxAge: fullConfig.server.static.assets.maxAge,
|
|
444
|
+
},
|
|
445
|
+
}),
|
|
446
|
+
}
|
|
447
|
+
: undefined,
|
|
448
|
+
fileUpload: {
|
|
449
|
+
maxFileSize: fullConfig.media.upload?.maxFileSize,
|
|
450
|
+
maxFiles: fullConfig.media.upload?.maxFiles,
|
|
451
|
+
allowedMimeTypes: fullConfig.media.upload?.allowedMimeTypes,
|
|
452
|
+
},
|
|
453
|
+
bodyParser: fullConfig.server.parsing,
|
|
454
|
+
authentication: fullConfig.security.enabled
|
|
455
|
+
? {
|
|
456
|
+
enabled: fullConfig.security.enabled,
|
|
457
|
+
publicPaths: [],
|
|
458
|
+
validateToken: async (token) => {
|
|
459
|
+
try {
|
|
460
|
+
// Use core's unified token verification which checks
|
|
461
|
+
// JWT signature + expiration and API token hash
|
|
462
|
+
const session = await core.verifyAnyToken(token);
|
|
463
|
+
return session !== null;
|
|
464
|
+
}
|
|
465
|
+
catch (error) {
|
|
466
|
+
return false;
|
|
467
|
+
}
|
|
468
|
+
},
|
|
469
|
+
}
|
|
470
|
+
: undefined,
|
|
471
|
+
rateLimiting: fullConfig.security.rateLimit?.enabled
|
|
472
|
+
? fullConfig.security.rateLimit
|
|
473
|
+
: undefined,
|
|
474
|
+
studio: fullConfig.studio.enabled
|
|
475
|
+
? {
|
|
476
|
+
enabled: fullConfig.studio.enabled,
|
|
477
|
+
mount: fullConfig.studio.path,
|
|
478
|
+
auth: fullConfig.studio.requireAuth,
|
|
479
|
+
branding: fullConfig.studio.branding,
|
|
480
|
+
structure: fullConfig.studio.structure,
|
|
481
|
+
customFields: fullConfig.studio.fields,
|
|
482
|
+
config: {
|
|
483
|
+
pageSize: fullConfig.studio.settings?.pageSize,
|
|
484
|
+
enableDrafts: fullConfig.studio.settings?.enableDrafts,
|
|
485
|
+
enableVersioning: fullConfig.studio.settings?.enableVersioning,
|
|
486
|
+
session: {
|
|
487
|
+
refreshBufferMs: fullConfig.studio.session?.refreshBuffer,
|
|
488
|
+
warningBufferMs: fullConfig.studio.session?.warningBuffer,
|
|
489
|
+
checkIntervalMs: fullConfig.studio.session?.checkInterval,
|
|
490
|
+
inactivityTimeoutMs: fullConfig.studio.session?.inactivityTimeout,
|
|
491
|
+
},
|
|
492
|
+
},
|
|
493
|
+
}
|
|
494
|
+
: undefined,
|
|
495
|
+
};
|
|
496
|
+
// 6. Create final integration
|
|
497
|
+
logger.debug('Creating integration with expressConfig', {
|
|
498
|
+
hasCore: !!expressConfig.core,
|
|
499
|
+
coreId: expressConfig.core ? 'present' : 'missing',
|
|
500
|
+
});
|
|
501
|
+
const integration = new TrokkyExpress(expressConfig);
|
|
502
|
+
// Store configs on instance (replaces global state pattern)
|
|
503
|
+
integration.studioConfig = resolvedStudioConfig;
|
|
504
|
+
integration.structureConfig = resolvedStructureConfig;
|
|
505
|
+
integration.i18nConfig = resolvedI18nConfig;
|
|
506
|
+
// Pass studio/structure config to routes via shared config reference
|
|
507
|
+
integration.config.studioConfig = resolvedStudioConfig;
|
|
508
|
+
integration.config.structureConfig = resolvedStructureConfig;
|
|
509
|
+
// Fail now if the structure presents collections as singletons that their schemas do
|
|
510
|
+
// not declare. Left alone the mismatch is invisible until a restore regenerates those
|
|
511
|
+
// documents' ids and the structure ends up pointing at documents that no longer exist.
|
|
512
|
+
await assertResolvedStructureConsistency(resolvedStructureConfig, core, fullConfig, logger);
|
|
513
|
+
const result = await integration.createIntegration();
|
|
514
|
+
// Debug: Check result.core before and after assignment
|
|
515
|
+
logger.debug('Integration result before core assignment', {
|
|
516
|
+
hasCore: !!result.core,
|
|
517
|
+
configCore: !!expressConfig.core,
|
|
518
|
+
localCore: !!core,
|
|
519
|
+
});
|
|
520
|
+
// Ensure core is accessible in the result
|
|
521
|
+
if (!result.core) {
|
|
522
|
+
logger.warn('result.core is undefined, assigning from local core variable');
|
|
523
|
+
result.core = core;
|
|
524
|
+
}
|
|
525
|
+
// Final verification
|
|
526
|
+
logger.debug('Integration result after core assignment', {
|
|
527
|
+
hasCore: !!result.core,
|
|
528
|
+
hasEvents: !!result.core?.events,
|
|
529
|
+
});
|
|
530
|
+
logger.info('Professional setup complete!');
|
|
531
|
+
return result;
|
|
532
|
+
}
|
|
533
|
+
catch (error) {
|
|
534
|
+
logger.error('Professional setup failed', error);
|
|
535
|
+
throw new Error(`Professional setup failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Helper method to extract route parameters for dynamic routing
|
|
540
|
+
*/
|
|
541
|
+
findRouteForPath(method, path) {
|
|
542
|
+
return this.routes.findRoute(method, path);
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Helper method to extract parameters from a path
|
|
546
|
+
*/
|
|
547
|
+
extractParamsFromPath(routePattern, actualPath) {
|
|
548
|
+
return this.routes.extractParams(routePattern, actualPath);
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Create split storage adapters from configuration
|
|
552
|
+
* Split-first architecture: always creates separate data and media adapters
|
|
553
|
+
*/
|
|
554
|
+
static async createStorageAdaptersFromConfig(config) {
|
|
555
|
+
const logger = createLogger('express', 'StorageAdapter');
|
|
556
|
+
logger.info('🔄 Creating split storage adapters', {
|
|
557
|
+
dataAdapter: config.data.adapter,
|
|
558
|
+
mediaAdapter: config.media.adapter,
|
|
559
|
+
});
|
|
560
|
+
// Create data adapter
|
|
561
|
+
const dataAdapter = await this.createDataAdapter(config.data);
|
|
562
|
+
// Create media adapter
|
|
563
|
+
const mediaAdapter = await this.createMediaAdapter(config.media);
|
|
564
|
+
// Return split adapters object
|
|
565
|
+
const splitAdapters = {
|
|
566
|
+
data: dataAdapter,
|
|
567
|
+
media: mediaAdapter,
|
|
568
|
+
};
|
|
569
|
+
logger.info('Split storage adapters created successfully');
|
|
570
|
+
return splitAdapters;
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Create data storage adapter using the registry system
|
|
574
|
+
*/
|
|
575
|
+
static async createDataAdapter(config) {
|
|
576
|
+
const { createAdapter } = await import('../../core/index.js');
|
|
577
|
+
try {
|
|
578
|
+
return await createAdapter(config.adapter, 'data', {
|
|
579
|
+
// Filesystem data adapter options
|
|
580
|
+
...(config.adapter === 'filesystem-data' && {
|
|
581
|
+
contentDir: config.options?.contentDir || './content',
|
|
582
|
+
usersDir: config.options?.usersDir || './users',
|
|
583
|
+
tokensDir: config.options?.tokensDir || './tokens',
|
|
584
|
+
webhooksDir: config.options?.webhooksDir || './webhooks',
|
|
585
|
+
settingsDir: config.options?.settingsDir || './settings',
|
|
586
|
+
auditLogsDir: config.options?.auditLogsDir || './audit-logs',
|
|
587
|
+
createDirs: config.options?.createDirs ?? true,
|
|
588
|
+
prettyJson: config.options?.prettyJson ?? true,
|
|
589
|
+
jsonSpaces: config.options?.jsonSpaces ?? 2,
|
|
590
|
+
silent: config.options?.silent ?? false,
|
|
591
|
+
}),
|
|
592
|
+
// Cloudflare D1 adapter options
|
|
593
|
+
...(config.adapter === 'cloudflare-d1' && {
|
|
594
|
+
database: config.options?.database,
|
|
595
|
+
databaseName: config.options?.databaseName,
|
|
596
|
+
tablePrefix: config.options?.tablePrefix,
|
|
597
|
+
debug: config.options?.debug ?? false,
|
|
598
|
+
enableFTS: config.options?.enableFTS ?? false,
|
|
599
|
+
enableAuditLog: config.options?.enableAuditLog ?? false,
|
|
600
|
+
migrations: config.options?.migrations,
|
|
601
|
+
}),
|
|
602
|
+
// Pass through any other options
|
|
603
|
+
...config.options,
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
catch (error) {
|
|
607
|
+
throw new Error(`Failed to create data adapter "${config.adapter}": ${error instanceof Error ? error.message : String(error)}\n\n` +
|
|
608
|
+
`Available data adapters depend on imported packages:\n` +
|
|
609
|
+
`- 'filesystem-data': Requires @trokky/adapter-filesystem-data (Node.js only)\n` +
|
|
610
|
+
`- 'cloudflare-d1': Requires @trokky/adapter-cloudflare-d1 (Edge runtime)\n` +
|
|
611
|
+
`- 'dynamodb': Requires @trokky/adapter-dynamodb\n\n` +
|
|
612
|
+
`Make sure the required adapter package is installed and imported.`);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Create media storage adapter using the registry system
|
|
617
|
+
*/
|
|
618
|
+
static async createMediaAdapter(config) {
|
|
619
|
+
const { createAdapter } = await import('../../core/index.js');
|
|
620
|
+
try {
|
|
621
|
+
return await createAdapter(config.adapter, 'media', {
|
|
622
|
+
// Filesystem media adapter options
|
|
623
|
+
...(config.adapter === 'filesystem-media' && {
|
|
624
|
+
mediaDir: config.options?.mediaDir || './media',
|
|
625
|
+
createDirs: config.options?.createDirs ?? true,
|
|
626
|
+
prettyJson: config.options?.prettyJson ?? true,
|
|
627
|
+
jsonSpaces: config.options?.jsonSpaces ?? 2,
|
|
628
|
+
mediaBaseUrl: config.options?.mediaBaseUrl || '/media',
|
|
629
|
+
silent: config.options?.silent ?? false,
|
|
630
|
+
}),
|
|
631
|
+
// Cloudflare R2 adapter options
|
|
632
|
+
...(config.adapter === 'cloudflare-r2' && {
|
|
633
|
+
bucket: config.options?.bucket,
|
|
634
|
+
bucketName: config.options?.bucketName,
|
|
635
|
+
keyPrefix: config.options?.keyPrefix,
|
|
636
|
+
debug: config.options?.debug ?? false,
|
|
637
|
+
cacheControl: config.options?.cacheControl,
|
|
638
|
+
defaultMetadata: config.options?.defaultMetadata,
|
|
639
|
+
autoContentType: config.options?.autoContentType ?? true,
|
|
640
|
+
maxFileSize: config.options?.maxFileSize,
|
|
641
|
+
allowPublicUrls: config.options?.allowPublicUrls ?? false,
|
|
642
|
+
customDomain: config.options?.customDomain,
|
|
643
|
+
defaultUrlExpiry: config.options?.defaultUrlExpiry ?? 3600,
|
|
644
|
+
maxUrlExpiry: config.options?.maxUrlExpiry ?? 86400,
|
|
645
|
+
accountId: config.options?.accountId,
|
|
646
|
+
accessKeyId: config.options?.accessKeyId,
|
|
647
|
+
secretAccessKey: config.options?.secretAccessKey,
|
|
648
|
+
cspConfig: config.options?.cspConfig,
|
|
649
|
+
}),
|
|
650
|
+
// Pass through any other options
|
|
651
|
+
...config.options,
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
catch (error) {
|
|
655
|
+
throw new Error(`Failed to create media adapter "${config.adapter}": ${error instanceof Error ? error.message : String(error)}\n\n` +
|
|
656
|
+
`Available media adapters depend on imported packages:\n` +
|
|
657
|
+
`- 'filesystem-media': Requires @trokky/adapter-filesystem-media (Node.js only)\n` +
|
|
658
|
+
`- 'cloudflare-r2': Requires @trokky/adapter-cloudflare-r2 (Edge runtime)\n` +
|
|
659
|
+
`- 's3': Requires @trokky/adapter-s3\n\n` +
|
|
660
|
+
`Make sure the required adapter package is installed and imported.`);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Generate a secure JWT secret if none provided
|
|
665
|
+
*/
|
|
666
|
+
static generateSecureSecret() {
|
|
667
|
+
// Simple secure secret generation for demo purposes
|
|
668
|
+
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
669
|
+
let result = '';
|
|
670
|
+
for (let i = 0; i < 64; i++) {
|
|
671
|
+
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
672
|
+
}
|
|
673
|
+
return result;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* Run the singleton consistency check against the structure a project actually configured.
|
|
678
|
+
*
|
|
679
|
+
* The structure may be a plain object or a function of the request context; at startup there
|
|
680
|
+
* is no user, so it is resolved the same way the create and read paths resolve it. A structure
|
|
681
|
+
* that cannot be resolved here is skipped rather than fatal — only a genuine disagreement
|
|
682
|
+
* between structure and schemas stops the server.
|
|
683
|
+
*/
|
|
684
|
+
async function assertResolvedStructureConsistency(structureConfig, core, config, logger) {
|
|
685
|
+
if (!structureConfig)
|
|
686
|
+
return;
|
|
687
|
+
const schemas = core.getAllSchemas();
|
|
688
|
+
let structure;
|
|
689
|
+
try {
|
|
690
|
+
structure =
|
|
691
|
+
typeof structureConfig === 'function'
|
|
692
|
+
? await Promise.resolve(structureConfig({ user: null, schemas, core, config }))
|
|
693
|
+
: structureConfig;
|
|
694
|
+
}
|
|
695
|
+
catch (error) {
|
|
696
|
+
logger.warn('Could not resolve structure to check singleton consistency', {
|
|
697
|
+
error: error instanceof Error ? error.message : String(error),
|
|
698
|
+
});
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
try {
|
|
702
|
+
assertSingletonConsistency(structure, schemas, message => logger.warn(message));
|
|
703
|
+
}
|
|
704
|
+
catch (error) {
|
|
705
|
+
// The core is already initialised at this point, so tear it down before rethrowing:
|
|
706
|
+
// this stops the rate-limiter sweep and OAuth2 cleanup intervals and releases the
|
|
707
|
+
// storage adapters and event storage, leaving no handles behind for a host that catches
|
|
708
|
+
// this error rather than exiting. Awaiting would delay the throw for no benefit — the
|
|
709
|
+
// rethrow below is what the caller is waiting on — so failures are only logged.
|
|
710
|
+
void core.shutdown?.().catch(shutdownError => {
|
|
711
|
+
logger.warn('Error shutting down core after singleton consistency failure', {
|
|
712
|
+
error: shutdownError instanceof Error ? shutdownError.message : String(shutdownError),
|
|
713
|
+
});
|
|
714
|
+
});
|
|
715
|
+
throw error;
|
|
716
|
+
}
|
|
717
|
+
// Only once structure and schemas agree, compare what the structure names against what storage
|
|
718
|
+
// actually holds. This one reads data rather than source, so it warns and never stops the boot —
|
|
719
|
+
// see `checkSingletonStoredIds`. Its own failures are swallowed there, but the call is guarded
|
|
720
|
+
// anyway: nothing about a startup advisory should be able to take the server down.
|
|
721
|
+
try {
|
|
722
|
+
await checkSingletonStoredIds(structure, schemas, core, message => logger.warn(message));
|
|
723
|
+
}
|
|
724
|
+
catch (error) {
|
|
725
|
+
logger.warn('Could not check singleton stored document ids', {
|
|
726
|
+
error: error instanceof Error ? error.message : String(error),
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
//# sourceMappingURL=integration.js.map
|