@portaidentity/server 1.7.0
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/CHANGELOG.md +11 -0
- package/LICENSE +21 -0
- package/README.md +33 -0
- package/dist/applications/cache.d.ts +64 -0
- package/dist/applications/cache.d.ts.map +1 -0
- package/dist/applications/cache.js +161 -0
- package/dist/applications/cache.js.map +1 -0
- package/dist/applications/errors.d.ts +25 -0
- package/dist/applications/errors.d.ts.map +1 -0
- package/dist/applications/errors.js +31 -0
- package/dist/applications/errors.js.map +1 -0
- package/dist/applications/index.d.ts +17 -0
- package/dist/applications/index.d.ts.map +1 -0
- package/dist/applications/index.js +19 -0
- package/dist/applications/index.js.map +1 -0
- package/dist/applications/repository.d.ts +184 -0
- package/dist/applications/repository.d.ts.map +1 -0
- package/dist/applications/repository.js +367 -0
- package/dist/applications/repository.js.map +1 -0
- package/dist/applications/service.d.ts +160 -0
- package/dist/applications/service.d.ts.map +1 -0
- package/dist/applications/service.js +388 -0
- package/dist/applications/service.js.map +1 -0
- package/dist/applications/slugs.d.ts +61 -0
- package/dist/applications/slugs.d.ts.map +1 -0
- package/dist/applications/slugs.js +115 -0
- package/dist/applications/slugs.js.map +1 -0
- package/dist/applications/types.d.ts +129 -0
- package/dist/applications/types.d.ts.map +1 -0
- package/dist/applications/types.js +62 -0
- package/dist/applications/types.js.map +1 -0
- package/dist/auth/csrf.d.ts +71 -0
- package/dist/auth/csrf.d.ts.map +1 -0
- package/dist/auth/csrf.js +112 -0
- package/dist/auth/csrf.js.map +1 -0
- package/dist/auth/email-renderer.d.ts +37 -0
- package/dist/auth/email-renderer.d.ts.map +1 -0
- package/dist/auth/email-renderer.js +116 -0
- package/dist/auth/email-renderer.js.map +1 -0
- package/dist/auth/email-service.d.ts +154 -0
- package/dist/auth/email-service.d.ts.map +1 -0
- package/dist/auth/email-service.js +415 -0
- package/dist/auth/email-service.js.map +1 -0
- package/dist/auth/email-transport.d.ts +65 -0
- package/dist/auth/email-transport.d.ts.map +1 -0
- package/dist/auth/email-transport.js +82 -0
- package/dist/auth/email-transport.js.map +1 -0
- package/dist/auth/i18n.d.ts +81 -0
- package/dist/auth/i18n.d.ts.map +1 -0
- package/dist/auth/i18n.js +395 -0
- package/dist/auth/i18n.js.map +1 -0
- package/dist/auth/index.d.ts +28 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +31 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/interaction-authority.d.ts +39 -0
- package/dist/auth/interaction-authority.d.ts.map +1 -0
- package/dist/auth/interaction-authority.js +30 -0
- package/dist/auth/interaction-authority.js.map +1 -0
- package/dist/auth/magic-link-session.d.ts +81 -0
- package/dist/auth/magic-link-session.d.ts.map +1 -0
- package/dist/auth/magic-link-session.js +183 -0
- package/dist/auth/magic-link-session.js.map +1 -0
- package/dist/auth/rate-limiter.d.ts +143 -0
- package/dist/auth/rate-limiter.d.ts.map +1 -0
- package/dist/auth/rate-limiter.js +220 -0
- package/dist/auth/rate-limiter.js.map +1 -0
- package/dist/auth/recovery-crypto.d.ts +34 -0
- package/dist/auth/recovery-crypto.d.ts.map +1 -0
- package/dist/auth/recovery-crypto.js +103 -0
- package/dist/auth/recovery-crypto.js.map +1 -0
- package/dist/auth/recovery-job-processor.d.ts +24 -0
- package/dist/auth/recovery-job-processor.d.ts.map +1 -0
- package/dist/auth/recovery-job-processor.js +123 -0
- package/dist/auth/recovery-job-processor.js.map +1 -0
- package/dist/auth/recovery-job-repository.d.ts +219 -0
- package/dist/auth/recovery-job-repository.d.ts.map +1 -0
- package/dist/auth/recovery-job-repository.js +340 -0
- package/dist/auth/recovery-job-repository.js.map +1 -0
- package/dist/auth/recovery-service.d.ts +27 -0
- package/dist/auth/recovery-service.d.ts.map +1 -0
- package/dist/auth/recovery-service.js +53 -0
- package/dist/auth/recovery-service.js.map +1 -0
- package/dist/auth/recovery-worker.d.ts +158 -0
- package/dist/auth/recovery-worker.d.ts.map +1 -0
- package/dist/auth/recovery-worker.js +306 -0
- package/dist/auth/recovery-worker.js.map +1 -0
- package/dist/auth/template-engine.d.ts +134 -0
- package/dist/auth/template-engine.d.ts.map +1 -0
- package/dist/auth/template-engine.js +225 -0
- package/dist/auth/template-engine.js.map +1 -0
- package/dist/auth/token-repository.d.ts +238 -0
- package/dist/auth/token-repository.d.ts.map +1 -0
- package/dist/auth/token-repository.js +475 -0
- package/dist/auth/token-repository.js.map +1 -0
- package/dist/auth/tokens.d.ts +45 -0
- package/dist/auth/tokens.d.ts.map +1 -0
- package/dist/auth/tokens.js +51 -0
- package/dist/auth/tokens.js.map +1 -0
- package/dist/cli/bootstrap.d.ts +55 -0
- package/dist/cli/bootstrap.d.ts.map +1 -0
- package/dist/cli/bootstrap.js +90 -0
- package/dist/cli/bootstrap.js.map +1 -0
- package/dist/cli/commands/health.d.ts +20 -0
- package/dist/cli/commands/health.d.ts.map +1 -0
- package/dist/cli/commands/health.js +80 -0
- package/dist/cli/commands/health.js.map +1 -0
- package/dist/cli/commands/init.d.ts +48 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +349 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/migrate.d.ts +19 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -0
- package/dist/cli/commands/migrate.js +88 -0
- package/dist/cli/commands/migrate.js.map +1 -0
- package/dist/cli/commands/seed.d.ts +19 -0
- package/dist/cli/commands/seed.d.ts.map +1 -0
- package/dist/cli/commands/seed.js +71 -0
- package/dist/cli/commands/seed.js.map +1 -0
- package/dist/cli/commands/user-2fa.d.ts +29 -0
- package/dist/cli/commands/user-2fa.d.ts.map +1 -0
- package/dist/cli/commands/user-2fa.js +113 -0
- package/dist/cli/commands/user-2fa.js.map +1 -0
- package/dist/cli/error-handler.d.ts +31 -0
- package/dist/cli/error-handler.d.ts.map +1 -0
- package/dist/cli/error-handler.js +65 -0
- package/dist/cli/error-handler.js.map +1 -0
- package/dist/cli/index.d.ts +48 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +99 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/output.d.ts +94 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +124 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/prompt.d.ts +48 -0
- package/dist/cli/prompt.d.ts.map +1 -0
- package/dist/cli/prompt.js +96 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/clients/cache.d.ts +63 -0
- package/dist/clients/cache.d.ts.map +1 -0
- package/dist/clients/cache.js +160 -0
- package/dist/clients/cache.js.map +1 -0
- package/dist/clients/crypto.d.ts +69 -0
- package/dist/clients/crypto.d.ts.map +1 -0
- package/dist/clients/crypto.js +83 -0
- package/dist/clients/crypto.js.map +1 -0
- package/dist/clients/errors.d.ts +27 -0
- package/dist/clients/errors.d.ts.map +1 -0
- package/dist/clients/errors.js +33 -0
- package/dist/clients/errors.js.map +1 -0
- package/dist/clients/index.d.ts +19 -0
- package/dist/clients/index.d.ts.map +1 -0
- package/dist/clients/index.js +23 -0
- package/dist/clients/index.js.map +1 -0
- package/dist/clients/repository.d.ts +161 -0
- package/dist/clients/repository.d.ts.map +1 -0
- package/dist/clients/repository.js +318 -0
- package/dist/clients/repository.js.map +1 -0
- package/dist/clients/resolve-login-methods.d.ts +74 -0
- package/dist/clients/resolve-login-methods.d.ts.map +1 -0
- package/dist/clients/resolve-login-methods.js +68 -0
- package/dist/clients/resolve-login-methods.js.map +1 -0
- package/dist/clients/secret-repository.d.ts +109 -0
- package/dist/clients/secret-repository.d.ts.map +1 -0
- package/dist/clients/secret-repository.js +166 -0
- package/dist/clients/secret-repository.js.map +1 -0
- package/dist/clients/secret-service.d.ts +87 -0
- package/dist/clients/secret-service.d.ts.map +1 -0
- package/dist/clients/secret-service.js +204 -0
- package/dist/clients/secret-service.js.map +1 -0
- package/dist/clients/service.d.ts +158 -0
- package/dist/clients/service.d.ts.map +1 -0
- package/dist/clients/service.js +523 -0
- package/dist/clients/service.js.map +1 -0
- package/dist/clients/types.d.ts +214 -0
- package/dist/clients/types.d.ts.map +1 -0
- package/dist/clients/types.js +77 -0
- package/dist/clients/types.js.map +1 -0
- package/dist/clients/validators.d.ts +87 -0
- package/dist/clients/validators.d.ts.map +1 -0
- package/dist/clients/validators.js +164 -0
- package/dist/clients/validators.js.map +1 -0
- package/dist/config/index.d.ts +23 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +52 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/schema.d.ts +35 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +167 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/custom-claims/cache.d.ts +48 -0
- package/dist/custom-claims/cache.d.ts.map +1 -0
- package/dist/custom-claims/cache.js +122 -0
- package/dist/custom-claims/cache.js.map +1 -0
- package/dist/custom-claims/errors.d.ts +25 -0
- package/dist/custom-claims/errors.d.ts.map +1 -0
- package/dist/custom-claims/errors.js +31 -0
- package/dist/custom-claims/errors.js.map +1 -0
- package/dist/custom-claims/index.d.ts +14 -0
- package/dist/custom-claims/index.d.ts.map +1 -0
- package/dist/custom-claims/index.js +17 -0
- package/dist/custom-claims/index.js.map +1 -0
- package/dist/custom-claims/repository.d.ts +147 -0
- package/dist/custom-claims/repository.d.ts.map +1 -0
- package/dist/custom-claims/repository.js +338 -0
- package/dist/custom-claims/repository.js.map +1 -0
- package/dist/custom-claims/service.d.ts +129 -0
- package/dist/custom-claims/service.d.ts.map +1 -0
- package/dist/custom-claims/service.js +296 -0
- package/dist/custom-claims/service.js.map +1 -0
- package/dist/custom-claims/types.d.ts +132 -0
- package/dist/custom-claims/types.d.ts.map +1 -0
- package/dist/custom-claims/types.js +61 -0
- package/dist/custom-claims/types.js.map +1 -0
- package/dist/custom-claims/validators.d.ts +61 -0
- package/dist/custom-claims/validators.d.ts.map +1 -0
- package/dist/custom-claims/validators.js +136 -0
- package/dist/custom-claims/validators.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/admin-permissions.d.ts +147 -0
- package/dist/lib/admin-permissions.d.ts.map +1 -0
- package/dist/lib/admin-permissions.js +261 -0
- package/dist/lib/admin-permissions.js.map +1 -0
- package/dist/lib/audit-log.d.ts +45 -0
- package/dist/lib/audit-log.d.ts.map +1 -0
- package/dist/lib/audit-log.js +79 -0
- package/dist/lib/audit-log.js.map +1 -0
- package/dist/lib/branding-assets.d.ts +47 -0
- package/dist/lib/branding-assets.d.ts.map +1 -0
- package/dist/lib/branding-assets.js +93 -0
- package/dist/lib/branding-assets.js.map +1 -0
- package/dist/lib/bulk-operations.d.ts +54 -0
- package/dist/lib/bulk-operations.d.ts.map +1 -0
- package/dist/lib/bulk-operations.js +201 -0
- package/dist/lib/bulk-operations.js.map +1 -0
- package/dist/lib/cursor.d.ts +110 -0
- package/dist/lib/cursor.d.ts.map +1 -0
- package/dist/lib/cursor.js +115 -0
- package/dist/lib/cursor.js.map +1 -0
- package/dist/lib/data-export.d.ts +67 -0
- package/dist/lib/data-export.d.ts.map +1 -0
- package/dist/lib/data-export.js +272 -0
- package/dist/lib/data-export.js.map +1 -0
- package/dist/lib/data-import-plan.d.ts +50 -0
- package/dist/lib/data-import-plan.d.ts.map +1 -0
- package/dist/lib/data-import-plan.js +235 -0
- package/dist/lib/data-import-plan.js.map +1 -0
- package/dist/lib/data-import.d.ts +276 -0
- package/dist/lib/data-import.d.ts.map +1 -0
- package/dist/lib/data-import.js +1694 -0
- package/dist/lib/data-import.js.map +1 -0
- package/dist/lib/database.d.ts +22 -0
- package/dist/lib/database.d.ts.map +1 -0
- package/dist/lib/database.js +103 -0
- package/dist/lib/database.js.map +1 -0
- package/dist/lib/entity-history.d.ts +52 -0
- package/dist/lib/entity-history.d.ts.map +1 -0
- package/dist/lib/entity-history.js +121 -0
- package/dist/lib/entity-history.js.map +1 -0
- package/dist/lib/etag.d.ts +92 -0
- package/dist/lib/etag.d.ts.map +1 -0
- package/dist/lib/etag.js +155 -0
- package/dist/lib/etag.js.map +1 -0
- package/dist/lib/image-validator.d.ts +44 -0
- package/dist/lib/image-validator.d.ts.map +1 -0
- package/dist/lib/image-validator.js +204 -0
- package/dist/lib/image-validator.js.map +1 -0
- package/dist/lib/logger.d.ts +15 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +84 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/migrator.d.ts +14 -0
- package/dist/lib/migrator.d.ts.map +1 -0
- package/dist/lib/migrator.js +34 -0
- package/dist/lib/migrator.js.map +1 -0
- package/dist/lib/redis.d.ts +5 -0
- package/dist/lib/redis.d.ts.map +1 -0
- package/dist/lib/redis.js +29 -0
- package/dist/lib/redis.js.map +1 -0
- package/dist/lib/runtime-paths.d.ts +38 -0
- package/dist/lib/runtime-paths.d.ts.map +1 -0
- package/dist/lib/runtime-paths.js +50 -0
- package/dist/lib/runtime-paths.js.map +1 -0
- package/dist/lib/session-tracking.d.ts +81 -0
- package/dist/lib/session-tracking.d.ts.map +1 -0
- package/dist/lib/session-tracking.js +145 -0
- package/dist/lib/session-tracking.js.map +1 -0
- package/dist/lib/signing-key-crypto.d.ts +53 -0
- package/dist/lib/signing-key-crypto.d.ts.map +1 -0
- package/dist/lib/signing-key-crypto.js +108 -0
- package/dist/lib/signing-key-crypto.js.map +1 -0
- package/dist/lib/signing-keys.d.ts +141 -0
- package/dist/lib/signing-keys.d.ts.map +1 -0
- package/dist/lib/signing-keys.js +206 -0
- package/dist/lib/signing-keys.js.map +1 -0
- package/dist/lib/stats.d.ts +83 -0
- package/dist/lib/stats.d.ts.map +1 -0
- package/dist/lib/stats.js +187 -0
- package/dist/lib/stats.js.map +1 -0
- package/dist/lib/super-admin-protection.d.ts +69 -0
- package/dist/lib/super-admin-protection.d.ts.map +1 -0
- package/dist/lib/super-admin-protection.js +102 -0
- package/dist/lib/super-admin-protection.js.map +1 -0
- package/dist/lib/system-config.d.ts +79 -0
- package/dist/lib/system-config.d.ts.map +1 -0
- package/dist/lib/system-config.js +159 -0
- package/dist/lib/system-config.js.map +1 -0
- package/dist/middleware/admin-auth.d.ts +100 -0
- package/dist/middleware/admin-auth.d.ts.map +1 -0
- package/dist/middleware/admin-auth.js +241 -0
- package/dist/middleware/admin-auth.js.map +1 -0
- package/dist/middleware/admin-cors.d.ts +41 -0
- package/dist/middleware/admin-cors.d.ts.map +1 -0
- package/dist/middleware/admin-cors.js +83 -0
- package/dist/middleware/admin-cors.js.map +1 -0
- package/dist/middleware/admin-mutation-audit.d.ts +9 -0
- package/dist/middleware/admin-mutation-audit.d.ts.map +1 -0
- package/dist/middleware/admin-mutation-audit.js +76 -0
- package/dist/middleware/admin-mutation-audit.js.map +1 -0
- package/dist/middleware/admin-rate-limiter.d.ts +56 -0
- package/dist/middleware/admin-rate-limiter.d.ts.map +1 -0
- package/dist/middleware/admin-rate-limiter.js +97 -0
- package/dist/middleware/admin-rate-limiter.js.map +1 -0
- package/dist/middleware/client-secret-hash.d.ts +34 -0
- package/dist/middleware/client-secret-hash.d.ts.map +1 -0
- package/dist/middleware/client-secret-hash.js +74 -0
- package/dist/middleware/client-secret-hash.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +3 -0
- package/dist/middleware/error-handler.d.ts.map +1 -0
- package/dist/middleware/error-handler.js +93 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/health.d.ts +3 -0
- package/dist/middleware/health.d.ts.map +1 -0
- package/dist/middleware/health.js +35 -0
- package/dist/middleware/health.js.map +1 -0
- package/dist/middleware/metrics.d.ts +40 -0
- package/dist/middleware/metrics.d.ts.map +1 -0
- package/dist/middleware/metrics.js +75 -0
- package/dist/middleware/metrics.js.map +1 -0
- package/dist/middleware/oidc-client-tenant.d.ts +37 -0
- package/dist/middleware/oidc-client-tenant.d.ts.map +1 -0
- package/dist/middleware/oidc-client-tenant.js +156 -0
- package/dist/middleware/oidc-client-tenant.js.map +1 -0
- package/dist/middleware/oidc-cors.d.ts +33 -0
- package/dist/middleware/oidc-cors.d.ts.map +1 -0
- package/dist/middleware/oidc-cors.js +68 -0
- package/dist/middleware/oidc-cors.js.map +1 -0
- package/dist/middleware/oidc-preflight-cors.d.ts +54 -0
- package/dist/middleware/oidc-preflight-cors.d.ts.map +1 -0
- package/dist/middleware/oidc-preflight-cors.js +267 -0
- package/dist/middleware/oidc-preflight-cors.js.map +1 -0
- package/dist/middleware/prompt-login-reset.d.ts +103 -0
- package/dist/middleware/prompt-login-reset.d.ts.map +1 -0
- package/dist/middleware/prompt-login-reset.js +204 -0
- package/dist/middleware/prompt-login-reset.js.map +1 -0
- package/dist/middleware/ready.d.ts +23 -0
- package/dist/middleware/ready.d.ts.map +1 -0
- package/dist/middleware/ready.js +60 -0
- package/dist/middleware/ready.js.map +1 -0
- package/dist/middleware/request-logger.d.ts +27 -0
- package/dist/middleware/request-logger.d.ts.map +1 -0
- package/dist/middleware/request-logger.js +46 -0
- package/dist/middleware/request-logger.js.map +1 -0
- package/dist/middleware/require-permission.d.ts +28 -0
- package/dist/middleware/require-permission.d.ts.map +1 -0
- package/dist/middleware/require-permission.js +63 -0
- package/dist/middleware/require-permission.js.map +1 -0
- package/dist/middleware/require-user-organization.d.ts +18 -0
- package/dist/middleware/require-user-organization.d.ts.map +1 -0
- package/dist/middleware/require-user-organization.js +53 -0
- package/dist/middleware/require-user-organization.js.map +1 -0
- package/dist/middleware/root-page.d.ts +62 -0
- package/dist/middleware/root-page.d.ts.map +1 -0
- package/dist/middleware/root-page.js +134 -0
- package/dist/middleware/root-page.js.map +1 -0
- package/dist/middleware/security-headers.d.ts +98 -0
- package/dist/middleware/security-headers.d.ts.map +1 -0
- package/dist/middleware/security-headers.js +159 -0
- package/dist/middleware/security-headers.js.map +1 -0
- package/dist/middleware/tenant-resolver.d.ts +37 -0
- package/dist/middleware/tenant-resolver.d.ts.map +1 -0
- package/dist/middleware/tenant-resolver.js +71 -0
- package/dist/middleware/tenant-resolver.js.map +1 -0
- package/dist/middleware/token-rate-limiter.d.ts +89 -0
- package/dist/middleware/token-rate-limiter.d.ts.map +1 -0
- package/dist/middleware/token-rate-limiter.js +189 -0
- package/dist/middleware/token-rate-limiter.js.map +1 -0
- package/dist/oidc/account-finder.d.ts +52 -0
- package/dist/oidc/account-finder.d.ts.map +1 -0
- package/dist/oidc/account-finder.js +134 -0
- package/dist/oidc/account-finder.js.map +1 -0
- package/dist/oidc/adapter-factory.d.ts +90 -0
- package/dist/oidc/adapter-factory.d.ts.map +1 -0
- package/dist/oidc/adapter-factory.js +165 -0
- package/dist/oidc/adapter-factory.js.map +1 -0
- package/dist/oidc/configuration.d.ts +155 -0
- package/dist/oidc/configuration.d.ts.map +1 -0
- package/dist/oidc/configuration.js +531 -0
- package/dist/oidc/configuration.js.map +1 -0
- package/dist/oidc/postgres-adapter.d.ts +159 -0
- package/dist/oidc/postgres-adapter.d.ts.map +1 -0
- package/dist/oidc/postgres-adapter.js +222 -0
- package/dist/oidc/postgres-adapter.js.map +1 -0
- package/dist/oidc/protocol-security-observer.d.ts +38 -0
- package/dist/oidc/protocol-security-observer.d.ts.map +1 -0
- package/dist/oidc/protocol-security-observer.js +93 -0
- package/dist/oidc/protocol-security-observer.js.map +1 -0
- package/dist/oidc/provider.d.ts +37 -0
- package/dist/oidc/provider.d.ts.map +1 -0
- package/dist/oidc/provider.js +71 -0
- package/dist/oidc/provider.js.map +1 -0
- package/dist/oidc/redis-adapter.d.ts +140 -0
- package/dist/oidc/redis-adapter.d.ts.map +1 -0
- package/dist/oidc/redis-adapter.js +344 -0
- package/dist/oidc/redis-adapter.js.map +1 -0
- package/dist/organizations/cache.d.ts +60 -0
- package/dist/organizations/cache.d.ts.map +1 -0
- package/dist/organizations/cache.js +157 -0
- package/dist/organizations/cache.js.map +1 -0
- package/dist/organizations/errors.d.ts +25 -0
- package/dist/organizations/errors.d.ts.map +1 -0
- package/dist/organizations/errors.js +31 -0
- package/dist/organizations/errors.js.map +1 -0
- package/dist/organizations/index.d.ts +15 -0
- package/dist/organizations/index.d.ts.map +1 -0
- package/dist/organizations/index.js +15 -0
- package/dist/organizations/index.js.map +1 -0
- package/dist/organizations/repository.d.ts +183 -0
- package/dist/organizations/repository.d.ts.map +1 -0
- package/dist/organizations/repository.js +354 -0
- package/dist/organizations/repository.js.map +1 -0
- package/dist/organizations/service.d.ts +168 -0
- package/dist/organizations/service.d.ts.map +1 -0
- package/dist/organizations/service.js +511 -0
- package/dist/organizations/service.js.map +1 -0
- package/dist/organizations/slugs.d.ts +57 -0
- package/dist/organizations/slugs.d.ts.map +1 -0
- package/dist/organizations/slugs.js +130 -0
- package/dist/organizations/slugs.js.map +1 -0
- package/dist/organizations/types.d.ts +146 -0
- package/dist/organizations/types.d.ts.map +1 -0
- package/dist/organizations/types.js +49 -0
- package/dist/organizations/types.js.map +1 -0
- package/dist/rbac/cache.d.ts +110 -0
- package/dist/rbac/cache.d.ts.map +1 -0
- package/dist/rbac/cache.js +271 -0
- package/dist/rbac/cache.js.map +1 -0
- package/dist/rbac/errors.d.ts +34 -0
- package/dist/rbac/errors.d.ts.map +1 -0
- package/dist/rbac/errors.js +43 -0
- package/dist/rbac/errors.js.map +1 -0
- package/dist/rbac/index.d.ts +17 -0
- package/dist/rbac/index.d.ts.map +1 -0
- package/dist/rbac/index.js +21 -0
- package/dist/rbac/index.js.map +1 -0
- package/dist/rbac/mapping-repository.d.ts +121 -0
- package/dist/rbac/mapping-repository.d.ts.map +1 -0
- package/dist/rbac/mapping-repository.js +224 -0
- package/dist/rbac/mapping-repository.js.map +1 -0
- package/dist/rbac/permission-repository.d.ts +100 -0
- package/dist/rbac/permission-repository.d.ts.map +1 -0
- package/dist/rbac/permission-repository.js +190 -0
- package/dist/rbac/permission-repository.js.map +1 -0
- package/dist/rbac/permission-service.d.ts +85 -0
- package/dist/rbac/permission-service.d.ts.map +1 -0
- package/dist/rbac/permission-service.js +179 -0
- package/dist/rbac/permission-service.js.map +1 -0
- package/dist/rbac/role-repository.d.ts +104 -0
- package/dist/rbac/role-repository.d.ts.map +1 -0
- package/dist/rbac/role-repository.js +202 -0
- package/dist/rbac/role-repository.js.map +1 -0
- package/dist/rbac/role-service.d.ts +111 -0
- package/dist/rbac/role-service.d.ts.map +1 -0
- package/dist/rbac/role-service.js +256 -0
- package/dist/rbac/role-service.js.map +1 -0
- package/dist/rbac/slugs.d.ts +116 -0
- package/dist/rbac/slugs.d.ts.map +1 -0
- package/dist/rbac/slugs.js +178 -0
- package/dist/rbac/slugs.js.map +1 -0
- package/dist/rbac/types.d.ts +187 -0
- package/dist/rbac/types.d.ts.map +1 -0
- package/dist/rbac/types.js +75 -0
- package/dist/rbac/types.js.map +1 -0
- package/dist/rbac/user-role-service.d.ts +101 -0
- package/dist/rbac/user-role-service.d.ts.map +1 -0
- package/dist/rbac/user-role-service.js +166 -0
- package/dist/rbac/user-role-service.js.map +1 -0
- package/dist/routes/applications.d.ts +40 -0
- package/dist/routes/applications.d.ts.map +1 -0
- package/dist/routes/applications.js +284 -0
- package/dist/routes/applications.js.map +1 -0
- package/dist/routes/audit.d.ts +31 -0
- package/dist/routes/audit.d.ts.map +1 -0
- package/dist/routes/audit.js +140 -0
- package/dist/routes/audit.js.map +1 -0
- package/dist/routes/branding.d.ts +17 -0
- package/dist/routes/branding.d.ts.map +1 -0
- package/dist/routes/branding.js +104 -0
- package/dist/routes/branding.js.map +1 -0
- package/dist/routes/bulk.d.ts +37 -0
- package/dist/routes/bulk.d.ts.map +1 -0
- package/dist/routes/bulk.js +94 -0
- package/dist/routes/bulk.js.map +1 -0
- package/dist/routes/clients.d.ts +44 -0
- package/dist/routes/clients.d.ts.map +1 -0
- package/dist/routes/clients.js +353 -0
- package/dist/routes/clients.js.map +1 -0
- package/dist/routes/config.d.ts +35 -0
- package/dist/routes/config.d.ts.map +1 -0
- package/dist/routes/config.js +115 -0
- package/dist/routes/config.js.map +1 -0
- package/dist/routes/custom-claims.d.ts +38 -0
- package/dist/routes/custom-claims.d.ts.map +1 -0
- package/dist/routes/custom-claims.js +208 -0
- package/dist/routes/custom-claims.js.map +1 -0
- package/dist/routes/exports.d.ts +21 -0
- package/dist/routes/exports.d.ts.map +1 -0
- package/dist/routes/exports.js +98 -0
- package/dist/routes/exports.js.map +1 -0
- package/dist/routes/imports.d.ts +18 -0
- package/dist/routes/imports.d.ts.map +1 -0
- package/dist/routes/imports.js +72 -0
- package/dist/routes/imports.js.map +1 -0
- package/dist/routes/interactions.d.ts +111 -0
- package/dist/routes/interactions.d.ts.map +1 -0
- package/dist/routes/interactions.js +1074 -0
- package/dist/routes/interactions.js.map +1 -0
- package/dist/routes/invitation.d.ts +31 -0
- package/dist/routes/invitation.d.ts.map +1 -0
- package/dist/routes/invitation.js +342 -0
- package/dist/routes/invitation.js.map +1 -0
- package/dist/routes/keys.d.ts +28 -0
- package/dist/routes/keys.d.ts.map +1 -0
- package/dist/routes/keys.js +91 -0
- package/dist/routes/keys.js.map +1 -0
- package/dist/routes/magic-link.d.ts +43 -0
- package/dist/routes/magic-link.d.ts.map +1 -0
- package/dist/routes/magic-link.js +264 -0
- package/dist/routes/magic-link.js.map +1 -0
- package/dist/routes/organizations.d.ts +38 -0
- package/dist/routes/organizations.d.ts.map +1 -0
- package/dist/routes/organizations.js +347 -0
- package/dist/routes/organizations.js.map +1 -0
- package/dist/routes/password-reset.d.ts +65 -0
- package/dist/routes/password-reset.d.ts.map +1 -0
- package/dist/routes/password-reset.js +493 -0
- package/dist/routes/password-reset.js.map +1 -0
- package/dist/routes/permissions.d.ts +33 -0
- package/dist/routes/permissions.d.ts.map +1 -0
- package/dist/routes/permissions.js +166 -0
- package/dist/routes/permissions.js.map +1 -0
- package/dist/routes/roles.d.ts +37 -0
- package/dist/routes/roles.d.ts.map +1 -0
- package/dist/routes/roles.js +222 -0
- package/dist/routes/roles.js.map +1 -0
- package/dist/routes/sessions.d.ts +37 -0
- package/dist/routes/sessions.d.ts.map +1 -0
- package/dist/routes/sessions.js +121 -0
- package/dist/routes/sessions.js.map +1 -0
- package/dist/routes/stats.d.ts +28 -0
- package/dist/routes/stats.d.ts.map +1 -0
- package/dist/routes/stats.js +65 -0
- package/dist/routes/stats.js.map +1 -0
- package/dist/routes/two-factor-admin.d.ts +54 -0
- package/dist/routes/two-factor-admin.d.ts.map +1 -0
- package/dist/routes/two-factor-admin.js +344 -0
- package/dist/routes/two-factor-admin.js.map +1 -0
- package/dist/routes/two-factor.d.ts +31 -0
- package/dist/routes/two-factor.d.ts.map +1 -0
- package/dist/routes/two-factor.js +595 -0
- package/dist/routes/two-factor.js.map +1 -0
- package/dist/routes/user-roles.d.ts +33 -0
- package/dist/routes/user-roles.d.ts.map +1 -0
- package/dist/routes/user-roles.js +129 -0
- package/dist/routes/user-roles.js.map +1 -0
- package/dist/routes/users.d.ts +61 -0
- package/dist/routes/users.d.ts.map +1 -0
- package/dist/routes/users.js +868 -0
- package/dist/routes/users.js.map +1 -0
- package/dist/security/decision-context.d.ts +52 -0
- package/dist/security/decision-context.d.ts.map +1 -0
- package/dist/security/decision-context.js +150 -0
- package/dist/security/decision-context.js.map +1 -0
- package/dist/security/decision-event.d.ts +128 -0
- package/dist/security/decision-event.d.ts.map +1 -0
- package/dist/security/decision-event.js +225 -0
- package/dist/security/decision-event.js.map +1 -0
- package/dist/security/transport-decision.d.ts +6 -0
- package/dist/security/transport-decision.d.ts.map +1 -0
- package/dist/security/transport-decision.js +37 -0
- package/dist/security/transport-decision.js.map +1 -0
- package/dist/server.d.ts +50 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +491 -0
- package/dist/server.js.map +1 -0
- package/dist/two-factor/cache.d.ts +47 -0
- package/dist/two-factor/cache.d.ts.map +1 -0
- package/dist/two-factor/cache.js +122 -0
- package/dist/two-factor/cache.js.map +1 -0
- package/dist/two-factor/crypto.d.ts +41 -0
- package/dist/two-factor/crypto.d.ts.map +1 -0
- package/dist/two-factor/crypto.js +94 -0
- package/dist/two-factor/crypto.js.map +1 -0
- package/dist/two-factor/errors.d.ts +82 -0
- package/dist/two-factor/errors.d.ts.map +1 -0
- package/dist/two-factor/errors.js +112 -0
- package/dist/two-factor/errors.js.map +1 -0
- package/dist/two-factor/index.d.ts +18 -0
- package/dist/two-factor/index.d.ts.map +1 -0
- package/dist/two-factor/index.js +25 -0
- package/dist/two-factor/index.js.map +1 -0
- package/dist/two-factor/otp.d.ts +43 -0
- package/dist/two-factor/otp.d.ts.map +1 -0
- package/dist/two-factor/otp.js +57 -0
- package/dist/two-factor/otp.js.map +1 -0
- package/dist/two-factor/recovery.d.ts +45 -0
- package/dist/two-factor/recovery.d.ts.map +1 -0
- package/dist/two-factor/recovery.js +104 -0
- package/dist/two-factor/recovery.js.map +1 -0
- package/dist/two-factor/repository.d.ts +156 -0
- package/dist/two-factor/repository.d.ts.map +1 -0
- package/dist/two-factor/repository.js +251 -0
- package/dist/two-factor/repository.js.map +1 -0
- package/dist/two-factor/service.d.ts +232 -0
- package/dist/two-factor/service.d.ts.map +1 -0
- package/dist/two-factor/service.js +599 -0
- package/dist/two-factor/service.js.map +1 -0
- package/dist/two-factor/totp.d.ts +57 -0
- package/dist/two-factor/totp.d.ts.map +1 -0
- package/dist/two-factor/totp.js +96 -0
- package/dist/two-factor/totp.js.map +1 -0
- package/dist/two-factor/types.d.ts +152 -0
- package/dist/two-factor/types.d.ts.map +1 -0
- package/dist/two-factor/types.js +64 -0
- package/dist/two-factor/types.js.map +1 -0
- package/dist/users/cache.d.ts +49 -0
- package/dist/users/cache.d.ts.map +1 -0
- package/dist/users/cache.js +140 -0
- package/dist/users/cache.js.map +1 -0
- package/dist/users/claims.d.ts +67 -0
- package/dist/users/claims.d.ts.map +1 -0
- package/dist/users/claims.js +104 -0
- package/dist/users/claims.js.map +1 -0
- package/dist/users/errors.d.ts +25 -0
- package/dist/users/errors.d.ts.map +1 -0
- package/dist/users/errors.js +31 -0
- package/dist/users/errors.js.map +1 -0
- package/dist/users/gdpr.d.ts +110 -0
- package/dist/users/gdpr.d.ts.map +1 -0
- package/dist/users/gdpr.js +211 -0
- package/dist/users/gdpr.js.map +1 -0
- package/dist/users/index.d.ts +20 -0
- package/dist/users/index.d.ts.map +1 -0
- package/dist/users/index.js +19 -0
- package/dist/users/index.js.map +1 -0
- package/dist/users/password.d.ts +85 -0
- package/dist/users/password.d.ts.map +1 -0
- package/dist/users/password.js +138 -0
- package/dist/users/password.js.map +1 -0
- package/dist/users/repository.d.ts +263 -0
- package/dist/users/repository.d.ts.map +1 -0
- package/dist/users/repository.js +499 -0
- package/dist/users/repository.js.map +1 -0
- package/dist/users/service.d.ts +299 -0
- package/dist/users/service.d.ts.map +1 -0
- package/dist/users/service.js +698 -0
- package/dist/users/service.js.map +1 -0
- package/dist/users/types.d.ts +220 -0
- package/dist/users/types.d.ts.map +1 -0
- package/dist/users/types.js +77 -0
- package/dist/users/types.js.map +1 -0
- package/locales/default/en/common.json +10 -0
- package/locales/default/en/consent.json +13 -0
- package/locales/default/en/emails.json +17 -0
- package/locales/default/en/errors.json +21 -0
- package/locales/default/en/forgot-password.json +11 -0
- package/locales/default/en/invitation.json +18 -0
- package/locales/default/en/login.json +17 -0
- package/locales/default/en/logout.json +9 -0
- package/locales/default/en/magic-link.json +12 -0
- package/locales/default/en/reset-password.json +16 -0
- package/locales/default/en/two-factor.json +29 -0
- package/migrations/.gitkeep +0 -0
- package/migrations/001_extensions.sql +22 -0
- package/migrations/002_organizations.sql +43 -0
- package/migrations/003_applications.sql +50 -0
- package/migrations/004_clients.sql +74 -0
- package/migrations/005_users.sql +119 -0
- package/migrations/006_roles_permissions.sql +80 -0
- package/migrations/007_custom_claims.sql +55 -0
- package/migrations/008_config.sql +51 -0
- package/migrations/009_audit_log.sql +31 -0
- package/migrations/010_oidc_adapter.sql +34 -0
- package/migrations/011_seed.sql +53 -0
- package/migrations/012_two_factor.sql +88 -0
- package/migrations/013_client_secret_sha256.sql +22 -0
- package/migrations/014_login_methods.sql +34 -0
- package/migrations/015_signing_key_encryption.sql +20 -0
- package/migrations/016_failed_login_count.sql +27 -0
- package/migrations/017_audit_retention.sql +11 -0
- package/migrations/018_admin_api_enhancements.sql +78 -0
- package/migrations/019_invitation_details.sql +27 -0
- package/migrations/020_two_factor_admin_permission.sql +108 -0
- package/migrations/021_auth_recovery_jobs.sql +74 -0
- package/migrations/022_recovery_artifact_ownership.sql +25 -0
- package/migrations/023_magic_link_authority.sql +39 -0
- package/package.json +106 -0
- package/templates/default/emails/invitation.hbs +39 -0
- package/templates/default/emails/invitation.txt.hbs +18 -0
- package/templates/default/emails/magic-link.hbs +30 -0
- package/templates/default/emails/magic-link.txt.hbs +11 -0
- package/templates/default/emails/otp-code.hbs +31 -0
- package/templates/default/emails/otp-code.txt.hbs +15 -0
- package/templates/default/emails/password-changed.hbs +24 -0
- package/templates/default/emails/password-changed.txt.hbs +7 -0
- package/templates/default/emails/password-reset.hbs +30 -0
- package/templates/default/emails/password-reset.txt.hbs +11 -0
- package/templates/default/emails/welcome.hbs +25 -0
- package/templates/default/emails/welcome.txt.hbs +9 -0
- package/templates/default/layouts/main.hbs +49 -0
- package/templates/default/pages/accept-invite.hbs +25 -0
- package/templates/default/pages/consent.hbs +27 -0
- package/templates/default/pages/error.hbs +15 -0
- package/templates/default/pages/forgot-password.hbs +21 -0
- package/templates/default/pages/invite-expired.hbs +6 -0
- package/templates/default/pages/invite-success.hbs +9 -0
- package/templates/default/pages/login.hbs +108 -0
- package/templates/default/pages/logout-success.hbs +5 -0
- package/templates/default/pages/logout.hbs +24 -0
- package/templates/default/pages/magic-link-sent.hbs +10 -0
- package/templates/default/pages/magic-link-success.hbs +17 -0
- package/templates/default/pages/reset-password.hbs +20 -0
- package/templates/default/pages/reset-success.hbs +9 -0
- package/templates/default/pages/two-factor-setup.hbs +65 -0
- package/templates/default/pages/two-factor-verify.hbs +77 -0
- package/templates/default/partials/flash-messages.hbs +10 -0
- package/templates/default/partials/footer.hbs +4 -0
- package/templates/default/partials/header.hbs +8 -0
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application repository — PostgreSQL data access layer.
|
|
3
|
+
*
|
|
4
|
+
* Provides CRUD operations for the `applications` and `application_modules`
|
|
5
|
+
* tables using parameterized queries. Each function acquires the pool via
|
|
6
|
+
* `getPool()` and returns mapped Application/ApplicationModule objects.
|
|
7
|
+
*
|
|
8
|
+
* This module is the sole interface to the database for application
|
|
9
|
+
* data. The service layer composes repository + cache + validation.
|
|
10
|
+
*
|
|
11
|
+
* Key patterns:
|
|
12
|
+
* - Dynamic UPDATE query builder for partial updates
|
|
13
|
+
* - Paginated listing with optional status/search filters
|
|
14
|
+
* - Whitelisted sort columns to prevent SQL injection
|
|
15
|
+
* - All rows mapped through `mapRowToApplication()` / `mapRowToModule()`
|
|
16
|
+
* - Module slug uniqueness scoped to parent application (composite key)
|
|
17
|
+
*/
|
|
18
|
+
import { getPool } from '../lib/database.js';
|
|
19
|
+
import { mapRowToApplication, mapRowToModule } from './types.js';
|
|
20
|
+
import { decodeCursor, buildCursorResult } from '../lib/cursor.js';
|
|
21
|
+
/**
|
|
22
|
+
* Insert a new application into the database.
|
|
23
|
+
*
|
|
24
|
+
* Uses RETURNING * to get the full row back in a single round trip.
|
|
25
|
+
* The slug must be unique (enforced by the DB unique constraint).
|
|
26
|
+
*
|
|
27
|
+
* @param data - Application data to insert
|
|
28
|
+
* @returns The newly created application
|
|
29
|
+
* @throws If slug already exists (unique constraint violation)
|
|
30
|
+
*/
|
|
31
|
+
export async function insertApplication(data) {
|
|
32
|
+
const pool = getPool();
|
|
33
|
+
const result = await pool.query(`INSERT INTO applications (name, slug, description)
|
|
34
|
+
VALUES ($1, $2, $3)
|
|
35
|
+
RETURNING *`, [data.name, data.slug, data.description ?? null]);
|
|
36
|
+
return mapRowToApplication(result.rows[0]);
|
|
37
|
+
}
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// Find
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
/**
|
|
42
|
+
* Find an application by its UUID.
|
|
43
|
+
*
|
|
44
|
+
* @param id - Application UUID
|
|
45
|
+
* @returns Application or null if not found
|
|
46
|
+
*/
|
|
47
|
+
export async function findApplicationById(id) {
|
|
48
|
+
const pool = getPool();
|
|
49
|
+
const result = await pool.query('SELECT * FROM applications WHERE id = $1', [id]);
|
|
50
|
+
if (result.rows.length === 0)
|
|
51
|
+
return null;
|
|
52
|
+
return mapRowToApplication(result.rows[0]);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Find an application by its slug.
|
|
56
|
+
*
|
|
57
|
+
* Returns applications of any status (active, inactive, archived).
|
|
58
|
+
* The caller (service layer) is responsible for status-based access control.
|
|
59
|
+
*
|
|
60
|
+
* @param slug - Application slug
|
|
61
|
+
* @returns Application or null if not found
|
|
62
|
+
*/
|
|
63
|
+
export async function findApplicationBySlug(slug) {
|
|
64
|
+
const pool = getPool();
|
|
65
|
+
const result = await pool.query('SELECT * FROM applications WHERE slug = $1', [slug]);
|
|
66
|
+
if (result.rows.length === 0)
|
|
67
|
+
return null;
|
|
68
|
+
return mapRowToApplication(result.rows[0]);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Mapping from UpdateApplicationData keys to database column names.
|
|
72
|
+
* Used by the dynamic query builder to construct SET clauses.
|
|
73
|
+
*/
|
|
74
|
+
const APP_FIELD_TO_COLUMN = {
|
|
75
|
+
name: 'name',
|
|
76
|
+
status: 'status',
|
|
77
|
+
description: 'description',
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Update an application's fields using a dynamic SET clause.
|
|
81
|
+
*
|
|
82
|
+
* Only explicitly provided fields (not undefined) are included in the
|
|
83
|
+
* UPDATE statement. This allows partial updates without overwriting
|
|
84
|
+
* fields that weren't specified.
|
|
85
|
+
*
|
|
86
|
+
* The `updated_at` column is handled automatically by the DB trigger.
|
|
87
|
+
*
|
|
88
|
+
* @param id - Application UUID
|
|
89
|
+
* @param data - Fields to update (only non-undefined fields are applied)
|
|
90
|
+
* @returns Updated application
|
|
91
|
+
* @throws Error if application not found or no fields provided
|
|
92
|
+
*/
|
|
93
|
+
export async function updateApplication(id, data) {
|
|
94
|
+
const pool = getPool();
|
|
95
|
+
// Build dynamic SET clause from provided fields
|
|
96
|
+
const setClauses = [];
|
|
97
|
+
const values = [id]; // $1 is always the ID
|
|
98
|
+
let paramIndex = 2;
|
|
99
|
+
for (const [field, column] of Object.entries(APP_FIELD_TO_COLUMN)) {
|
|
100
|
+
const value = data[field];
|
|
101
|
+
// Include the field if it's explicitly set (including null for clearing)
|
|
102
|
+
if (value !== undefined) {
|
|
103
|
+
setClauses.push(`${column} = $${paramIndex}`);
|
|
104
|
+
values.push(value);
|
|
105
|
+
paramIndex++;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (setClauses.length === 0) {
|
|
109
|
+
throw new Error('No fields to update');
|
|
110
|
+
}
|
|
111
|
+
const sql = `UPDATE applications SET ${setClauses.join(', ')} WHERE id = $1 RETURNING *`;
|
|
112
|
+
const result = await pool.query(sql, values);
|
|
113
|
+
if (result.rows.length === 0) {
|
|
114
|
+
throw new Error('Application not found');
|
|
115
|
+
}
|
|
116
|
+
return mapRowToApplication(result.rows[0]);
|
|
117
|
+
}
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
// List
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
/**
|
|
122
|
+
* Allowed sort columns — whitelisted to prevent SQL injection.
|
|
123
|
+
* These are interpolated directly into the SQL ORDER BY clause.
|
|
124
|
+
*/
|
|
125
|
+
const ALLOWED_SORT_COLUMNS = {
|
|
126
|
+
name: 'name',
|
|
127
|
+
created_at: 'created_at',
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* List applications with pagination, optional status filter, search, and sorting.
|
|
131
|
+
*
|
|
132
|
+
* Executes two queries:
|
|
133
|
+
* 1. COUNT query for total matching rows
|
|
134
|
+
* 2. Data query with LIMIT/OFFSET for the current page
|
|
135
|
+
*
|
|
136
|
+
* Sort column and direction are whitelisted (not parameterized) since
|
|
137
|
+
* they're SQL identifiers/keywords, not user data values.
|
|
138
|
+
*
|
|
139
|
+
* @param options - Pagination, filter, and sort options
|
|
140
|
+
* @returns Paginated result with applications and metadata
|
|
141
|
+
*/
|
|
142
|
+
export async function listApplications(options) {
|
|
143
|
+
const pool = getPool();
|
|
144
|
+
const { page, pageSize, status, search, sortBy, sortOrder } = options;
|
|
145
|
+
// Build WHERE conditions
|
|
146
|
+
const conditions = [];
|
|
147
|
+
const params = [];
|
|
148
|
+
let paramIndex = 1;
|
|
149
|
+
if (status) {
|
|
150
|
+
conditions.push(`status = $${paramIndex}`);
|
|
151
|
+
params.push(status);
|
|
152
|
+
paramIndex++;
|
|
153
|
+
}
|
|
154
|
+
if (search) {
|
|
155
|
+
// Search by name or slug using case-insensitive LIKE
|
|
156
|
+
conditions.push(`(name ILIKE $${paramIndex} OR slug ILIKE $${paramIndex})`);
|
|
157
|
+
params.push(`%${search}%`);
|
|
158
|
+
paramIndex++;
|
|
159
|
+
}
|
|
160
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
161
|
+
// Whitelist sort column and direction to prevent SQL injection
|
|
162
|
+
const sortColumn = ALLOWED_SORT_COLUMNS[sortBy ?? 'created_at'] ?? 'created_at';
|
|
163
|
+
const direction = sortOrder === 'asc' ? 'ASC' : 'DESC';
|
|
164
|
+
// Count total matching rows
|
|
165
|
+
const countResult = await pool.query(`SELECT COUNT(*) as count FROM applications ${whereClause}`, params);
|
|
166
|
+
const total = parseInt(countResult.rows[0].count, 10);
|
|
167
|
+
// Fetch paginated data
|
|
168
|
+
const offset = (page - 1) * pageSize;
|
|
169
|
+
const dataResult = await pool.query(`SELECT * FROM applications ${whereClause} ORDER BY ${sortColumn} ${direction} LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [...params, pageSize, offset]);
|
|
170
|
+
return {
|
|
171
|
+
data: dataResult.rows.map(mapRowToApplication),
|
|
172
|
+
total,
|
|
173
|
+
page,
|
|
174
|
+
pageSize,
|
|
175
|
+
totalPages: Math.ceil(total / pageSize),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* List applications with cursor-based keyset pagination.
|
|
180
|
+
*
|
|
181
|
+
* Uses `(sort_column, id) > (cursor_sort, cursor_id)` for efficient
|
|
182
|
+
* paging without COUNT queries. Queries limit+1 rows to detect hasMore.
|
|
183
|
+
*
|
|
184
|
+
* @param options - Cursor pagination, filter, and sort options
|
|
185
|
+
* @returns Cursor-paginated result with applications
|
|
186
|
+
*/
|
|
187
|
+
export async function listApplicationsCursor(options) {
|
|
188
|
+
const pool = getPool();
|
|
189
|
+
const limit = Math.min(Math.max(1, options.limit ?? 25), 100);
|
|
190
|
+
const sortColumn = ALLOWED_SORT_COLUMNS[options.sortBy ?? 'created_at'] ?? 'created_at';
|
|
191
|
+
const direction = options.sortOrder === 'asc' ? 'ASC' : 'DESC';
|
|
192
|
+
const comparator = direction === 'ASC' ? '>' : '<';
|
|
193
|
+
const conditions = [];
|
|
194
|
+
const params = [];
|
|
195
|
+
let paramIndex = 1;
|
|
196
|
+
if (options.cursor) {
|
|
197
|
+
const decoded = decodeCursor(options.cursor);
|
|
198
|
+
if (decoded) {
|
|
199
|
+
if (decoded.s === null) {
|
|
200
|
+
conditions.push(`(${sortColumn} IS NOT NULL OR (${sortColumn} IS NULL AND id ${comparator} $${paramIndex}))`);
|
|
201
|
+
params.push(decoded.i);
|
|
202
|
+
paramIndex++;
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
conditions.push(`(${sortColumn}, id) ${comparator} ($${paramIndex}, $${paramIndex + 1})`);
|
|
206
|
+
params.push(decoded.s, decoded.i);
|
|
207
|
+
paramIndex += 2;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (options.status) {
|
|
212
|
+
conditions.push(`status = $${paramIndex}`);
|
|
213
|
+
params.push(options.status);
|
|
214
|
+
paramIndex++;
|
|
215
|
+
}
|
|
216
|
+
if (options.search) {
|
|
217
|
+
conditions.push(`(name ILIKE $${paramIndex} OR slug ILIKE $${paramIndex})`);
|
|
218
|
+
params.push(`%${options.search}%`);
|
|
219
|
+
paramIndex++;
|
|
220
|
+
}
|
|
221
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
222
|
+
const sql = `SELECT * FROM applications ${whereClause} ORDER BY ${sortColumn} ${direction}, id ${direction} LIMIT $${paramIndex}`;
|
|
223
|
+
params.push(limit + 1);
|
|
224
|
+
const result = await pool.query(sql, params);
|
|
225
|
+
const rows = result.rows.map(mapRowToApplication);
|
|
226
|
+
return buildCursorResult(rows, limit, (app) => sortColumn === 'name' ? app.name : app.createdAt.toISOString(), (app) => app.id);
|
|
227
|
+
}
|
|
228
|
+
// ---------------------------------------------------------------------------
|
|
229
|
+
// Slug existence check
|
|
230
|
+
// ---------------------------------------------------------------------------
|
|
231
|
+
/**
|
|
232
|
+
* Check if an application slug is already taken in the database.
|
|
233
|
+
*
|
|
234
|
+
* Checks across all statuses (active, inactive, archived) because
|
|
235
|
+
* slugs must be globally unique regardless of application status.
|
|
236
|
+
*
|
|
237
|
+
* @param slug - Slug to check
|
|
238
|
+
* @param excludeId - Optional app ID to exclude (useful for updates)
|
|
239
|
+
* @returns true if the slug already exists
|
|
240
|
+
*/
|
|
241
|
+
export async function slugExists(slug, excludeId) {
|
|
242
|
+
const pool = getPool();
|
|
243
|
+
if (excludeId) {
|
|
244
|
+
const result = await pool.query('SELECT EXISTS(SELECT 1 FROM applications WHERE slug = $1 AND id != $2) as exists', [slug, excludeId]);
|
|
245
|
+
return result.rows[0].exists;
|
|
246
|
+
}
|
|
247
|
+
const result = await pool.query('SELECT EXISTS(SELECT 1 FROM applications WHERE slug = $1) as exists', [slug]);
|
|
248
|
+
return result.rows[0].exists;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Insert a new module into the database for a given application.
|
|
252
|
+
*
|
|
253
|
+
* Module slugs are unique within their parent application
|
|
254
|
+
* (enforced by the composite UNIQUE constraint on application_id + slug).
|
|
255
|
+
*
|
|
256
|
+
* @param data - Module data to insert
|
|
257
|
+
* @returns The newly created module
|
|
258
|
+
* @throws If composite slug already exists (unique constraint violation)
|
|
259
|
+
*/
|
|
260
|
+
export async function insertModule(data) {
|
|
261
|
+
const pool = getPool();
|
|
262
|
+
const result = await pool.query(`INSERT INTO application_modules (application_id, name, slug, description)
|
|
263
|
+
VALUES ($1, $2, $3, $4)
|
|
264
|
+
RETURNING *`, [data.applicationId, data.name, data.slug, data.description ?? null]);
|
|
265
|
+
return mapRowToModule(result.rows[0]);
|
|
266
|
+
}
|
|
267
|
+
// ---------------------------------------------------------------------------
|
|
268
|
+
// Find Module
|
|
269
|
+
// ---------------------------------------------------------------------------
|
|
270
|
+
/**
|
|
271
|
+
* Find a module by its UUID.
|
|
272
|
+
*
|
|
273
|
+
* @param id - Module UUID
|
|
274
|
+
* @returns ApplicationModule or null if not found
|
|
275
|
+
*/
|
|
276
|
+
export async function findModuleById(id) {
|
|
277
|
+
const pool = getPool();
|
|
278
|
+
const result = await pool.query('SELECT * FROM application_modules WHERE id = $1', [id]);
|
|
279
|
+
if (result.rows.length === 0)
|
|
280
|
+
return null;
|
|
281
|
+
return mapRowToModule(result.rows[0]);
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Mapping from UpdateModuleData keys to database column names.
|
|
285
|
+
* Used by the dynamic query builder to construct SET clauses.
|
|
286
|
+
*/
|
|
287
|
+
const MODULE_FIELD_TO_COLUMN = {
|
|
288
|
+
name: 'name',
|
|
289
|
+
status: 'status',
|
|
290
|
+
description: 'description',
|
|
291
|
+
};
|
|
292
|
+
/**
|
|
293
|
+
* Update a module's fields using a dynamic SET clause.
|
|
294
|
+
*
|
|
295
|
+
* Only explicitly provided fields (not undefined) are included in the
|
|
296
|
+
* UPDATE statement. The `updated_at` column is handled by the DB trigger.
|
|
297
|
+
*
|
|
298
|
+
* @param id - Module UUID
|
|
299
|
+
* @param data - Fields to update (only non-undefined fields are applied)
|
|
300
|
+
* @returns Updated module
|
|
301
|
+
* @throws Error if module not found or no fields provided
|
|
302
|
+
*/
|
|
303
|
+
export async function updateModule(id, data) {
|
|
304
|
+
const pool = getPool();
|
|
305
|
+
// Build dynamic SET clause from provided fields
|
|
306
|
+
const setClauses = [];
|
|
307
|
+
const values = [id]; // $1 is always the ID
|
|
308
|
+
let paramIndex = 2;
|
|
309
|
+
for (const [field, column] of Object.entries(MODULE_FIELD_TO_COLUMN)) {
|
|
310
|
+
const value = data[field];
|
|
311
|
+
if (value !== undefined) {
|
|
312
|
+
setClauses.push(`${column} = $${paramIndex}`);
|
|
313
|
+
values.push(value);
|
|
314
|
+
paramIndex++;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
if (setClauses.length === 0) {
|
|
318
|
+
throw new Error('No fields to update');
|
|
319
|
+
}
|
|
320
|
+
const sql = `UPDATE application_modules SET ${setClauses.join(', ')} WHERE id = $1 RETURNING *`;
|
|
321
|
+
const result = await pool.query(sql, values);
|
|
322
|
+
if (result.rows.length === 0) {
|
|
323
|
+
throw new Error('Module not found');
|
|
324
|
+
}
|
|
325
|
+
return mapRowToModule(result.rows[0]);
|
|
326
|
+
}
|
|
327
|
+
// ---------------------------------------------------------------------------
|
|
328
|
+
// List Modules
|
|
329
|
+
// ---------------------------------------------------------------------------
|
|
330
|
+
/**
|
|
331
|
+
* List all modules for a given application.
|
|
332
|
+
*
|
|
333
|
+
* Returns all modules regardless of status, ordered by name ascending.
|
|
334
|
+
* No pagination — modules per application are expected to be small in number.
|
|
335
|
+
*
|
|
336
|
+
* @param applicationId - Application UUID
|
|
337
|
+
* @returns Array of modules for the application
|
|
338
|
+
*/
|
|
339
|
+
export async function listModules(applicationId) {
|
|
340
|
+
const pool = getPool();
|
|
341
|
+
const result = await pool.query('SELECT * FROM application_modules WHERE application_id = $1 ORDER BY name ASC', [applicationId]);
|
|
342
|
+
return result.rows.map(mapRowToModule);
|
|
343
|
+
}
|
|
344
|
+
// ---------------------------------------------------------------------------
|
|
345
|
+
// Module slug existence check
|
|
346
|
+
// ---------------------------------------------------------------------------
|
|
347
|
+
/**
|
|
348
|
+
* Check if a module slug is already taken within a given application.
|
|
349
|
+
*
|
|
350
|
+
* Module slugs are unique within their parent application (composite key).
|
|
351
|
+
* This check looks at all statuses (active, inactive).
|
|
352
|
+
*
|
|
353
|
+
* @param applicationId - Application UUID
|
|
354
|
+
* @param slug - Module slug to check
|
|
355
|
+
* @param excludeId - Optional module ID to exclude (useful for updates)
|
|
356
|
+
* @returns true if the slug already exists within the application
|
|
357
|
+
*/
|
|
358
|
+
export async function moduleSlugExists(applicationId, slug, excludeId) {
|
|
359
|
+
const pool = getPool();
|
|
360
|
+
if (excludeId) {
|
|
361
|
+
const result = await pool.query('SELECT EXISTS(SELECT 1 FROM application_modules WHERE application_id = $1 AND slug = $2 AND id != $3) as exists', [applicationId, slug, excludeId]);
|
|
362
|
+
return result.rows[0].exists;
|
|
363
|
+
}
|
|
364
|
+
const result = await pool.query('SELECT EXISTS(SELECT 1 FROM application_modules WHERE application_id = $1 AND slug = $2) as exists', [applicationId, slug]);
|
|
365
|
+
return result.rows[0].exists;
|
|
366
|
+
}
|
|
367
|
+
//# sourceMappingURL=repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/applications/repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application service — business logic orchestrator.
|
|
3
|
+
*
|
|
4
|
+
* Composes the repository, cache, slug utilities, and audit log
|
|
5
|
+
* to provide the complete application management API. All write
|
|
6
|
+
* operations follow the pattern:
|
|
7
|
+
* 1. Validate inputs
|
|
8
|
+
* 2. Perform DB operation (via repository)
|
|
9
|
+
* 3. Invalidate + re-cache (via cache)
|
|
10
|
+
* 4. Write audit log (fire-and-forget)
|
|
11
|
+
*
|
|
12
|
+
* Read operations check cache first, fall back to DB on miss.
|
|
13
|
+
*
|
|
14
|
+
* Status lifecycle rules (different from organizations):
|
|
15
|
+
* - deactivate: active → inactive
|
|
16
|
+
* - activate: inactive → active
|
|
17
|
+
* - archive: active|inactive → archived (permanent, cannot be restored)
|
|
18
|
+
*
|
|
19
|
+
* Module management:
|
|
20
|
+
* - Modules belong to an application (parent must exist)
|
|
21
|
+
* - Module slugs are unique within their parent application
|
|
22
|
+
* - Module deactivation sets status to inactive
|
|
23
|
+
*/
|
|
24
|
+
import type { Application, ApplicationModule, CreateApplicationInput, UpdateApplicationInput, CreateModuleInput, UpdateModuleInput, ListApplicationsOptions, PaginatedResult } from './types.js';
|
|
25
|
+
import type { ListApplicationsCursorOptions } from './repository.js';
|
|
26
|
+
import type { CursorPaginatedResult } from '../lib/cursor.js';
|
|
27
|
+
/**
|
|
28
|
+
* Create a new application.
|
|
29
|
+
*
|
|
30
|
+
* 1. Generate slug from name if not provided
|
|
31
|
+
* 2. Validate slug format and reserved words
|
|
32
|
+
* 3. Check slug uniqueness in the database
|
|
33
|
+
* 4. Insert application via repository
|
|
34
|
+
* 5. Cache the new application
|
|
35
|
+
* 6. Write audit log entry
|
|
36
|
+
*
|
|
37
|
+
* @param input - Application creation data
|
|
38
|
+
* @param actorId - UUID of the user performing the action (for audit)
|
|
39
|
+
* @returns Created application
|
|
40
|
+
* @throws ApplicationValidationError if slug is invalid or already taken
|
|
41
|
+
*/
|
|
42
|
+
export declare function createApplication(input: CreateApplicationInput, actorId?: string): Promise<Application>;
|
|
43
|
+
/**
|
|
44
|
+
* Find an application by ID.
|
|
45
|
+
* Checks Redis cache first, falls back to database on miss.
|
|
46
|
+
*
|
|
47
|
+
* @param id - Application UUID
|
|
48
|
+
* @returns Application or null if not found
|
|
49
|
+
*/
|
|
50
|
+
export declare function getApplicationById(id: string): Promise<Application | null>;
|
|
51
|
+
/**
|
|
52
|
+
* Find an application by slug.
|
|
53
|
+
* Checks Redis cache first, falls back to database on miss.
|
|
54
|
+
*
|
|
55
|
+
* @param slug - Application slug
|
|
56
|
+
* @returns Application or null if not found
|
|
57
|
+
*/
|
|
58
|
+
export declare function getApplicationBySlug(slug: string): Promise<Application | null>;
|
|
59
|
+
/**
|
|
60
|
+
* Update an application's basic fields (name, description).
|
|
61
|
+
*
|
|
62
|
+
* @param id - Application UUID
|
|
63
|
+
* @param input - Fields to update
|
|
64
|
+
* @param actorId - UUID of the user performing the action
|
|
65
|
+
* @returns Updated application
|
|
66
|
+
* @throws ApplicationNotFoundError if application not found
|
|
67
|
+
*/
|
|
68
|
+
export declare function updateApplication(id: string, input: UpdateApplicationInput, actorId?: string): Promise<Application>;
|
|
69
|
+
/**
|
|
70
|
+
* List applications with pagination and filtering.
|
|
71
|
+
* Delegates directly to the repository.
|
|
72
|
+
*
|
|
73
|
+
* @param options - Pagination, filter, and sort options
|
|
74
|
+
* @returns Paginated result
|
|
75
|
+
*/
|
|
76
|
+
export declare function listApplications(options: ListApplicationsOptions): Promise<PaginatedResult<Application>>;
|
|
77
|
+
/**
|
|
78
|
+
* List applications with cursor-based keyset pagination.
|
|
79
|
+
* Provides stable, efficient pagination without COUNT queries.
|
|
80
|
+
*
|
|
81
|
+
* @param options - Cursor, limit, filter, and sort options
|
|
82
|
+
* @returns Cursor-paginated result with nextCursor/hasMore
|
|
83
|
+
*/
|
|
84
|
+
export declare function listApplicationsCursor(options: ListApplicationsCursorOptions): Promise<CursorPaginatedResult<Application>>;
|
|
85
|
+
/**
|
|
86
|
+
* Deactivate an application (active → inactive).
|
|
87
|
+
*
|
|
88
|
+
* @param id - Application UUID
|
|
89
|
+
* @param actorId - UUID of the user performing the action
|
|
90
|
+
* @throws ApplicationNotFoundError if not found
|
|
91
|
+
* @throws ApplicationValidationError if not currently active
|
|
92
|
+
*/
|
|
93
|
+
export declare function deactivateApplication(id: string, actorId?: string): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* Activate an application (inactive → active).
|
|
96
|
+
*
|
|
97
|
+
* @param id - Application UUID
|
|
98
|
+
* @param actorId - UUID of the user performing the action
|
|
99
|
+
* @throws ApplicationNotFoundError if not found
|
|
100
|
+
* @throws ApplicationValidationError if not currently inactive
|
|
101
|
+
*/
|
|
102
|
+
export declare function activateApplication(id: string, actorId?: string): Promise<void>;
|
|
103
|
+
/**
|
|
104
|
+
* Archive an application (active or inactive → archived).
|
|
105
|
+
*
|
|
106
|
+
* Archive is a permanent soft-delete — archived applications cannot
|
|
107
|
+
* be restored (unlike organizations which support restore).
|
|
108
|
+
*
|
|
109
|
+
* @param id - Application UUID
|
|
110
|
+
* @param actorId - UUID of the user performing the action
|
|
111
|
+
* @throws ApplicationNotFoundError if not found
|
|
112
|
+
* @throws ApplicationValidationError if already archived
|
|
113
|
+
*/
|
|
114
|
+
export declare function archiveApplication(id: string, actorId?: string): Promise<void>;
|
|
115
|
+
/**
|
|
116
|
+
* Create a new module within an application.
|
|
117
|
+
*
|
|
118
|
+
* 1. Validate the parent application exists
|
|
119
|
+
* 2. Generate slug from name if not provided
|
|
120
|
+
* 3. Validate slug format
|
|
121
|
+
* 4. Check module slug uniqueness within the application
|
|
122
|
+
* 5. Insert module via repository
|
|
123
|
+
* 6. Write audit log entry
|
|
124
|
+
*
|
|
125
|
+
* @param applicationId - Parent application UUID
|
|
126
|
+
* @param input - Module creation data
|
|
127
|
+
* @param actorId - UUID of the user performing the action
|
|
128
|
+
* @returns Created module
|
|
129
|
+
* @throws ApplicationNotFoundError if parent application not found
|
|
130
|
+
* @throws ApplicationValidationError if slug is invalid or taken within app
|
|
131
|
+
*/
|
|
132
|
+
export declare function createModule(applicationId: string, input: CreateModuleInput, actorId?: string): Promise<ApplicationModule>;
|
|
133
|
+
/**
|
|
134
|
+
* Update a module's basic fields (name, description).
|
|
135
|
+
*
|
|
136
|
+
* @param moduleId - Module UUID
|
|
137
|
+
* @param input - Fields to update
|
|
138
|
+
* @param actorId - UUID of the user performing the action
|
|
139
|
+
* @returns Updated module
|
|
140
|
+
* @throws ApplicationNotFoundError if module not found
|
|
141
|
+
*/
|
|
142
|
+
export declare function updateModule(moduleId: string, input: UpdateModuleInput, actorId?: string): Promise<ApplicationModule>;
|
|
143
|
+
/**
|
|
144
|
+
* Deactivate a module (set status to inactive).
|
|
145
|
+
*
|
|
146
|
+
* @param moduleId - Module UUID
|
|
147
|
+
* @param actorId - UUID of the user performing the action
|
|
148
|
+
* @throws ApplicationNotFoundError if module not found
|
|
149
|
+
* @throws ApplicationValidationError if not currently active
|
|
150
|
+
*/
|
|
151
|
+
export declare function deactivateModule(moduleId: string, actorId?: string): Promise<void>;
|
|
152
|
+
/**
|
|
153
|
+
* List all modules for an application.
|
|
154
|
+
* Delegates directly to the repository.
|
|
155
|
+
*
|
|
156
|
+
* @param applicationId - Application UUID
|
|
157
|
+
* @returns Array of modules
|
|
158
|
+
*/
|
|
159
|
+
export declare function listModules(applicationId: string): Promise<ApplicationModule[]>;
|
|
160
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/applications/service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,eAAe,EAChB,MAAM,YAAY,CAAC;AAepB,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAmB9D;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,sBAAsB,EAC7B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,WAAW,CAAC,CAmCtB;AAMD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAWhF;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAWpF;AAMD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,sBAAsB,EAC7B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,WAAW,CAAC,CA6BtB;AAMD;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAEvC;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAE7C;AAgBD;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAgBf;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,YAAY,CAChC,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,iBAAiB,EACxB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,CAAC,CAqC5B;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,iBAAiB,EACxB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,CAAC,CAyB5B;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAErF"}
|