@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,388 @@
|
|
|
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 { insertApplication, findApplicationById, findApplicationBySlug, updateApplication as repoUpdateApp, listApplications as repoListApps, listApplicationsCursor as repoListAppsCursor, slugExists, insertModule, findModuleById, updateModule as repoUpdateModule, listModules as repoListModules, moduleSlugExists, } from './repository.js';
|
|
25
|
+
import { getCachedApplicationById, getCachedApplicationBySlug, cacheApplication, invalidateApplicationCache, } from './cache.js';
|
|
26
|
+
import { generateSlug, validateSlug } from './slugs.js';
|
|
27
|
+
import { writeAuditLog } from '../lib/audit-log.js';
|
|
28
|
+
import { ApplicationNotFoundError, ApplicationValidationError } from './errors.js';
|
|
29
|
+
// ===========================================================================
|
|
30
|
+
// Application CRUD
|
|
31
|
+
// ===========================================================================
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Create
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
/**
|
|
36
|
+
* Create a new application.
|
|
37
|
+
*
|
|
38
|
+
* 1. Generate slug from name if not provided
|
|
39
|
+
* 2. Validate slug format and reserved words
|
|
40
|
+
* 3. Check slug uniqueness in the database
|
|
41
|
+
* 4. Insert application via repository
|
|
42
|
+
* 5. Cache the new application
|
|
43
|
+
* 6. Write audit log entry
|
|
44
|
+
*
|
|
45
|
+
* @param input - Application creation data
|
|
46
|
+
* @param actorId - UUID of the user performing the action (for audit)
|
|
47
|
+
* @returns Created application
|
|
48
|
+
* @throws ApplicationValidationError if slug is invalid or already taken
|
|
49
|
+
*/
|
|
50
|
+
export async function createApplication(input, actorId) {
|
|
51
|
+
// Generate or use provided slug
|
|
52
|
+
const slug = input.slug ?? generateSlug(input.name);
|
|
53
|
+
// Validate slug format and reserved words
|
|
54
|
+
const validation = validateSlug(slug);
|
|
55
|
+
if (!validation.isValid) {
|
|
56
|
+
throw new ApplicationValidationError(validation.error);
|
|
57
|
+
}
|
|
58
|
+
// Check uniqueness
|
|
59
|
+
const taken = await slugExists(slug);
|
|
60
|
+
if (taken) {
|
|
61
|
+
throw new ApplicationValidationError('Slug already in use');
|
|
62
|
+
}
|
|
63
|
+
// Insert into database
|
|
64
|
+
const app = await insertApplication({
|
|
65
|
+
name: input.name,
|
|
66
|
+
slug,
|
|
67
|
+
description: input.description,
|
|
68
|
+
});
|
|
69
|
+
// Cache the new application
|
|
70
|
+
await cacheApplication(app);
|
|
71
|
+
// Audit log (fire-and-forget)
|
|
72
|
+
await writeAuditLog({
|
|
73
|
+
eventType: 'app.created',
|
|
74
|
+
eventCategory: 'admin',
|
|
75
|
+
actorId,
|
|
76
|
+
metadata: { applicationId: app.id, slug: app.slug, name: app.name },
|
|
77
|
+
});
|
|
78
|
+
return app;
|
|
79
|
+
}
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
// Read
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
/**
|
|
84
|
+
* Find an application by ID.
|
|
85
|
+
* Checks Redis cache first, falls back to database on miss.
|
|
86
|
+
*
|
|
87
|
+
* @param id - Application UUID
|
|
88
|
+
* @returns Application or null if not found
|
|
89
|
+
*/
|
|
90
|
+
export async function getApplicationById(id) {
|
|
91
|
+
// Try cache first
|
|
92
|
+
const cached = await getCachedApplicationById(id);
|
|
93
|
+
if (cached)
|
|
94
|
+
return cached;
|
|
95
|
+
// Fall back to database
|
|
96
|
+
const app = await findApplicationById(id);
|
|
97
|
+
if (app) {
|
|
98
|
+
await cacheApplication(app);
|
|
99
|
+
}
|
|
100
|
+
return app;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Find an application by slug.
|
|
104
|
+
* Checks Redis cache first, falls back to database on miss.
|
|
105
|
+
*
|
|
106
|
+
* @param slug - Application slug
|
|
107
|
+
* @returns Application or null if not found
|
|
108
|
+
*/
|
|
109
|
+
export async function getApplicationBySlug(slug) {
|
|
110
|
+
// Try cache first
|
|
111
|
+
const cached = await getCachedApplicationBySlug(slug);
|
|
112
|
+
if (cached)
|
|
113
|
+
return cached;
|
|
114
|
+
// Fall back to database
|
|
115
|
+
const app = await findApplicationBySlug(slug);
|
|
116
|
+
if (app) {
|
|
117
|
+
await cacheApplication(app);
|
|
118
|
+
}
|
|
119
|
+
return app;
|
|
120
|
+
}
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
// Update
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
/**
|
|
125
|
+
* Update an application's basic fields (name, description).
|
|
126
|
+
*
|
|
127
|
+
* @param id - Application UUID
|
|
128
|
+
* @param input - Fields to update
|
|
129
|
+
* @param actorId - UUID of the user performing the action
|
|
130
|
+
* @returns Updated application
|
|
131
|
+
* @throws ApplicationNotFoundError if application not found
|
|
132
|
+
*/
|
|
133
|
+
export async function updateApplication(id, input, actorId) {
|
|
134
|
+
// Build update data from input
|
|
135
|
+
const updateData = {};
|
|
136
|
+
if (input.name !== undefined)
|
|
137
|
+
updateData.name = input.name;
|
|
138
|
+
if (input.description !== undefined)
|
|
139
|
+
updateData.description = input.description;
|
|
140
|
+
let app;
|
|
141
|
+
try {
|
|
142
|
+
app = await repoUpdateApp(id, updateData);
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
if (err instanceof Error && err.message === 'Application not found') {
|
|
146
|
+
throw new ApplicationNotFoundError(id);
|
|
147
|
+
}
|
|
148
|
+
throw err;
|
|
149
|
+
}
|
|
150
|
+
// Invalidate old cache and re-cache the updated version
|
|
151
|
+
await invalidateApplicationCache(app.slug, app.id);
|
|
152
|
+
await cacheApplication(app);
|
|
153
|
+
// Audit log (fire-and-forget)
|
|
154
|
+
await writeAuditLog({
|
|
155
|
+
eventType: 'app.updated',
|
|
156
|
+
eventCategory: 'admin',
|
|
157
|
+
actorId,
|
|
158
|
+
metadata: { applicationId: app.id, fields: Object.keys(updateData) },
|
|
159
|
+
});
|
|
160
|
+
return app;
|
|
161
|
+
}
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
163
|
+
// List
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
/**
|
|
166
|
+
* List applications with pagination and filtering.
|
|
167
|
+
* Delegates directly to the repository.
|
|
168
|
+
*
|
|
169
|
+
* @param options - Pagination, filter, and sort options
|
|
170
|
+
* @returns Paginated result
|
|
171
|
+
*/
|
|
172
|
+
export async function listApplications(options) {
|
|
173
|
+
return repoListApps(options);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* List applications with cursor-based keyset pagination.
|
|
177
|
+
* Provides stable, efficient pagination without COUNT queries.
|
|
178
|
+
*
|
|
179
|
+
* @param options - Cursor, limit, filter, and sort options
|
|
180
|
+
* @returns Cursor-paginated result with nextCursor/hasMore
|
|
181
|
+
*/
|
|
182
|
+
export async function listApplicationsCursor(options) {
|
|
183
|
+
return repoListAppsCursor(options);
|
|
184
|
+
}
|
|
185
|
+
// ===========================================================================
|
|
186
|
+
// Status lifecycle
|
|
187
|
+
// ===========================================================================
|
|
188
|
+
/**
|
|
189
|
+
* Load and validate an application exists before a status change.
|
|
190
|
+
* @throws ApplicationNotFoundError if not found
|
|
191
|
+
*/
|
|
192
|
+
async function loadAppForStatusChange(id) {
|
|
193
|
+
const app = await findApplicationById(id);
|
|
194
|
+
if (!app)
|
|
195
|
+
throw new ApplicationNotFoundError(id);
|
|
196
|
+
return app;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Deactivate an application (active → inactive).
|
|
200
|
+
*
|
|
201
|
+
* @param id - Application UUID
|
|
202
|
+
* @param actorId - UUID of the user performing the action
|
|
203
|
+
* @throws ApplicationNotFoundError if not found
|
|
204
|
+
* @throws ApplicationValidationError if not currently active
|
|
205
|
+
*/
|
|
206
|
+
export async function deactivateApplication(id, actorId) {
|
|
207
|
+
const app = await loadAppForStatusChange(id);
|
|
208
|
+
if (app.status !== 'active') {
|
|
209
|
+
throw new ApplicationValidationError(`Cannot deactivate application from status: ${app.status}`);
|
|
210
|
+
}
|
|
211
|
+
await repoUpdateApp(id, { status: 'inactive' });
|
|
212
|
+
await invalidateApplicationCache(app.slug, app.id);
|
|
213
|
+
await writeAuditLog({
|
|
214
|
+
eventType: 'app.deactivated',
|
|
215
|
+
eventCategory: 'admin',
|
|
216
|
+
actorId,
|
|
217
|
+
metadata: { applicationId: app.id },
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Activate an application (inactive → active).
|
|
222
|
+
*
|
|
223
|
+
* @param id - Application UUID
|
|
224
|
+
* @param actorId - UUID of the user performing the action
|
|
225
|
+
* @throws ApplicationNotFoundError if not found
|
|
226
|
+
* @throws ApplicationValidationError if not currently inactive
|
|
227
|
+
*/
|
|
228
|
+
export async function activateApplication(id, actorId) {
|
|
229
|
+
const app = await loadAppForStatusChange(id);
|
|
230
|
+
if (app.status !== 'inactive') {
|
|
231
|
+
throw new ApplicationValidationError(`Cannot activate application from status: ${app.status}`);
|
|
232
|
+
}
|
|
233
|
+
await repoUpdateApp(id, { status: 'active' });
|
|
234
|
+
await invalidateApplicationCache(app.slug, app.id);
|
|
235
|
+
await writeAuditLog({
|
|
236
|
+
eventType: 'app.activated',
|
|
237
|
+
eventCategory: 'admin',
|
|
238
|
+
actorId,
|
|
239
|
+
metadata: { applicationId: app.id },
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Archive an application (active or inactive → archived).
|
|
244
|
+
*
|
|
245
|
+
* Archive is a permanent soft-delete — archived applications cannot
|
|
246
|
+
* be restored (unlike organizations which support restore).
|
|
247
|
+
*
|
|
248
|
+
* @param id - Application UUID
|
|
249
|
+
* @param actorId - UUID of the user performing the action
|
|
250
|
+
* @throws ApplicationNotFoundError if not found
|
|
251
|
+
* @throws ApplicationValidationError if already archived
|
|
252
|
+
*/
|
|
253
|
+
export async function archiveApplication(id, actorId) {
|
|
254
|
+
const app = await loadAppForStatusChange(id);
|
|
255
|
+
if (app.status === 'archived') {
|
|
256
|
+
throw new ApplicationValidationError('Application is already archived');
|
|
257
|
+
}
|
|
258
|
+
await repoUpdateApp(id, { status: 'archived' });
|
|
259
|
+
await invalidateApplicationCache(app.slug, app.id);
|
|
260
|
+
await writeAuditLog({
|
|
261
|
+
eventType: 'app.archived',
|
|
262
|
+
eventCategory: 'admin',
|
|
263
|
+
actorId,
|
|
264
|
+
metadata: { applicationId: app.id, previousStatus: app.status },
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
// ===========================================================================
|
|
268
|
+
// Module management
|
|
269
|
+
// ===========================================================================
|
|
270
|
+
/**
|
|
271
|
+
* Create a new module within an application.
|
|
272
|
+
*
|
|
273
|
+
* 1. Validate the parent application exists
|
|
274
|
+
* 2. Generate slug from name if not provided
|
|
275
|
+
* 3. Validate slug format
|
|
276
|
+
* 4. Check module slug uniqueness within the application
|
|
277
|
+
* 5. Insert module via repository
|
|
278
|
+
* 6. Write audit log entry
|
|
279
|
+
*
|
|
280
|
+
* @param applicationId - Parent application UUID
|
|
281
|
+
* @param input - Module creation data
|
|
282
|
+
* @param actorId - UUID of the user performing the action
|
|
283
|
+
* @returns Created module
|
|
284
|
+
* @throws ApplicationNotFoundError if parent application not found
|
|
285
|
+
* @throws ApplicationValidationError if slug is invalid or taken within app
|
|
286
|
+
*/
|
|
287
|
+
export async function createModule(applicationId, input, actorId) {
|
|
288
|
+
// Validate parent application exists
|
|
289
|
+
const app = await findApplicationById(applicationId);
|
|
290
|
+
if (!app)
|
|
291
|
+
throw new ApplicationNotFoundError(applicationId);
|
|
292
|
+
// Generate or use provided slug
|
|
293
|
+
const slug = input.slug ?? generateSlug(input.name);
|
|
294
|
+
// Validate slug format and reserved words
|
|
295
|
+
const validation = validateSlug(slug);
|
|
296
|
+
if (!validation.isValid) {
|
|
297
|
+
throw new ApplicationValidationError(validation.error);
|
|
298
|
+
}
|
|
299
|
+
// Check uniqueness within the application
|
|
300
|
+
const taken = await moduleSlugExists(applicationId, slug);
|
|
301
|
+
if (taken) {
|
|
302
|
+
throw new ApplicationValidationError('Module slug already in use within this application');
|
|
303
|
+
}
|
|
304
|
+
// Insert into database
|
|
305
|
+
const mod = await insertModule({
|
|
306
|
+
applicationId,
|
|
307
|
+
name: input.name,
|
|
308
|
+
slug,
|
|
309
|
+
description: input.description,
|
|
310
|
+
});
|
|
311
|
+
// Audit log (fire-and-forget)
|
|
312
|
+
await writeAuditLog({
|
|
313
|
+
eventType: 'app.module.created',
|
|
314
|
+
eventCategory: 'admin',
|
|
315
|
+
actorId,
|
|
316
|
+
metadata: { applicationId, moduleId: mod.id, slug: mod.slug, name: mod.name },
|
|
317
|
+
});
|
|
318
|
+
return mod;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Update a module's basic fields (name, description).
|
|
322
|
+
*
|
|
323
|
+
* @param moduleId - Module UUID
|
|
324
|
+
* @param input - Fields to update
|
|
325
|
+
* @param actorId - UUID of the user performing the action
|
|
326
|
+
* @returns Updated module
|
|
327
|
+
* @throws ApplicationNotFoundError if module not found
|
|
328
|
+
*/
|
|
329
|
+
export async function updateModule(moduleId, input, actorId) {
|
|
330
|
+
// Build update data from input
|
|
331
|
+
const updateData = {};
|
|
332
|
+
if (input.name !== undefined)
|
|
333
|
+
updateData.name = input.name;
|
|
334
|
+
if (input.description !== undefined)
|
|
335
|
+
updateData.description = input.description;
|
|
336
|
+
let mod;
|
|
337
|
+
try {
|
|
338
|
+
mod = await repoUpdateModule(moduleId, updateData);
|
|
339
|
+
}
|
|
340
|
+
catch (err) {
|
|
341
|
+
if (err instanceof Error && err.message === 'Module not found') {
|
|
342
|
+
throw new ApplicationNotFoundError(moduleId);
|
|
343
|
+
}
|
|
344
|
+
throw err;
|
|
345
|
+
}
|
|
346
|
+
// Audit log (fire-and-forget)
|
|
347
|
+
await writeAuditLog({
|
|
348
|
+
eventType: 'app.module.updated',
|
|
349
|
+
eventCategory: 'admin',
|
|
350
|
+
actorId,
|
|
351
|
+
metadata: { moduleId: mod.id, applicationId: mod.applicationId, fields: Object.keys(updateData) },
|
|
352
|
+
});
|
|
353
|
+
return mod;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Deactivate a module (set status to inactive).
|
|
357
|
+
*
|
|
358
|
+
* @param moduleId - Module UUID
|
|
359
|
+
* @param actorId - UUID of the user performing the action
|
|
360
|
+
* @throws ApplicationNotFoundError if module not found
|
|
361
|
+
* @throws ApplicationValidationError if not currently active
|
|
362
|
+
*/
|
|
363
|
+
export async function deactivateModule(moduleId, actorId) {
|
|
364
|
+
const mod = await findModuleById(moduleId);
|
|
365
|
+
if (!mod)
|
|
366
|
+
throw new ApplicationNotFoundError(moduleId);
|
|
367
|
+
if (mod.status !== 'active') {
|
|
368
|
+
throw new ApplicationValidationError(`Cannot deactivate module from status: ${mod.status}`);
|
|
369
|
+
}
|
|
370
|
+
await repoUpdateModule(moduleId, { status: 'inactive' });
|
|
371
|
+
await writeAuditLog({
|
|
372
|
+
eventType: 'app.module.deactivated',
|
|
373
|
+
eventCategory: 'admin',
|
|
374
|
+
actorId,
|
|
375
|
+
metadata: { moduleId: mod.id, applicationId: mod.applicationId },
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* List all modules for an application.
|
|
380
|
+
* Delegates directly to the repository.
|
|
381
|
+
*
|
|
382
|
+
* @param applicationId - Application UUID
|
|
383
|
+
* @returns Array of modules
|
|
384
|
+
*/
|
|
385
|
+
export async function listModules(applicationId) {
|
|
386
|
+
return repoListModules(applicationId);
|
|
387
|
+
}
|
|
388
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/applications/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slug generation and validation utilities for applications.
|
|
3
|
+
*
|
|
4
|
+
* Application slugs are URL-safe identifiers used to reference
|
|
5
|
+
* applications in API paths and configuration. They must be
|
|
6
|
+
* 3–100 characters, lowercase alphanumeric with hyphens,
|
|
7
|
+
* and cannot be a reserved system word.
|
|
8
|
+
*
|
|
9
|
+
* This module provides:
|
|
10
|
+
* - `generateSlug(name)` — Derive a slug from an application name
|
|
11
|
+
* - `validateSlug(slug)` — Check format and reserved-word rules
|
|
12
|
+
* - `RESERVED_SLUGS` — The set of words that cannot be used as application slugs
|
|
13
|
+
*
|
|
14
|
+
* Note: Application reserved words differ from organization reserved words
|
|
15
|
+
* because app slugs appear in different contexts (e.g., app references in
|
|
16
|
+
* client metadata, module namespacing).
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Reserved slugs that cannot be used as application slugs.
|
|
20
|
+
* These conflict with system concepts, internal naming, or
|
|
21
|
+
* could cause confusion with infrastructure functionality.
|
|
22
|
+
*/
|
|
23
|
+
export declare const RESERVED_SLUGS: ReadonlySet<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Generate a URL-safe slug from an application name.
|
|
26
|
+
*
|
|
27
|
+
* Transformation rules:
|
|
28
|
+
* 1. Convert to lowercase
|
|
29
|
+
* 2. Replace non-alphanumeric characters with hyphens
|
|
30
|
+
* 3. Collapse multiple consecutive hyphens into one
|
|
31
|
+
* 4. Trim leading and trailing hyphens
|
|
32
|
+
* 5. Truncate to 100 characters (trimming trailing hyphens after truncation)
|
|
33
|
+
*
|
|
34
|
+
* Returns an empty string for empty/whitespace-only input — the caller
|
|
35
|
+
* (service layer) is responsible for validation.
|
|
36
|
+
*
|
|
37
|
+
* @param name - Application name to derive a slug from
|
|
38
|
+
* @returns Generated slug string
|
|
39
|
+
*/
|
|
40
|
+
export declare function generateSlug(name: string): string;
|
|
41
|
+
/** Result of slug validation — isValid flag with optional error message */
|
|
42
|
+
export interface SlugValidationResult {
|
|
43
|
+
isValid: boolean;
|
|
44
|
+
error?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Validate a slug against format and reserved word rules.
|
|
48
|
+
*
|
|
49
|
+
* Checks (in order):
|
|
50
|
+
* 1. Minimum length (3 characters)
|
|
51
|
+
* 2. Maximum length (100 characters)
|
|
52
|
+
* 3. Format (lowercase alphanumeric + hyphens, no leading/trailing hyphens)
|
|
53
|
+
* 4. Not a reserved word
|
|
54
|
+
*
|
|
55
|
+
* Does NOT check uniqueness — that's the repository/service layer's job.
|
|
56
|
+
*
|
|
57
|
+
* @param slug - Slug string to validate
|
|
58
|
+
* @returns Object with isValid boolean and optional error message
|
|
59
|
+
*/
|
|
60
|
+
export declare function validateSlug(slug: string): SlugValidationResult;
|
|
61
|
+
//# sourceMappingURL=slugs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slugs.d.ts","sourceRoot":"","sources":["../../src/applications/slugs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,CAQ7C,CAAC;AAiBH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgBjD;AAMD,2EAA2E;AAC3E,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,CA2B/D"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slug generation and validation utilities for applications.
|
|
3
|
+
*
|
|
4
|
+
* Application slugs are URL-safe identifiers used to reference
|
|
5
|
+
* applications in API paths and configuration. They must be
|
|
6
|
+
* 3–100 characters, lowercase alphanumeric with hyphens,
|
|
7
|
+
* and cannot be a reserved system word.
|
|
8
|
+
*
|
|
9
|
+
* This module provides:
|
|
10
|
+
* - `generateSlug(name)` — Derive a slug from an application name
|
|
11
|
+
* - `validateSlug(slug)` — Check format and reserved-word rules
|
|
12
|
+
* - `RESERVED_SLUGS` — The set of words that cannot be used as application slugs
|
|
13
|
+
*
|
|
14
|
+
* Note: Application reserved words differ from organization reserved words
|
|
15
|
+
* because app slugs appear in different contexts (e.g., app references in
|
|
16
|
+
* client metadata, module namespacing).
|
|
17
|
+
*/
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Reserved slugs
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
/**
|
|
22
|
+
* Reserved slugs that cannot be used as application slugs.
|
|
23
|
+
* These conflict with system concepts, internal naming, or
|
|
24
|
+
* could cause confusion with infrastructure functionality.
|
|
25
|
+
*/
|
|
26
|
+
export const RESERVED_SLUGS = new Set([
|
|
27
|
+
'admin',
|
|
28
|
+
'api',
|
|
29
|
+
'system',
|
|
30
|
+
'internal',
|
|
31
|
+
'default',
|
|
32
|
+
'health',
|
|
33
|
+
'status',
|
|
34
|
+
]);
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Slug format
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
/**
|
|
39
|
+
* Slug format regex: 3–100 characters, lowercase alphanumeric + hyphens.
|
|
40
|
+
* Must start and end with an alphanumeric character (no leading/trailing hyphens).
|
|
41
|
+
* The middle section allows 1–98 characters of alphanumeric + hyphens.
|
|
42
|
+
*/
|
|
43
|
+
const SLUG_REGEX = /^[a-z0-9][a-z0-9-]{1,98}[a-z0-9]$/;
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Slug generation
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
/**
|
|
48
|
+
* Generate a URL-safe slug from an application name.
|
|
49
|
+
*
|
|
50
|
+
* Transformation rules:
|
|
51
|
+
* 1. Convert to lowercase
|
|
52
|
+
* 2. Replace non-alphanumeric characters with hyphens
|
|
53
|
+
* 3. Collapse multiple consecutive hyphens into one
|
|
54
|
+
* 4. Trim leading and trailing hyphens
|
|
55
|
+
* 5. Truncate to 100 characters (trimming trailing hyphens after truncation)
|
|
56
|
+
*
|
|
57
|
+
* Returns an empty string for empty/whitespace-only input — the caller
|
|
58
|
+
* (service layer) is responsible for validation.
|
|
59
|
+
*
|
|
60
|
+
* @param name - Application name to derive a slug from
|
|
61
|
+
* @returns Generated slug string
|
|
62
|
+
*/
|
|
63
|
+
export function generateSlug(name) {
|
|
64
|
+
if (!name || !name.trim()) {
|
|
65
|
+
return '';
|
|
66
|
+
}
|
|
67
|
+
const slug = name
|
|
68
|
+
.toLowerCase()
|
|
69
|
+
// Replace any character that's not a-z, 0-9, or hyphen with a hyphen
|
|
70
|
+
.replace(/[^a-z0-9-]/g, '-')
|
|
71
|
+
// Collapse consecutive hyphens into a single hyphen
|
|
72
|
+
.replace(/-+/g, '-')
|
|
73
|
+
// Remove leading and trailing hyphens
|
|
74
|
+
.replace(/^-+|-+$/g, '');
|
|
75
|
+
// Truncate to 100 characters, then trim any trailing hyphen caused by truncation
|
|
76
|
+
return slug.slice(0, 100).replace(/-+$/, '');
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Validate a slug against format and reserved word rules.
|
|
80
|
+
*
|
|
81
|
+
* Checks (in order):
|
|
82
|
+
* 1. Minimum length (3 characters)
|
|
83
|
+
* 2. Maximum length (100 characters)
|
|
84
|
+
* 3. Format (lowercase alphanumeric + hyphens, no leading/trailing hyphens)
|
|
85
|
+
* 4. Not a reserved word
|
|
86
|
+
*
|
|
87
|
+
* Does NOT check uniqueness — that's the repository/service layer's job.
|
|
88
|
+
*
|
|
89
|
+
* @param slug - Slug string to validate
|
|
90
|
+
* @returns Object with isValid boolean and optional error message
|
|
91
|
+
*/
|
|
92
|
+
export function validateSlug(slug) {
|
|
93
|
+
// Check minimum length
|
|
94
|
+
if (slug.length < 3) {
|
|
95
|
+
return { isValid: false, error: 'Slug must be at least 3 characters' };
|
|
96
|
+
}
|
|
97
|
+
// Check maximum length
|
|
98
|
+
if (slug.length > 100) {
|
|
99
|
+
return { isValid: false, error: 'Slug must be at most 100 characters' };
|
|
100
|
+
}
|
|
101
|
+
// Check format: lowercase alphanumeric + hyphens, no leading/trailing hyphens
|
|
102
|
+
if (!SLUG_REGEX.test(slug)) {
|
|
103
|
+
return {
|
|
104
|
+
isValid: false,
|
|
105
|
+
error: 'Slug must contain only lowercase letters, numbers, and hyphens, ' +
|
|
106
|
+
'and cannot start or end with a hyphen',
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// Check reserved words
|
|
110
|
+
if (RESERVED_SLUGS.has(slug)) {
|
|
111
|
+
return { isValid: false, error: `Slug "${slug}" is reserved and cannot be used` };
|
|
112
|
+
}
|
|
113
|
+
return { isValid: true };
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=slugs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slugs.js","sourceRoot":"","sources":["../../src/applications/slugs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC;IACzD,OAAO;IACP,KAAK;IACL,QAAQ;IACR,UAAU;IACV,SAAS;IACT,QAAQ;IACR,QAAQ;CACT,CAAC,CAAC;AAEH,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,UAAU,GAAG,mCAAmC,CAAC;AAEvD,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,IAAI,GAAG,IAAI;SACd,WAAW,EAAE;QACd,qEAAqE;SACpE,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;QAC5B,oDAAoD;SACnD,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;QACpB,sCAAsC;SACrC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAE3B,iFAAiF;IACjF,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC/C,CAAC;AAYD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,uBAAuB;IACvB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAC;IACzE,CAAC;IAED,uBAAuB;IACvB,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QACtB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,qCAAqC,EAAE,CAAC;IAC1E,CAAC;IAED,8EAA8E;IAC9E,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EACH,kEAAkE;gBAClE,uCAAuC;SAC1C,CAAC;IACJ,CAAC;IAED,uBAAuB;IACvB,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,IAAI,kCAAkC,EAAE,CAAC;IACpF,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC"}
|