@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,41 @@
|
|
|
1
|
+
import { ContentSchema, TrokkyConfig } from '../types/index.js';
|
|
2
|
+
export declare class SchemaRegistry {
|
|
3
|
+
private schemas;
|
|
4
|
+
private config;
|
|
5
|
+
constructor(schemas: ContentSchema[] | string, config?: TrokkyConfig['features']);
|
|
6
|
+
private loadSchemas;
|
|
7
|
+
private validateAndRegisterSchema;
|
|
8
|
+
/**
|
|
9
|
+
* Automatically injects a slug field for document schemas if:
|
|
10
|
+
* 1. It's a document type (not singleton necessarily, but typically)
|
|
11
|
+
* 2. No slug field is already defined
|
|
12
|
+
* 3. There's a 'title' field to generate from (or fallback to the first string field)
|
|
13
|
+
*/
|
|
14
|
+
private injectAutoSlugField;
|
|
15
|
+
/**
|
|
16
|
+
* Automatically injects a thumbnail field for document schemas if:
|
|
17
|
+
* 1. Feature is enabled in configuration (default: true)
|
|
18
|
+
* 2. It's a document type (or singleton if configured to include them)
|
|
19
|
+
* 3. No thumbnail/featured image field is already defined
|
|
20
|
+
* 4. Schema is not in the skip list
|
|
21
|
+
*/
|
|
22
|
+
private injectAutoThumbnailField;
|
|
23
|
+
/**
|
|
24
|
+
* Find the best field to use as slug source
|
|
25
|
+
* Priority: 'title' > 'name' > first string field
|
|
26
|
+
*/
|
|
27
|
+
private findSlugSourceField;
|
|
28
|
+
getSchema(name: string): ContentSchema | null;
|
|
29
|
+
hasSchema(name: string): boolean;
|
|
30
|
+
getAllSchemas(): ContentSchema[];
|
|
31
|
+
getSchemaNames(): string[];
|
|
32
|
+
registerSchema(schema: ContentSchema): void;
|
|
33
|
+
unregisterSchema(name: string): boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Accept the array form of `fields` ([{ name, type, ... }]) at the top level of
|
|
37
|
+
* a schema and convert it to the record form keyed by field name that the
|
|
38
|
+
* engine, validator and route handlers iterate over. Record form passes through.
|
|
39
|
+
*/
|
|
40
|
+
export declare function normalizeSchemaFields(schema: ContentSchema): ContentSchema;
|
|
41
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/core/schema/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAuB,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGpF,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAwC;IACvD,OAAO,CAAC,MAAM,CAA0B;gBAE5B,OAAO,EAAE,aAAa,EAAE,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,CAAC,UAAU,CAAC;IAWhF,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,yBAAyB;IAajC;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IA0C3B;;;;;;OAMG;IACH,OAAO,CAAC,wBAAwB;IAmHhC;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAuBpB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAI7C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIhC,aAAa,IAAI,aAAa,EAAE;IAIhC,cAAc,IAAI,MAAM,EAAE;IAI1B,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAI3C,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CAG/C;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CAiB1E"}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { ContentSchemaSchema } from '../types/index.js';
|
|
2
|
+
import { isSingletonSchema } from './singleton.js';
|
|
3
|
+
export class SchemaRegistry {
|
|
4
|
+
schemas = new Map();
|
|
5
|
+
config;
|
|
6
|
+
constructor(schemas, config) {
|
|
7
|
+
this.config = config || {};
|
|
8
|
+
if (Array.isArray(schemas)) {
|
|
9
|
+
this.loadSchemas(schemas);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
// TODO: Implement dynamic schema loading from file pattern
|
|
13
|
+
throw new Error('File-based schema loading not yet implemented');
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
loadSchemas(schemas) {
|
|
17
|
+
for (const schema of schemas) {
|
|
18
|
+
this.validateAndRegisterSchema(schema);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
validateAndRegisterSchema(schema) {
|
|
22
|
+
try {
|
|
23
|
+
// Automatically inject auto-fields for document schemas based on configuration
|
|
24
|
+
let processedSchema = this.injectAutoSlugField(normalizeSchemaFields(schema));
|
|
25
|
+
processedSchema = this.injectAutoThumbnailField(processedSchema);
|
|
26
|
+
const validatedSchema = ContentSchemaSchema.parse(processedSchema);
|
|
27
|
+
this.schemas.set(validatedSchema.name, validatedSchema);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
throw new Error(`Invalid schema "${schema.name}": ${error}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Automatically injects a slug field for document schemas if:
|
|
35
|
+
* 1. It's a document type (not singleton necessarily, but typically)
|
|
36
|
+
* 2. No slug field is already defined
|
|
37
|
+
* 3. There's a 'title' field to generate from (or fallback to the first string field)
|
|
38
|
+
*/
|
|
39
|
+
injectAutoSlugField(schema) {
|
|
40
|
+
// Skip if slug field already exists
|
|
41
|
+
if (schema.fields.slug) {
|
|
42
|
+
return schema;
|
|
43
|
+
}
|
|
44
|
+
// Find a suitable source field for slug generation
|
|
45
|
+
const sourceField = this.findSlugSourceField(schema);
|
|
46
|
+
// Only inject if we have a source field
|
|
47
|
+
if (!sourceField) {
|
|
48
|
+
return schema;
|
|
49
|
+
}
|
|
50
|
+
// Create a copy of the schema with the injected slug field
|
|
51
|
+
// Insert slug field right after the source field for better UX
|
|
52
|
+
const newFields = {};
|
|
53
|
+
for (const [fieldName, fieldDef] of Object.entries(schema.fields)) {
|
|
54
|
+
newFields[fieldName] = fieldDef;
|
|
55
|
+
// Insert slug field right after the source field
|
|
56
|
+
if (fieldName === sourceField) {
|
|
57
|
+
newFields.slug = {
|
|
58
|
+
type: 'slug',
|
|
59
|
+
// Use i18n: prefix to indicate this should be translated on the frontend
|
|
60
|
+
title: 'i18n:autoFields.slug.title',
|
|
61
|
+
description: 'i18n:autoFields.slug.description',
|
|
62
|
+
source: sourceField,
|
|
63
|
+
autoGenerate: true,
|
|
64
|
+
unique: true,
|
|
65
|
+
required: false // Auto-generated, so not strictly required from user
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
...schema,
|
|
71
|
+
fields: newFields
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Automatically injects a thumbnail field for document schemas if:
|
|
76
|
+
* 1. Feature is enabled in configuration (default: true)
|
|
77
|
+
* 2. It's a document type (or singleton if configured to include them)
|
|
78
|
+
* 3. No thumbnail/featured image field is already defined
|
|
79
|
+
* 4. Schema is not in the skip list
|
|
80
|
+
*/
|
|
81
|
+
injectAutoThumbnailField(schema) {
|
|
82
|
+
const autoThumbnailConfig = this.config?.autoThumbnail || {};
|
|
83
|
+
// Check if feature is enabled (default: true)
|
|
84
|
+
if (autoThumbnailConfig.enabled === false) {
|
|
85
|
+
return schema;
|
|
86
|
+
}
|
|
87
|
+
// Check if schema is in skip list
|
|
88
|
+
if (autoThumbnailConfig.skipSchemas?.includes(schema.name)) {
|
|
89
|
+
return schema;
|
|
90
|
+
}
|
|
91
|
+
// Skip singletons if configured to do so (default: true)
|
|
92
|
+
const skipSingletons = autoThumbnailConfig.skipSingletons !== false;
|
|
93
|
+
if (skipSingletons && isSingletonSchema(schema)) {
|
|
94
|
+
return schema;
|
|
95
|
+
}
|
|
96
|
+
// Get field name from config (default: '_thumbnail')
|
|
97
|
+
const fieldName = autoThumbnailConfig.fieldName || '_thumbnail';
|
|
98
|
+
// Skip if thumbnail field already exists (check configured name and common variations)
|
|
99
|
+
if (schema.fields[fieldName] ||
|
|
100
|
+
schema.fields._thumbnail ||
|
|
101
|
+
schema.fields.thumbnail ||
|
|
102
|
+
schema.fields.featuredImage ||
|
|
103
|
+
schema.fields.featured_image ||
|
|
104
|
+
schema.fields.image) {
|
|
105
|
+
return schema;
|
|
106
|
+
}
|
|
107
|
+
// Get configuration values with defaults
|
|
108
|
+
const maxFileSize = autoThumbnailConfig.maxFileSize || 10 * 1024 * 1024; // 10MB
|
|
109
|
+
const allowedTypes = autoThumbnailConfig.allowedTypes || [
|
|
110
|
+
'image/jpeg', 'image/png', 'image/webp', 'image/gif'
|
|
111
|
+
];
|
|
112
|
+
// Create a copy of the schema with the injected thumbnail field
|
|
113
|
+
// Insert thumbnail field at the beginning for better UX (after title/name if present)
|
|
114
|
+
const newFields = {};
|
|
115
|
+
let thumbnailInserted = false;
|
|
116
|
+
for (const [fieldKey, fieldDef] of Object.entries(schema.fields)) {
|
|
117
|
+
newFields[fieldKey] = fieldDef;
|
|
118
|
+
// Insert thumbnail field after title, name, or slug field for better UX
|
|
119
|
+
if (!thumbnailInserted && (fieldKey === 'title' || fieldKey === 'name' || fieldKey === 'slug')) {
|
|
120
|
+
newFields[fieldName] = {
|
|
121
|
+
type: 'media',
|
|
122
|
+
// Use i18n: prefix to indicate this should be translated on the frontend
|
|
123
|
+
title: 'i18n:autoFields._thumbnail.title',
|
|
124
|
+
description: 'i18n:autoFields._thumbnail.description',
|
|
125
|
+
required: false,
|
|
126
|
+
options: {
|
|
127
|
+
// Enable upload/browse functionality
|
|
128
|
+
enableUpload: true,
|
|
129
|
+
enableBrowse: true,
|
|
130
|
+
enableDragDrop: true,
|
|
131
|
+
// Media type and validation
|
|
132
|
+
showVariantSelector: true,
|
|
133
|
+
showMetadata: true,
|
|
134
|
+
showPreview: true,
|
|
135
|
+
requireAlt: true
|
|
136
|
+
},
|
|
137
|
+
validation: {
|
|
138
|
+
allowedTypes,
|
|
139
|
+
maxFileSize,
|
|
140
|
+
restrictToMediaType: 'image'
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
thumbnailInserted = true;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// If we haven't inserted it yet, add it at the beginning
|
|
147
|
+
if (!thumbnailInserted) {
|
|
148
|
+
const fieldsWithThumbnail = {
|
|
149
|
+
[fieldName]: {
|
|
150
|
+
type: 'media',
|
|
151
|
+
// Use i18n: prefix to indicate this should be translated on the frontend
|
|
152
|
+
title: 'i18n:autoFields._thumbnail.title',
|
|
153
|
+
description: 'i18n:autoFields._thumbnail.description',
|
|
154
|
+
required: false,
|
|
155
|
+
options: {
|
|
156
|
+
// Enable upload/browse functionality
|
|
157
|
+
enableUpload: true,
|
|
158
|
+
enableBrowse: true,
|
|
159
|
+
enableDragDrop: true,
|
|
160
|
+
// Media type and validation
|
|
161
|
+
showVariantSelector: true,
|
|
162
|
+
showMetadata: true,
|
|
163
|
+
showPreview: true,
|
|
164
|
+
requireAlt: true
|
|
165
|
+
},
|
|
166
|
+
validation: {
|
|
167
|
+
allowedTypes,
|
|
168
|
+
maxFileSize,
|
|
169
|
+
restrictToMediaType: 'image'
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
...newFields
|
|
173
|
+
};
|
|
174
|
+
return {
|
|
175
|
+
...schema,
|
|
176
|
+
fields: fieldsWithThumbnail
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
...schema,
|
|
181
|
+
fields: newFields
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Find the best field to use as slug source
|
|
186
|
+
* Priority: 'title' > 'name' > first string field
|
|
187
|
+
*/
|
|
188
|
+
findSlugSourceField(schema) {
|
|
189
|
+
const fields = schema.fields;
|
|
190
|
+
// Priority 1: 'title' field
|
|
191
|
+
if (fields.title && fields.title.type === 'string') {
|
|
192
|
+
return 'title';
|
|
193
|
+
}
|
|
194
|
+
// Priority 2: 'name' field
|
|
195
|
+
if (fields.name && fields.name.type === 'string') {
|
|
196
|
+
return 'name';
|
|
197
|
+
}
|
|
198
|
+
// Priority 3: First string field
|
|
199
|
+
for (const [fieldName, fieldDef] of Object.entries(fields)) {
|
|
200
|
+
if (fieldDef.type === 'string') {
|
|
201
|
+
return fieldName;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
getSchema(name) {
|
|
207
|
+
return this.schemas.get(name) || null;
|
|
208
|
+
}
|
|
209
|
+
hasSchema(name) {
|
|
210
|
+
return this.schemas.has(name);
|
|
211
|
+
}
|
|
212
|
+
getAllSchemas() {
|
|
213
|
+
return Array.from(this.schemas.values());
|
|
214
|
+
}
|
|
215
|
+
getSchemaNames() {
|
|
216
|
+
return Array.from(this.schemas.keys());
|
|
217
|
+
}
|
|
218
|
+
registerSchema(schema) {
|
|
219
|
+
this.validateAndRegisterSchema(schema);
|
|
220
|
+
}
|
|
221
|
+
unregisterSchema(name) {
|
|
222
|
+
return this.schemas.delete(name);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Accept the array form of `fields` ([{ name, type, ... }]) at the top level of
|
|
227
|
+
* a schema and convert it to the record form keyed by field name that the
|
|
228
|
+
* engine, validator and route handlers iterate over. Record form passes through.
|
|
229
|
+
*/
|
|
230
|
+
export function normalizeSchemaFields(schema) {
|
|
231
|
+
const fields = schema.fields;
|
|
232
|
+
if (!Array.isArray(fields)) {
|
|
233
|
+
return schema;
|
|
234
|
+
}
|
|
235
|
+
const record = {};
|
|
236
|
+
for (const entry of fields) {
|
|
237
|
+
const { name, ...rest } = entry;
|
|
238
|
+
if (typeof name !== 'string' || name.length === 0) {
|
|
239
|
+
throw new Error(`Schema "${schema.name}": every field in array form needs a non-empty "name"`);
|
|
240
|
+
}
|
|
241
|
+
if (name in record) {
|
|
242
|
+
throw new Error(`Schema "${schema.name}": duplicate field "${name}"`);
|
|
243
|
+
}
|
|
244
|
+
record[name] = rest;
|
|
245
|
+
}
|
|
246
|
+
return { ...schema, fields: record };
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/core/schema/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Singleton resolution — the one place that answers "does this collection hold
|
|
3
|
+
* exactly one document?".
|
|
4
|
+
*
|
|
5
|
+
* The schema is the source of truth. "Exactly one document" is a content-model
|
|
6
|
+
* invariant: it governs the create guard, the PUT upsert, and how the CLI restores
|
|
7
|
+
* a backup. A `type: 'singleton'` entry in a project's structure answers a different
|
|
8
|
+
* question — which document the navigation opens and auto-creates — and must never
|
|
9
|
+
* be used to decide the invariant, because a project can have no custom structure,
|
|
10
|
+
* a static one, or one that varies by user role.
|
|
11
|
+
*
|
|
12
|
+
* Declaring the structure entry without the schema flag used to be silent: every
|
|
13
|
+
* request still behaved correctly and the divergence only surfaced later, when a
|
|
14
|
+
* restore regenerated document ids and dropped documents. `assertSingletonConsistency`
|
|
15
|
+
* turns that into a boot failure instead.
|
|
16
|
+
*/
|
|
17
|
+
import type { ContentSchema } from '../types/index.js';
|
|
18
|
+
/** A structure entry that presents a collection as a singleton. */
|
|
19
|
+
export interface StructureSingleton {
|
|
20
|
+
collection: string;
|
|
21
|
+
documentId: string;
|
|
22
|
+
/** `options.autoCreate`, defaulting to true when the entry does not set it. */
|
|
23
|
+
autoCreate: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface SingletonConsistencyIssue {
|
|
26
|
+
collection: string;
|
|
27
|
+
documentId: string;
|
|
28
|
+
reason: 'schema-not-singleton' | 'schema-missing';
|
|
29
|
+
}
|
|
30
|
+
/** A singleton whose one stored document is filed under an id the structure does not name. */
|
|
31
|
+
export interface SingletonStoredIdIssue {
|
|
32
|
+
collection: string;
|
|
33
|
+
/** The id the structure addresses the singleton by. */
|
|
34
|
+
expectedId: string;
|
|
35
|
+
/** The id the document is actually stored under. */
|
|
36
|
+
actualId: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The slice of the core the stored-id check needs.
|
|
40
|
+
*
|
|
41
|
+
* Narrowed to one method so the check can be unit-tested without standing up an engine, and so
|
|
42
|
+
* it cannot reach for anything that writes: a boot-time advisory only ever reads.
|
|
43
|
+
*/
|
|
44
|
+
export interface SingletonDocumentReader {
|
|
45
|
+
listDocuments(collection: string, options?: {
|
|
46
|
+
limit?: number;
|
|
47
|
+
}): Promise<Array<{
|
|
48
|
+
id?: string;
|
|
49
|
+
} | null | undefined>>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Whether a schema declares itself a singleton.
|
|
53
|
+
*
|
|
54
|
+
* Both spellings are accepted: `singleton: true` and `type: 'singleton'`. Either alone means
|
|
55
|
+
* singleton, so a schema that sets `type: 'singleton'` alongside `singleton: false` is still
|
|
56
|
+
* one. Schemas are validated as `z.ZodSchema<any>`, so neither spelling is checked by the
|
|
57
|
+
* compiler and a near miss such as `isSingleton: true` is silently ignored — which is exactly
|
|
58
|
+
* why the consistency check below exists.
|
|
59
|
+
*/
|
|
60
|
+
export declare function isSingletonSchema(schema: ContentSchema | null | undefined): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Collect every `type: 'singleton'` entry in a resolved structure, walking nested items.
|
|
63
|
+
*
|
|
64
|
+
* `documentId` falls back to the collection name, matching how the Studio addresses a
|
|
65
|
+
* singleton view that does not name one explicitly.
|
|
66
|
+
*/
|
|
67
|
+
export declare function collectStructureSingletons(structure: any): StructureSingleton[];
|
|
68
|
+
/**
|
|
69
|
+
* Find structure singletons whose schema does not declare the invariant.
|
|
70
|
+
*
|
|
71
|
+
* Only this direction is a defect. A schema may be a singleton without appearing in the
|
|
72
|
+
* structure at all — it simply gets no navigation entry.
|
|
73
|
+
*/
|
|
74
|
+
export declare function findSingletonConsistencyIssues(structure: any, schemas: ContentSchema[]): SingletonConsistencyIssue[];
|
|
75
|
+
/**
|
|
76
|
+
* Throw if the structure and the schemas disagree about which collections are singletons.
|
|
77
|
+
*
|
|
78
|
+
* Called at startup so the mismatch is reported against the project's source, long before
|
|
79
|
+
* it can cost documents during a restore.
|
|
80
|
+
*
|
|
81
|
+
* Only a schema that contradicts the structure is fatal. A structure entry naming a schema
|
|
82
|
+
* that is not registered at all is reported through `onWarning` instead: it costs a broken
|
|
83
|
+
* navigation link rather than documents, and a project may legitimately leave a nav entry in
|
|
84
|
+
* place while registering its schema conditionally.
|
|
85
|
+
*/
|
|
86
|
+
export declare function assertSingletonConsistency(structure: any, schemas: ContentSchema[], onWarning?: (message: string) => void): void;
|
|
87
|
+
/**
|
|
88
|
+
* Warn when a singleton's stored document is filed under a different id than the structure names.
|
|
89
|
+
*
|
|
90
|
+
* The structure addresses a singleton by a fixed id, so a structure that says 'home' while storage
|
|
91
|
+
* holds 'homepage' silently 404s the singleton view — the document is there, nothing errors, and
|
|
92
|
+
* the only symptom is an editor screen that offers to create a document that already exists.
|
|
93
|
+
* Restores compound it, because they write back the id they find rather than the id the structure
|
|
94
|
+
* expects.
|
|
95
|
+
*
|
|
96
|
+
* This warns and never throws, unlike `assertSingletonConsistency` above. That check reads the
|
|
97
|
+
* project's own source, where a disagreement is always a defect the developer can fix on the spot.
|
|
98
|
+
* This one reads data, where the same divergence is routinely a legitimate intermediate state — a
|
|
99
|
+
* rename mid-migration, a restore from an older backup, a fixture — and refusing to boot on it
|
|
100
|
+
* would take a running site down over a condition the next deploy resolves.
|
|
101
|
+
*
|
|
102
|
+
* Only entries whose schema already agrees they are singletons are inspected; the rest belong to
|
|
103
|
+
* `findSingletonConsistencyIssues`, and reporting them twice would bury the actionable message.
|
|
104
|
+
* Returns the issues it found so callers (and tests) can act on them beyond the warning.
|
|
105
|
+
*/
|
|
106
|
+
export declare function checkSingletonStoredIds(structure: any, schemas: ContentSchema[], reader: SingletonDocumentReader | null | undefined, onWarning?: (message: string) => void): Promise<SingletonStoredIdIssue[]>;
|
|
107
|
+
//# sourceMappingURL=singleton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"singleton.d.ts","sourceRoot":"","sources":["../../../src/core/schema/singleton.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEtD,mEAAmE;AACnE,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,+EAA+E;IAC/E,UAAU,EAAE,OAAO,CAAA;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,sBAAsB,GAAG,gBAAgB,CAAA;CAClD;AAED,8FAA8F;AAC9F,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAA;IAClB,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAA;IAClB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,aAAa,CACX,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3B,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC,CAAA;CACtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAGnF;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,GAAG,GAAG,kBAAkB,EAAE,CA0B/E;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,GAAG,EACd,OAAO,EAAE,aAAa,EAAE,GACvB,yBAAyB,EAAE,CAiB7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,GAAG,EACd,OAAO,EAAE,aAAa,EAAE,EACxB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACpC,IAAI,CAyBN;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,GAAG,EACd,OAAO,EAAE,aAAa,EAAE,EACxB,MAAM,EAAE,uBAAuB,GAAG,IAAI,GAAG,SAAS,EAClD,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACpC,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAoDnC"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Singleton resolution — the one place that answers "does this collection hold
|
|
3
|
+
* exactly one document?".
|
|
4
|
+
*
|
|
5
|
+
* The schema is the source of truth. "Exactly one document" is a content-model
|
|
6
|
+
* invariant: it governs the create guard, the PUT upsert, and how the CLI restores
|
|
7
|
+
* a backup. A `type: 'singleton'` entry in a project's structure answers a different
|
|
8
|
+
* question — which document the navigation opens and auto-creates — and must never
|
|
9
|
+
* be used to decide the invariant, because a project can have no custom structure,
|
|
10
|
+
* a static one, or one that varies by user role.
|
|
11
|
+
*
|
|
12
|
+
* Declaring the structure entry without the schema flag used to be silent: every
|
|
13
|
+
* request still behaved correctly and the divergence only surfaced later, when a
|
|
14
|
+
* restore regenerated document ids and dropped documents. `assertSingletonConsistency`
|
|
15
|
+
* turns that into a boot failure instead.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Whether a schema declares itself a singleton.
|
|
19
|
+
*
|
|
20
|
+
* Both spellings are accepted: `singleton: true` and `type: 'singleton'`. Either alone means
|
|
21
|
+
* singleton, so a schema that sets `type: 'singleton'` alongside `singleton: false` is still
|
|
22
|
+
* one. Schemas are validated as `z.ZodSchema<any>`, so neither spelling is checked by the
|
|
23
|
+
* compiler and a near miss such as `isSingleton: true` is silently ignored — which is exactly
|
|
24
|
+
* why the consistency check below exists.
|
|
25
|
+
*/
|
|
26
|
+
export function isSingletonSchema(schema) {
|
|
27
|
+
if (!schema)
|
|
28
|
+
return false;
|
|
29
|
+
return schema.singleton === true || schema.type === 'singleton';
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Collect every `type: 'singleton'` entry in a resolved structure, walking nested items.
|
|
33
|
+
*
|
|
34
|
+
* `documentId` falls back to the collection name, matching how the Studio addresses a
|
|
35
|
+
* singleton view that does not name one explicitly.
|
|
36
|
+
*/
|
|
37
|
+
export function collectStructureSingletons(structure) {
|
|
38
|
+
const found = [];
|
|
39
|
+
const seen = new Set();
|
|
40
|
+
const walk = (items) => {
|
|
41
|
+
for (const item of items) {
|
|
42
|
+
if (!item || typeof item !== 'object')
|
|
43
|
+
continue;
|
|
44
|
+
// Structures are user-supplied and may be self-referential.
|
|
45
|
+
if (seen.has(item))
|
|
46
|
+
continue;
|
|
47
|
+
seen.add(item);
|
|
48
|
+
if (item.type === 'singleton' && typeof item.schemaType === 'string') {
|
|
49
|
+
found.push({
|
|
50
|
+
collection: item.schemaType,
|
|
51
|
+
documentId: item.documentId || item.schemaType,
|
|
52
|
+
autoCreate: item.options?.autoCreate !== false,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (Array.isArray(item.items))
|
|
56
|
+
walk(item.items);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
walk(Array.isArray(structure?.items) ? structure.items : []);
|
|
60
|
+
return found;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Find structure singletons whose schema does not declare the invariant.
|
|
64
|
+
*
|
|
65
|
+
* Only this direction is a defect. A schema may be a singleton without appearing in the
|
|
66
|
+
* structure at all — it simply gets no navigation entry.
|
|
67
|
+
*/
|
|
68
|
+
export function findSingletonConsistencyIssues(structure, schemas) {
|
|
69
|
+
const byName = new Map();
|
|
70
|
+
for (const schema of schemas) {
|
|
71
|
+
if (schema?.name)
|
|
72
|
+
byName.set(schema.name, schema);
|
|
73
|
+
}
|
|
74
|
+
const issues = [];
|
|
75
|
+
for (const entry of collectStructureSingletons(structure)) {
|
|
76
|
+
const { collection, documentId } = entry;
|
|
77
|
+
const schema = byName.get(collection);
|
|
78
|
+
if (!schema) {
|
|
79
|
+
issues.push({ collection, documentId, reason: 'schema-missing' });
|
|
80
|
+
}
|
|
81
|
+
else if (!isSingletonSchema(schema)) {
|
|
82
|
+
issues.push({ collection, documentId, reason: 'schema-not-singleton' });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return issues;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Throw if the structure and the schemas disagree about which collections are singletons.
|
|
89
|
+
*
|
|
90
|
+
* Called at startup so the mismatch is reported against the project's source, long before
|
|
91
|
+
* it can cost documents during a restore.
|
|
92
|
+
*
|
|
93
|
+
* Only a schema that contradicts the structure is fatal. A structure entry naming a schema
|
|
94
|
+
* that is not registered at all is reported through `onWarning` instead: it costs a broken
|
|
95
|
+
* navigation link rather than documents, and a project may legitimately leave a nav entry in
|
|
96
|
+
* place while registering its schema conditionally.
|
|
97
|
+
*/
|
|
98
|
+
export function assertSingletonConsistency(structure, schemas, onWarning) {
|
|
99
|
+
const issues = findSingletonConsistencyIssues(structure, schemas);
|
|
100
|
+
if (issues.length === 0)
|
|
101
|
+
return;
|
|
102
|
+
for (const issue of issues.filter(i => i.reason === 'schema-missing')) {
|
|
103
|
+
onWarning?.(`Structure presents '${issue.collection}' as a singleton but no schema by that name is registered`);
|
|
104
|
+
}
|
|
105
|
+
const fatal = issues.filter(issue => issue.reason === 'schema-not-singleton');
|
|
106
|
+
if (fatal.length === 0)
|
|
107
|
+
return;
|
|
108
|
+
const lines = fatal.map(issue => ` - '${issue.collection}' is presented as a singleton but its schema does not set 'singleton: true'`);
|
|
109
|
+
throw new Error(`Structure and schemas disagree about singletons:\n${lines.join('\n')}\n\n` +
|
|
110
|
+
`The schema decides whether a collection holds exactly one document. Without the flag, ` +
|
|
111
|
+
`creating and restoring documents in these collections behaves as if they were ordinary ` +
|
|
112
|
+
`list collections: a restore regenerates their document ids, so the structure ends up ` +
|
|
113
|
+
`pointing at documents that no longer exist.`);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Warn when a singleton's stored document is filed under a different id than the structure names.
|
|
117
|
+
*
|
|
118
|
+
* The structure addresses a singleton by a fixed id, so a structure that says 'home' while storage
|
|
119
|
+
* holds 'homepage' silently 404s the singleton view — the document is there, nothing errors, and
|
|
120
|
+
* the only symptom is an editor screen that offers to create a document that already exists.
|
|
121
|
+
* Restores compound it, because they write back the id they find rather than the id the structure
|
|
122
|
+
* expects.
|
|
123
|
+
*
|
|
124
|
+
* This warns and never throws, unlike `assertSingletonConsistency` above. That check reads the
|
|
125
|
+
* project's own source, where a disagreement is always a defect the developer can fix on the spot.
|
|
126
|
+
* This one reads data, where the same divergence is routinely a legitimate intermediate state — a
|
|
127
|
+
* rename mid-migration, a restore from an older backup, a fixture — and refusing to boot on it
|
|
128
|
+
* would take a running site down over a condition the next deploy resolves.
|
|
129
|
+
*
|
|
130
|
+
* Only entries whose schema already agrees they are singletons are inspected; the rest belong to
|
|
131
|
+
* `findSingletonConsistencyIssues`, and reporting them twice would bury the actionable message.
|
|
132
|
+
* Returns the issues it found so callers (and tests) can act on them beyond the warning.
|
|
133
|
+
*/
|
|
134
|
+
export async function checkSingletonStoredIds(structure, schemas, reader, onWarning) {
|
|
135
|
+
if (!reader || typeof reader.listDocuments !== 'function')
|
|
136
|
+
return [];
|
|
137
|
+
const byName = new Map();
|
|
138
|
+
for (const schema of schemas) {
|
|
139
|
+
if (schema?.name)
|
|
140
|
+
byName.set(schema.name, schema);
|
|
141
|
+
}
|
|
142
|
+
const issues = [];
|
|
143
|
+
for (const entry of collectStructureSingletons(structure)) {
|
|
144
|
+
if (!isSingletonSchema(byName.get(entry.collection)))
|
|
145
|
+
continue;
|
|
146
|
+
let documents;
|
|
147
|
+
try {
|
|
148
|
+
// One document is enough: the collection is declared to hold exactly one, and a boot check
|
|
149
|
+
// has no business paging through a collection that turned out to hold more.
|
|
150
|
+
documents = (await reader.listDocuments(entry.collection, { limit: 1 })) ?? [];
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
// An adapter that is not up yet, a collection that does not exist, a role that cannot read
|
|
154
|
+
// it — all recoverable, and none of them worth failing a boot over.
|
|
155
|
+
onWarning?.(`Could not read '${entry.collection}' to check its singleton document id: ` +
|
|
156
|
+
`${error instanceof Error ? error.message : String(error)}`);
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
// Adapters disagree about which field carries the identity: filesystem-data returns `id`,
|
|
160
|
+
// postgres-data returns `_id`. Reading only one of them makes this check silently inert on
|
|
161
|
+
// the other backend — which would have meant it never ran on a Postgres-backed site.
|
|
162
|
+
const first = Array.isArray(documents) ? documents[0] : undefined;
|
|
163
|
+
const actualId = first?.id ?? first?._id;
|
|
164
|
+
// An empty collection has not diverged from anything; auto-create will file the first
|
|
165
|
+
// document under the id the structure names.
|
|
166
|
+
if (!actualId || actualId === entry.documentId)
|
|
167
|
+
continue;
|
|
168
|
+
issues.push({
|
|
169
|
+
collection: entry.collection,
|
|
170
|
+
expectedId: entry.documentId,
|
|
171
|
+
actualId,
|
|
172
|
+
});
|
|
173
|
+
onWarning?.(`Singleton '${entry.collection}' is stored under id '${actualId}' but the structure ` +
|
|
174
|
+
`addresses it as '${entry.documentId}'. The Studio will not find the existing document ` +
|
|
175
|
+
`and will offer to create a second one; rename the document or set the structure entry's ` +
|
|
176
|
+
`documentId to '${actualId}'.`);
|
|
177
|
+
}
|
|
178
|
+
return issues;
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=singleton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"singleton.js","sourceRoot":"","sources":["../../../src/core/schema/singleton.ts"],"names":[],"mappings":"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"}
|