@sixthsummit/ship-api 0.0.0-stage → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +605 -0
- package/LICENSE +202 -0
- package/NOTICE +4 -0
- package/README.md +58 -2
- package/cli/commands/add.js +537 -0
- package/cli/commands/contract.js +2 -0
- package/cli/commands/create.js +250 -0
- package/cli/commands/dev.js +227 -0
- package/cli/commands/doctor.js +286 -0
- package/cli/commands/generate.js +937 -0
- package/cli/commands/graph.js +2 -0
- package/cli/commands/migrate-orm.js +1171 -0
- package/cli/commands/update.js +37 -0
- package/cli/ship-api.js +285 -0
- package/lib/app/auth/AuthProvider.d.ts +91 -0
- package/lib/app/auth/AuthProvider.d.ts.map +1 -0
- package/lib/app/auth/AuthProvider.js +13 -0
- package/lib/app/auth/AuthProvider.js.map +1 -0
- package/lib/app/auth/adapters/firebase.d.ts +79 -0
- package/lib/app/auth/adapters/firebase.d.ts.map +1 -0
- package/lib/app/auth/adapters/firebase.js +122 -0
- package/lib/app/auth/adapters/firebase.js.map +1 -0
- package/lib/app/auth/adapters/jwtCookie.d.ts +55 -0
- package/lib/app/auth/adapters/jwtCookie.d.ts.map +1 -0
- package/lib/app/auth/adapters/jwtCookie.js +120 -0
- package/lib/app/auth/adapters/jwtCookie.js.map +1 -0
- package/lib/app/auth/index.d.ts +8 -0
- package/lib/app/auth/index.d.ts.map +1 -0
- package/lib/app/auth/index.js +7 -0
- package/lib/app/auth/index.js.map +1 -0
- package/lib/app/auth/jwt/AuthFlow.d.ts +94 -0
- package/lib/app/auth/jwt/AuthFlow.d.ts.map +1 -0
- package/lib/app/auth/jwt/AuthFlow.js +127 -0
- package/lib/app/auth/jwt/AuthFlow.js.map +1 -0
- package/lib/app/auth/jwt/DrizzleRefreshTokenStore.d.ts +80 -0
- package/lib/app/auth/jwt/DrizzleRefreshTokenStore.d.ts.map +1 -0
- package/lib/app/auth/jwt/DrizzleRefreshTokenStore.js +134 -0
- package/lib/app/auth/jwt/DrizzleRefreshTokenStore.js.map +1 -0
- package/lib/app/auth/jwt/JwtSigner.d.ts +123 -0
- package/lib/app/auth/jwt/JwtSigner.d.ts.map +1 -0
- package/lib/app/auth/jwt/JwtSigner.js +118 -0
- package/lib/app/auth/jwt/JwtSigner.js.map +1 -0
- package/lib/app/auth/jwt/RefreshTokenStore.d.ts +97 -0
- package/lib/app/auth/jwt/RefreshTokenStore.d.ts.map +1 -0
- package/lib/app/auth/jwt/RefreshTokenStore.js +122 -0
- package/lib/app/auth/jwt/RefreshTokenStore.js.map +1 -0
- package/lib/app/auth/permissionDefinition.d.ts +20 -0
- package/lib/app/auth/permissionDefinition.d.ts.map +1 -0
- package/lib/app/auth/permissionDefinition.js +2 -0
- package/lib/app/auth/permissionDefinition.js.map +1 -0
- package/lib/app/context/RequestContext.d.ts +59 -0
- package/lib/app/context/RequestContext.d.ts.map +1 -0
- package/lib/app/context/RequestContext.js +25 -0
- package/lib/app/context/RequestContext.js.map +1 -0
- package/lib/app/db/QueryOptions.d.ts +82 -0
- package/lib/app/db/QueryOptions.d.ts.map +1 -0
- package/lib/app/db/QueryOptions.js +37 -0
- package/lib/app/db/QueryOptions.js.map +1 -0
- package/lib/app/db/baseFields.d.ts +60 -0
- package/lib/app/db/baseFields.d.ts.map +1 -0
- package/lib/app/db/baseFields.js +54 -0
- package/lib/app/db/baseFields.js.map +1 -0
- package/lib/app/db/buildWhere.d.ts +22 -0
- package/lib/app/db/buildWhere.d.ts.map +1 -0
- package/lib/app/db/buildWhere.js +75 -0
- package/lib/app/db/buildWhere.js.map +1 -0
- package/lib/app/db/client.d.ts +111 -0
- package/lib/app/db/client.d.ts.map +1 -0
- package/lib/app/db/client.js +99 -0
- package/lib/app/db/client.js.map +1 -0
- package/lib/app/db/tenantScoped.d.ts +59 -0
- package/lib/app/db/tenantScoped.d.ts.map +1 -0
- package/lib/app/db/tenantScoped.js +54 -0
- package/lib/app/db/tenantScoped.js.map +1 -0
- package/lib/app/db/transaction.d.ts +58 -0
- package/lib/app/db/transaction.d.ts.map +1 -0
- package/lib/app/db/transaction.js +106 -0
- package/lib/app/db/transaction.js.map +1 -0
- package/lib/app/health/HealthCheck.d.ts +121 -0
- package/lib/app/health/HealthCheck.d.ts.map +1 -0
- package/lib/app/health/HealthCheck.js +151 -0
- package/lib/app/health/HealthCheck.js.map +1 -0
- package/lib/app/health/redisHealthCheck.d.ts +14 -0
- package/lib/app/health/redisHealthCheck.d.ts.map +1 -0
- package/lib/app/health/redisHealthCheck.js +21 -0
- package/lib/app/health/redisHealthCheck.js.map +1 -0
- package/lib/app/lifecycle/Bootstrapper.d.ts +92 -0
- package/lib/app/lifecycle/Bootstrapper.d.ts.map +1 -0
- package/lib/app/lifecycle/Bootstrapper.js +99 -0
- package/lib/app/lifecycle/Bootstrapper.js.map +1 -0
- package/lib/app/registry/routes.d.ts +89 -0
- package/lib/app/registry/routes.d.ts.map +1 -0
- package/lib/app/registry/routes.js +72 -0
- package/lib/app/registry/routes.js.map +1 -0
- package/lib/app/services/DrizzleEntityService.d.ts +123 -0
- package/lib/app/services/DrizzleEntityService.d.ts.map +1 -0
- package/lib/app/services/DrizzleEntityService.js +342 -0
- package/lib/app/services/DrizzleEntityService.js.map +1 -0
- package/lib/app/services/RedisProvider.d.ts +52 -0
- package/lib/app/services/RedisProvider.d.ts.map +1 -0
- package/lib/app/services/RedisProvider.js +75 -0
- package/lib/app/services/RedisProvider.js.map +1 -0
- package/lib/app/services/cache/Cache.d.ts +70 -0
- package/lib/app/services/cache/Cache.d.ts.map +1 -0
- package/lib/app/services/cache/Cache.js +18 -0
- package/lib/app/services/cache/Cache.js.map +1 -0
- package/lib/app/services/cache/InMemoryCache.d.ts +35 -0
- package/lib/app/services/cache/InMemoryCache.d.ts.map +1 -0
- package/lib/app/services/cache/InMemoryCache.js +76 -0
- package/lib/app/services/cache/InMemoryCache.js.map +1 -0
- package/lib/app/services/cache/RedisCache.d.ts +99 -0
- package/lib/app/services/cache/RedisCache.d.ts.map +1 -0
- package/lib/app/services/cache/RedisCache.js +150 -0
- package/lib/app/services/cache/RedisCache.js.map +1 -0
- package/lib/app/services/cache/cached.d.ts +30 -0
- package/lib/app/services/cache/cached.d.ts.map +1 -0
- package/lib/app/services/cache/cached.js +38 -0
- package/lib/app/services/cache/cached.js.map +1 -0
- package/lib/app/services/cache/index.d.ts +5 -0
- package/lib/app/services/cache/index.d.ts.map +1 -0
- package/lib/app/services/cache/index.js +4 -0
- package/lib/app/services/cache/index.js.map +1 -0
- package/lib/app/services/cron/defineCron.d.ts +57 -0
- package/lib/app/services/cron/defineCron.d.ts.map +1 -0
- package/lib/app/services/cron/defineCron.js +15 -0
- package/lib/app/services/cron/defineCron.js.map +1 -0
- package/lib/app/services/cron/index.d.ts +2 -0
- package/lib/app/services/cron/index.d.ts.map +1 -0
- package/lib/app/services/cron/index.js +2 -0
- package/lib/app/services/cron/index.js.map +1 -0
- package/lib/app/services/hooks/LifecycleHooks.d.ts +61 -0
- package/lib/app/services/hooks/LifecycleHooks.d.ts.map +1 -0
- package/lib/app/services/hooks/LifecycleHooks.js +85 -0
- package/lib/app/services/hooks/LifecycleHooks.js.map +1 -0
- package/lib/app/services/jobs/JobsManager.d.ts +67 -0
- package/lib/app/services/jobs/JobsManager.d.ts.map +1 -0
- package/lib/app/services/jobs/JobsManager.js +121 -0
- package/lib/app/services/jobs/JobsManager.js.map +1 -0
- package/lib/app/services/jobs/bullBoard.d.ts +72 -0
- package/lib/app/services/jobs/bullBoard.d.ts.map +1 -0
- package/lib/app/services/jobs/bullBoard.js +96 -0
- package/lib/app/services/jobs/bullBoard.js.map +1 -0
- package/lib/app/services/jobs/defineJob.d.ts +81 -0
- package/lib/app/services/jobs/defineJob.d.ts.map +1 -0
- package/lib/app/services/jobs/defineJob.js +49 -0
- package/lib/app/services/jobs/defineJob.js.map +1 -0
- package/lib/app/services/jobs/index.d.ts +4 -0
- package/lib/app/services/jobs/index.d.ts.map +1 -0
- package/lib/app/services/jobs/index.js +4 -0
- package/lib/app/services/jobs/index.js.map +1 -0
- package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.d.ts +23 -0
- package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.d.ts.map +1 -0
- package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.js +51 -0
- package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.js.map +1 -0
- package/lib/app/services/rateLimit/RateLimitBackend.d.ts +41 -0
- package/lib/app/services/rateLimit/RateLimitBackend.d.ts.map +1 -0
- package/lib/app/services/rateLimit/RateLimitBackend.js +19 -0
- package/lib/app/services/rateLimit/RateLimitBackend.js.map +1 -0
- package/lib/app/services/rateLimit/RedisSlidingWindowBackend.d.ts +16 -0
- package/lib/app/services/rateLimit/RedisSlidingWindowBackend.d.ts.map +1 -0
- package/lib/app/services/rateLimit/RedisSlidingWindowBackend.js +80 -0
- package/lib/app/services/rateLimit/RedisSlidingWindowBackend.js.map +1 -0
- package/lib/app/services/rateLimit/index.d.ts +4 -0
- package/lib/app/services/rateLimit/index.d.ts.map +1 -0
- package/lib/app/services/rateLimit/index.js +3 -0
- package/lib/app/services/rateLimit/index.js.map +1 -0
- package/lib/app/services/storage/DiskStorageAdapter.d.ts +62 -0
- package/lib/app/services/storage/DiskStorageAdapter.d.ts.map +1 -0
- package/lib/app/services/storage/DiskStorageAdapter.js +295 -0
- package/lib/app/services/storage/DiskStorageAdapter.js.map +1 -0
- package/lib/app/services/storage/GCSStorageAdapter.d.ts +44 -0
- package/lib/app/services/storage/GCSStorageAdapter.d.ts.map +1 -0
- package/lib/app/services/storage/GCSStorageAdapter.js +133 -0
- package/lib/app/services/storage/GCSStorageAdapter.js.map +1 -0
- package/lib/app/services/storage/S3StorageAdapter.d.ts +57 -0
- package/lib/app/services/storage/S3StorageAdapter.d.ts.map +1 -0
- package/lib/app/services/storage/S3StorageAdapter.js +162 -0
- package/lib/app/services/storage/S3StorageAdapter.js.map +1 -0
- package/lib/app/services/storage/StorageService.d.ts +88 -0
- package/lib/app/services/storage/StorageService.d.ts.map +1 -0
- package/lib/app/services/storage/StorageService.js +18 -0
- package/lib/app/services/storage/StorageService.js.map +1 -0
- package/lib/app/services/storage/index.d.ts +5 -0
- package/lib/app/services/storage/index.d.ts.map +1 -0
- package/lib/app/services/storage/index.js +4 -0
- package/lib/app/services/storage/index.js.map +1 -0
- package/lib/app/utils/ContextValidators.d.ts +46 -0
- package/lib/app/utils/ContextValidators.d.ts.map +1 -0
- package/lib/app/utils/ContextValidators.js +81 -0
- package/lib/app/utils/ContextValidators.js.map +1 -0
- package/lib/app/utils/defineEnv.d.ts +80 -0
- package/lib/app/utils/defineEnv.d.ts.map +1 -0
- package/lib/app/utils/defineEnv.js +95 -0
- package/lib/app/utils/defineEnv.js.map +1 -0
- package/lib/client.d.ts +139 -0
- package/lib/client.d.ts.map +1 -0
- package/lib/client.js +98 -0
- package/lib/client.js.map +1 -0
- package/lib/contract/application.d.ts +3 -0
- package/lib/contract/application.d.ts.map +1 -0
- package/lib/contract/application.js +2 -0
- package/lib/contract/application.js.map +1 -0
- package/lib/contract/client.d.ts +3 -0
- package/lib/contract/client.d.ts.map +1 -0
- package/lib/contract/client.js +3 -0
- package/lib/contract/client.js.map +1 -0
- package/lib/contract/index.d.ts +3 -0
- package/lib/contract/index.d.ts.map +1 -0
- package/lib/contract/index.js +3 -0
- package/lib/contract/index.js.map +1 -0
- package/lib/contract/manifest.d.ts +3 -0
- package/lib/contract/manifest.d.ts.map +1 -0
- package/lib/contract/manifest.js +2 -0
- package/lib/contract/manifest.js.map +1 -0
- package/lib/contract/openapi.d.ts +3 -0
- package/lib/contract/openapi.d.ts.map +1 -0
- package/lib/contract/openapi.js +3 -0
- package/lib/contract/openapi.js.map +1 -0
- package/lib/contract/project.d.ts +3 -0
- package/lib/contract/project.d.ts.map +1 -0
- package/lib/contract/project.js +3 -0
- package/lib/contract/project.js.map +1 -0
- package/lib/contract/schema.d.ts +3 -0
- package/lib/contract/schema.d.ts.map +1 -0
- package/lib/contract/schema.js +3 -0
- package/lib/contract/schema.js.map +1 -0
- package/lib/drizzle/index.d.ts +3 -0
- package/lib/drizzle/index.d.ts.map +1 -0
- package/lib/drizzle/index.js +3 -0
- package/lib/drizzle/index.js.map +1 -0
- package/lib/hono/auth.d.ts +6 -0
- package/lib/hono/auth.d.ts.map +1 -0
- package/lib/hono/auth.js +54 -0
- package/lib/hono/auth.js.map +1 -0
- package/lib/hono/index.d.ts +4 -0
- package/lib/hono/index.d.ts.map +1 -0
- package/lib/hono/index.js +4 -0
- package/lib/hono/index.js.map +1 -0
- package/lib/http/app/createApp.d.ts +132 -0
- package/lib/http/app/createApp.d.ts.map +1 -0
- package/lib/http/app/createApp.js +215 -0
- package/lib/http/app/createApp.js.map +1 -0
- package/lib/http/app/devRoutes.d.ts +31 -0
- package/lib/http/app/devRoutes.d.ts.map +1 -0
- package/lib/http/app/devRoutes.js +145 -0
- package/lib/http/app/devRoutes.js.map +1 -0
- package/lib/http/app/errors.d.ts +45 -0
- package/lib/http/app/errors.d.ts.map +1 -0
- package/lib/http/app/errors.js +93 -0
- package/lib/http/app/errors.js.map +1 -0
- package/lib/http/app/health.d.ts +66 -0
- package/lib/http/app/health.d.ts.map +1 -0
- package/lib/http/app/health.js +104 -0
- package/lib/http/app/health.js.map +1 -0
- package/lib/http/errors/AppError.d.ts +10 -0
- package/lib/http/errors/AppError.d.ts.map +1 -0
- package/lib/http/errors/AppError.js +19 -0
- package/lib/http/errors/AppError.js.map +1 -0
- package/lib/http/errors/AuthenticationError.d.ts +8 -0
- package/lib/http/errors/AuthenticationError.d.ts.map +1 -0
- package/lib/http/errors/AuthenticationError.js +10 -0
- package/lib/http/errors/AuthenticationError.js.map +1 -0
- package/lib/http/errors/AuthorizationError.d.ts +8 -0
- package/lib/http/errors/AuthorizationError.d.ts.map +1 -0
- package/lib/http/errors/AuthorizationError.js +10 -0
- package/lib/http/errors/AuthorizationError.js.map +1 -0
- package/lib/http/errors/BadRequestError.d.ts +8 -0
- package/lib/http/errors/BadRequestError.d.ts.map +1 -0
- package/lib/http/errors/BadRequestError.js +10 -0
- package/lib/http/errors/BadRequestError.js.map +1 -0
- package/lib/http/errors/ConflictError.d.ts +8 -0
- package/lib/http/errors/ConflictError.d.ts.map +1 -0
- package/lib/http/errors/ConflictError.js +10 -0
- package/lib/http/errors/ConflictError.js.map +1 -0
- package/lib/http/errors/InternalServerError.d.ts +8 -0
- package/lib/http/errors/InternalServerError.d.ts.map +1 -0
- package/lib/http/errors/InternalServerError.js +10 -0
- package/lib/http/errors/InternalServerError.js.map +1 -0
- package/lib/http/errors/NotFoundError.d.ts +8 -0
- package/lib/http/errors/NotFoundError.d.ts.map +1 -0
- package/lib/http/errors/NotFoundError.js +10 -0
- package/lib/http/errors/NotFoundError.js.map +1 -0
- package/lib/http/errors/RateLimitError.d.ts +13 -0
- package/lib/http/errors/RateLimitError.d.ts.map +1 -0
- package/lib/http/errors/RateLimitError.js +16 -0
- package/lib/http/errors/RateLimitError.js.map +1 -0
- package/lib/http/errors/ServiceUnavailableError.d.ts +8 -0
- package/lib/http/errors/ServiceUnavailableError.d.ts.map +1 -0
- package/lib/http/errors/ServiceUnavailableError.js +10 -0
- package/lib/http/errors/ServiceUnavailableError.js.map +1 -0
- package/lib/http/errors/ValidationError.d.ts +9 -0
- package/lib/http/errors/ValidationError.d.ts.map +1 -0
- package/lib/http/errors/ValidationError.js +12 -0
- package/lib/http/errors/ValidationError.js.map +1 -0
- package/lib/http/errors/index.d.ts +11 -0
- package/lib/http/errors/index.d.ts.map +1 -0
- package/lib/http/errors/index.js +12 -0
- package/lib/http/errors/index.js.map +1 -0
- package/lib/http/middleware/apiKey.d.ts +9 -0
- package/lib/http/middleware/apiKey.d.ts.map +1 -0
- package/lib/http/middleware/apiKey.js +71 -0
- package/lib/http/middleware/apiKey.js.map +1 -0
- package/lib/http/middleware/csrf.d.ts +63 -0
- package/lib/http/middleware/csrf.d.ts.map +1 -0
- package/lib/http/middleware/csrf.js +169 -0
- package/lib/http/middleware/csrf.js.map +1 -0
- package/lib/http/middleware/httpLogger.d.ts +39 -0
- package/lib/http/middleware/httpLogger.d.ts.map +1 -0
- package/lib/http/middleware/httpLogger.js +118 -0
- package/lib/http/middleware/httpLogger.js.map +1 -0
- package/lib/http/middleware/idempotency.d.ts +48 -0
- package/lib/http/middleware/idempotency.d.ts.map +1 -0
- package/lib/http/middleware/idempotency.js +180 -0
- package/lib/http/middleware/idempotency.js.map +1 -0
- package/lib/http/middleware/rateLimit.d.ts +105 -0
- package/lib/http/middleware/rateLimit.d.ts.map +1 -0
- package/lib/http/middleware/rateLimit.js +84 -0
- package/lib/http/middleware/rateLimit.js.map +1 -0
- package/lib/http/middleware/requireAuth.d.ts +58 -0
- package/lib/http/middleware/requireAuth.d.ts.map +1 -0
- package/lib/http/middleware/requireAuth.js +63 -0
- package/lib/http/middleware/requireAuth.js.map +1 -0
- package/lib/http/middleware/requirePermission.d.ts +23 -0
- package/lib/http/middleware/requirePermission.d.ts.map +1 -0
- package/lib/http/middleware/requirePermission.js +50 -0
- package/lib/http/middleware/requirePermission.js.map +1 -0
- package/lib/http/middleware/resolveTenant.d.ts +41 -0
- package/lib/http/middleware/resolveTenant.d.ts.map +1 -0
- package/lib/http/middleware/resolveTenant.js +17 -0
- package/lib/http/middleware/resolveTenant.js.map +1 -0
- package/lib/http/streaming/sse.d.ts +31 -0
- package/lib/http/streaming/sse.d.ts.map +1 -0
- package/lib/http/streaming/sse.js +11 -0
- package/lib/http/streaming/sse.js.map +1 -0
- package/lib/http/streaming/streamLLM.d.ts +94 -0
- package/lib/http/streaming/streamLLM.d.ts.map +1 -0
- package/lib/http/streaming/streamLLM.js +94 -0
- package/lib/http/streaming/streamLLM.js.map +1 -0
- package/lib/http/utils/authCookies.d.ts +74 -0
- package/lib/http/utils/authCookies.d.ts.map +1 -0
- package/lib/http/utils/authCookies.js +102 -0
- package/lib/http/utils/authCookies.js.map +1 -0
- package/lib/http/utils/clientIp.d.ts +85 -0
- package/lib/http/utils/clientIp.d.ts.map +1 -0
- package/lib/http/utils/clientIp.js +249 -0
- package/lib/http/utils/clientIp.js.map +1 -0
- package/lib/http/utils/index.d.ts +4 -0
- package/lib/http/utils/index.d.ts.map +1 -0
- package/lib/http/utils/index.js +5 -0
- package/lib/http/utils/index.js.map +1 -0
- package/lib/http/utils/metaTags.d.ts +49 -0
- package/lib/http/utils/metaTags.d.ts.map +1 -0
- package/lib/http/utils/metaTags.js +32 -0
- package/lib/http/utils/metaTags.js.map +1 -0
- package/lib/http/utils/publicSuffix.d.ts +34 -0
- package/lib/http/utils/publicSuffix.d.ts.map +1 -0
- package/lib/http/utils/publicSuffix.js +276 -0
- package/lib/http/utils/publicSuffix.js.map +1 -0
- package/lib/http/utils/uploads.d.ts +92 -0
- package/lib/http/utils/uploads.d.ts.map +1 -0
- package/lib/http/utils/uploads.js +126 -0
- package/lib/http/utils/uploads.js.map +1 -0
- package/lib/http/utils/validate.d.ts +41 -0
- package/lib/http/utils/validate.d.ts.map +1 -0
- package/lib/http/utils/validate.js +55 -0
- package/lib/http/utils/validate.js.map +1 -0
- package/lib/http/utils/webhooks.d.ts +63 -0
- package/lib/http/utils/webhooks.d.ts.map +1 -0
- package/lib/http/utils/webhooks.js +133 -0
- package/lib/http/utils/webhooks.js.map +1 -0
- package/lib/http/ws/auth.d.ts +46 -0
- package/lib/http/ws/auth.d.ts.map +1 -0
- package/lib/http/ws/auth.js +123 -0
- package/lib/http/ws/auth.js.map +1 -0
- package/lib/index.d.ts +80 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +61 -0
- package/lib/index.js.map +1 -0
- package/lib/kernel/index.d.ts +3 -0
- package/lib/kernel/index.d.ts.map +1 -0
- package/lib/kernel/index.js +3 -0
- package/lib/kernel/index.js.map +1 -0
- package/lib/libraries/.gitkeep +0 -0
- package/lib/libraries/ai/CHANGELOG.md +17 -0
- package/lib/libraries/ai/README.md +164 -0
- package/lib/libraries/ai/adapters/AnthropicAdapter.ts +382 -0
- package/lib/libraries/ai/adapters/LLMProvider.ts +76 -0
- package/lib/libraries/ai/adapters/OpenAIAdapter.ts +466 -0
- package/lib/libraries/ai/experimental/index.ts +20 -0
- package/lib/libraries/ai/index.ts +128 -0
- package/lib/libraries/ai/library.json +19 -0
- package/lib/libraries/ai/loop/agentLoop.ts +377 -0
- package/lib/libraries/ai/prompts/definePrompt.ts +0 -0
- package/lib/libraries/ai/rag/retrieveAndAnswer.ts +177 -0
- package/lib/libraries/ai/streaming/streamLLM.ts +94 -0
- package/lib/libraries/ai/structured/completeStructured.ts +143 -0
- package/lib/libraries/ai/tokens/Tokenizer.ts +216 -0
- package/lib/libraries/ai/tools/defineTool.ts +208 -0
- package/lib/libraries/ai/types.ts +260 -0
- package/lib/libraries/chunking/ChunkingService.ts +103 -0
- package/lib/libraries/chunking/README.md +104 -0
- package/lib/libraries/chunking/docs/api-reference.md +549 -0
- package/lib/libraries/chunking/docs/best-practices.md +321 -0
- package/lib/libraries/chunking/docs/code-organization.md +538 -0
- package/lib/libraries/chunking/docs/configuration.md +418 -0
- package/lib/libraries/chunking/docs/index.md +236 -0
- package/lib/libraries/chunking/docs/quick-start.md +298 -0
- package/lib/libraries/chunking/docs/strategies.md +407 -0
- package/lib/libraries/chunking/docs/summary.md +258 -0
- package/lib/libraries/chunking/docs/troubleshooting.md +527 -0
- package/lib/libraries/chunking/index.ts +17 -0
- package/lib/libraries/chunking/library.json +16 -0
- package/lib/libraries/chunking/strategies/ChunkingStrategy.ts +13 -0
- package/lib/libraries/chunking/strategies/FixedLengthChunkingStrategy.ts +88 -0
- package/lib/libraries/chunking/strategies/SemanticChunkingStrategy.ts +389 -0
- package/lib/libraries/chunking/strategies/SlidingWindowChunkingStrategy.ts +258 -0
- package/lib/libraries/chunking/types/index.ts +63 -0
- package/lib/libraries/email/EmailService.ts +591 -0
- package/lib/libraries/email/README.md +777 -0
- package/lib/libraries/email/TemplateRegistry.ts +148 -0
- package/lib/libraries/email/TemplateRenderer.ts +273 -0
- package/lib/libraries/email/index.ts +4 -0
- package/lib/libraries/email/initializeEmailService.ts +60 -0
- package/lib/libraries/email/library.json +12 -0
- package/lib/libraries/email/types/EmailAddress.ts +4 -0
- package/lib/libraries/email/types/EmailAttachment.ts +11 -0
- package/lib/libraries/email/types/EmailTag.ts +9 -0
- package/lib/libraries/email/types/EmailTemplate.ts +124 -0
- package/lib/libraries/email/types/SendBatchEmailsOptions.ts +9 -0
- package/lib/libraries/email/types/SendBatchEmailsResult.ts +9 -0
- package/lib/libraries/email/types/SendEmailOptions.ts +33 -0
- package/lib/libraries/email/types/SendEmailResult.ts +9 -0
- package/lib/libraries/email/types/index.ts +8 -0
- package/lib/libraries/weaviate/QueryBuilder.ts +292 -0
- package/lib/libraries/weaviate/README.md +284 -0
- package/lib/libraries/weaviate/Weaviate.ts +1419 -0
- package/lib/libraries/weaviate/WeaviateConfig.ts +268 -0
- package/lib/libraries/weaviate/docs/.gitkeep +1 -0
- package/lib/libraries/weaviate/docs/API_REFERENCE.md +1067 -0
- package/lib/libraries/weaviate/docs/CONFIGURATION.md +320 -0
- package/lib/libraries/weaviate/docs/ERROR_HANDLING.md +271 -0
- package/lib/libraries/weaviate/docs/MULTI_TENANCY.md +348 -0
- package/lib/libraries/weaviate/docs/PERFORMANCE.md +602 -0
- package/lib/libraries/weaviate/docs/PLUGIN_DEVELOPMENT.md +547 -0
- package/lib/libraries/weaviate/docs/QUICK_START.md +443 -0
- package/lib/libraries/weaviate/docs/README.md +269 -0
- package/lib/libraries/weaviate/docs/SCHEMA_GUIDE.md +630 -0
- package/lib/libraries/weaviate/docs/WEAVIATE_README.md +520 -0
- package/lib/libraries/weaviate/errors/WeaviateError.ts +92 -0
- package/lib/libraries/weaviate/errors/index.ts +1 -0
- package/lib/libraries/weaviate/index.ts +35 -0
- package/lib/libraries/weaviate/library.json +26 -0
- package/lib/libraries/weaviate/plugins/index.ts +2 -0
- package/lib/libraries/weaviate/schemas/SchemaRegistry.ts +284 -0
- package/lib/libraries/weaviate/schemas/index.ts +2 -0
- package/lib/libraries/weaviate/types/BM25SearchOptions.ts +9 -0
- package/lib/libraries/weaviate/types/ExtendedWeaviateClient.ts +7 -0
- package/lib/libraries/weaviate/types/HybridSearchOptions.ts +11 -0
- package/lib/libraries/weaviate/types/MultiTenancy.ts +81 -0
- package/lib/libraries/weaviate/types/Plugin.ts +17 -0
- package/lib/libraries/weaviate/types/SchemaConfig.ts +25 -0
- package/lib/libraries/weaviate/types/SearchMethod.ts +8 -0
- package/lib/libraries/weaviate/types/SearchOptions.ts +16 -0
- package/lib/libraries/weaviate/types/SearchRequest.ts +19 -0
- package/lib/libraries/weaviate/types/SearchResult.ts +16 -0
- package/lib/libraries/weaviate/types/SearchableField.ts +87 -0
- package/lib/libraries/weaviate/types/VectorIndexConfig.ts +19 -0
- package/lib/libraries/weaviate/types/VectorSearchOptions.ts +18 -0
- package/lib/libraries/weaviate/types/VectorizerConfig.ts +8 -0
- package/lib/libraries/weaviate/types/index.ts +29 -0
- package/lib/libraries/weaviate/utils/TenantContextManager.ts +94 -0
- package/lib/modules/accounts/index.ts +47 -0
- package/lib/modules/accounts/module.json +15 -0
- package/lib/modules/accounts/permissions.ts +33 -0
- package/lib/modules/accounts/routes.ts +200 -0
- package/lib/modules/accounts/schema.ts +219 -0
- package/lib/modules/accounts/services/AccountService.ts +44 -0
- package/lib/modules/accounts/validation/schemas.ts +70 -0
- package/lib/modules/oauth/adapters/GmailOAuthAdapter.ts +35 -0
- package/lib/modules/oauth/adapters/GoogleOAuthAdapter.ts +278 -0
- package/lib/modules/oauth/adapters/MicrosoftOAuthAdapter.ts +269 -0
- package/lib/modules/oauth/adapters/MockOAuthAdapter.ts +138 -0
- package/lib/modules/oauth/adapters/OAuthAdapter.ts +211 -0
- package/lib/modules/oauth/adapters/OAuthAdapterRegistry.ts +77 -0
- package/lib/modules/oauth/adapters/OutlookOAuthAdapter.ts +38 -0
- package/lib/modules/oauth/index.ts +79 -0
- package/lib/modules/oauth/module.json +23 -0
- package/lib/modules/oauth/permissions.ts +39 -0
- package/lib/modules/oauth/routes.ts +497 -0
- package/lib/modules/oauth/schema.ts +127 -0
- package/lib/modules/oauth/services/OAuthConnectionService.ts +147 -0
- package/lib/modules/oauth/state.ts +234 -0
- package/lib/modules/oauth/stateJtiCache.ts +85 -0
- package/lib/modules/oauth/verifyIdToken.ts +178 -0
- package/lib/modules/outbox/EventEmitter.ts +106 -0
- package/lib/modules/outbox/OutboxDrainer.ts +163 -0
- package/lib/modules/outbox/handlers/EventHandler.ts +115 -0
- package/lib/modules/outbox/index.ts +43 -0
- package/lib/modules/outbox/module.json +15 -0
- package/lib/modules/outbox/permissions.ts +36 -0
- package/lib/modules/outbox/routes.ts +219 -0
- package/lib/modules/outbox/schema.ts +207 -0
- package/lib/modules/outbox/services/OutboxEventService.ts +223 -0
- package/lib/observability/logger.d.ts +30 -0
- package/lib/observability/logger.d.ts.map +1 -0
- package/lib/observability/logger.js +110 -0
- package/lib/observability/logger.js.map +1 -0
- package/lib/observability/metrics.d.ts +3 -0
- package/lib/observability/metrics.d.ts.map +1 -0
- package/lib/observability/metrics.js +3 -0
- package/lib/observability/metrics.js.map +1 -0
- package/lib/observability/otel.d.ts +3 -0
- package/lib/observability/otel.d.ts.map +1 -0
- package/lib/observability/otel.js +3 -0
- package/lib/observability/otel.js.map +1 -0
- package/lib/observability/safeErrorFields.d.ts +14 -0
- package/lib/observability/safeErrorFields.d.ts.map +1 -0
- package/lib/observability/safeErrorFields.js +14 -0
- package/lib/observability/safeErrorFields.js.map +1 -0
- package/lib/observability/tracing.d.ts +3 -0
- package/lib/observability/tracing.d.ts.map +1 -0
- package/lib/observability/tracing.js +3 -0
- package/lib/observability/tracing.js.map +1 -0
- package/lib/package.json +4 -0
- package/lib/testing.d.ts +3 -0
- package/lib/testing.d.ts.map +1 -0
- package/lib/testing.js +3 -0
- package/lib/testing.js.map +1 -0
- package/package.json +193 -3
- package/templates/default/.claude/agents/qa-brief.md +106 -0
- package/templates/default/.claude/commands/sherpa-brief.md +23 -0
- package/templates/default/.cursor/rules/api.mdc +80 -0
- package/templates/default/.cursor/rules/commits.mdc +88 -0
- package/templates/default/.cursor/rules/security.mdc +92 -0
- package/templates/default/.cursor/rules/testing.mdc +123 -0
- package/templates/default/.cursor/rules/typescript.mdc +86 -0
- package/templates/default/.env.example +79 -0
- package/templates/default/.github/workflows/sherpa-brief.yml +180 -0
- package/templates/default/AGENTS.md +166 -0
- package/templates/default/CLAUDE.md +17 -0
- package/templates/default/README.md +97 -0
- package/templates/default/_gitignore +27 -0
- package/templates/default/docker-compose.yml +83 -0
- package/templates/default/drizzle.config.ts +34 -0
- package/templates/default/eslint.config.mjs +106 -0
- package/templates/default/package.json +57 -0
- package/templates/default/ship-api.config.ts +21 -0
- package/templates/default/src/client.ts +34 -0
- package/templates/default/src/config/modules.ts +23 -0
- package/templates/default/src/db/schema.ts +26 -0
- package/templates/default/src/environment.ts +81 -0
- package/templates/default/src/index.test.ts +53 -0
- package/templates/default/src/index.ts +11 -0
- package/templates/default/src/instrumentation.ts +13 -0
- package/templates/default/src/server.ts +90 -0
- package/templates/default/tsconfig.json +24 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pluggable health-check primitive.
|
|
3
|
+
*
|
|
4
|
+
* The framework exposes two HTTP endpoints (`/livez` and `/readyz`) backed
|
|
5
|
+
* by a `HealthCheckRegistry`:
|
|
6
|
+
*
|
|
7
|
+
* - `/livez` — process is up. Always 200 with no checks. Used by load
|
|
8
|
+
* balancers / orchestrators to decide "should I restart this pod?"
|
|
9
|
+
* - `/readyz` — runs every registered check. 200 if all pass; 503 with
|
|
10
|
+
* a structured `{ checks: [...] }` body otherwise. Used to decide
|
|
11
|
+
* "should I send traffic to this pod?"
|
|
12
|
+
*
|
|
13
|
+
* `createApp()` mounts both routes by default (see `http/app/health.ts`).
|
|
14
|
+
* Modules / consumer code register checks via `healthCheckRegistry.add(...)`.
|
|
15
|
+
* Built-in checks: `createDb()` registers a `db.primary` check on its pool by
|
|
16
|
+
* default; `redisHealthCheck(provider)` is a factory you add yourself.
|
|
17
|
+
*
|
|
18
|
+
* Duplicate names: the first registration of a name wins and later ones are
|
|
19
|
+
* skipped (logged), except that a check added with `{ replaceable: true }`
|
|
20
|
+
* (what framework defaults such as `createDb`'s `db.primary` use) gives way
|
|
21
|
+
* to a later explicit registration of the same name. So a consumer that
|
|
22
|
+
* registers its own `db.primary` after `createDb()` gets exactly one check:
|
|
23
|
+
* its own.
|
|
24
|
+
*/
|
|
25
|
+
import { logger } from "../../observability/logger.js";
|
|
26
|
+
/**
|
|
27
|
+
* Container for registered checks. One framework-wide singleton (below);
|
|
28
|
+
* tests construct their own via `new HealthCheckRegistry()`.
|
|
29
|
+
*/
|
|
30
|
+
export class HealthCheckRegistry {
|
|
31
|
+
checks = [];
|
|
32
|
+
replaceable = new Set();
|
|
33
|
+
/**
|
|
34
|
+
* Register a check. Returns `true` when the check is now registered,
|
|
35
|
+
* `false` when it was skipped because a check of that name already exists.
|
|
36
|
+
*
|
|
37
|
+
* Duplicate names never throw and never run twice:
|
|
38
|
+
* - existing check is `replaceable` and the new one is not → the new
|
|
39
|
+
* check replaces it (debug log);
|
|
40
|
+
* - otherwise the existing check wins and the new one is skipped (debug
|
|
41
|
+
* log when either side is `replaceable`, warn log when both are
|
|
42
|
+
* explicit registrations, since that is usually a consumer bug).
|
|
43
|
+
*/
|
|
44
|
+
add(check, opts = {}) {
|
|
45
|
+
const index = this.checks.findIndex((c) => c.name === check.name);
|
|
46
|
+
if (index === -1) {
|
|
47
|
+
this.checks.push(check);
|
|
48
|
+
if (opts.replaceable)
|
|
49
|
+
this.replaceable.add(check);
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
const existing = this.checks[index];
|
|
53
|
+
const existingReplaceable = this.replaceable.has(existing);
|
|
54
|
+
if (existingReplaceable && !opts.replaceable) {
|
|
55
|
+
this.replaceable.delete(existing);
|
|
56
|
+
this.checks[index] = check;
|
|
57
|
+
logger.debug({ check: check.name }, "Health check replaced the framework default registered under the same name");
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
const message = "Health check with this name is already registered; keeping the first one";
|
|
61
|
+
if (existingReplaceable || opts.replaceable)
|
|
62
|
+
logger.debug({ check: check.name }, message);
|
|
63
|
+
else
|
|
64
|
+
logger.warn({ check: check.name }, message);
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
/** Test / admin helper. */
|
|
68
|
+
remove(name) {
|
|
69
|
+
const before = this.checks.length;
|
|
70
|
+
this.checks = this.checks.filter((c) => {
|
|
71
|
+
if (c.name !== name)
|
|
72
|
+
return true;
|
|
73
|
+
this.replaceable.delete(c);
|
|
74
|
+
return false;
|
|
75
|
+
});
|
|
76
|
+
return this.checks.length < before;
|
|
77
|
+
}
|
|
78
|
+
list() {
|
|
79
|
+
return [...this.checks];
|
|
80
|
+
}
|
|
81
|
+
size() {
|
|
82
|
+
return this.checks.length;
|
|
83
|
+
}
|
|
84
|
+
clear() {
|
|
85
|
+
this.checks = [];
|
|
86
|
+
this.replaceable.clear();
|
|
87
|
+
}
|
|
88
|
+
async runAll(opts = {}) {
|
|
89
|
+
const timeoutMs = opts.timeoutMs ?? 3_000;
|
|
90
|
+
const reportFailure = (failure) => {
|
|
91
|
+
try {
|
|
92
|
+
opts.onCheckFailure?.(failure);
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// A logging callback must never break readiness reporting.
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const results = await Promise.all(this.checks.map(async (check) => {
|
|
99
|
+
const start = performance.now();
|
|
100
|
+
let ok = true;
|
|
101
|
+
let error;
|
|
102
|
+
let details;
|
|
103
|
+
let timer;
|
|
104
|
+
const timedOut = Symbol("timeout");
|
|
105
|
+
try {
|
|
106
|
+
const result = await Promise.race([
|
|
107
|
+
Promise.resolve(check.check()),
|
|
108
|
+
new Promise((resolve) => {
|
|
109
|
+
timer = setTimeout(() => resolve(timedOut), timeoutMs);
|
|
110
|
+
}),
|
|
111
|
+
]);
|
|
112
|
+
if (result === timedOut) {
|
|
113
|
+
ok = false;
|
|
114
|
+
error = "timeout";
|
|
115
|
+
reportFailure({ name: check.name, error: new Error("timeout"), timedOut: true });
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
ok = result.ok;
|
|
119
|
+
error = result.error;
|
|
120
|
+
details = result.details;
|
|
121
|
+
if (!ok) {
|
|
122
|
+
reportFailure({
|
|
123
|
+
name: check.name,
|
|
124
|
+
error: result.error,
|
|
125
|
+
timedOut: false,
|
|
126
|
+
...(typeof result.error === "string" ? { reason: result.error } : {}),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
ok = false;
|
|
133
|
+
error = err instanceof Error ? err.message : String(err);
|
|
134
|
+
reportFailure({ name: check.name, error: err, timedOut: false });
|
|
135
|
+
}
|
|
136
|
+
finally {
|
|
137
|
+
if (timer !== undefined)
|
|
138
|
+
clearTimeout(timer);
|
|
139
|
+
}
|
|
140
|
+
const latencyMs = Math.round(performance.now() - start);
|
|
141
|
+
return { name: check.name, ok, latencyMs, error, details };
|
|
142
|
+
}));
|
|
143
|
+
return {
|
|
144
|
+
ok: results.every((r) => r.ok),
|
|
145
|
+
checks: results,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/** Framework-wide registry. Bootstrappers / modules add checks here. */
|
|
150
|
+
export const healthCheckRegistry = new HealthCheckRegistry();
|
|
151
|
+
//# sourceMappingURL=HealthCheck.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HealthCheck.js","sourceRoot":"","sources":["../../../src/app/health/HealthCheck.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { RedisProvider } from "../services/RedisProvider.js";
|
|
2
|
+
import type { HealthCheck } from "./HealthCheck.js";
|
|
3
|
+
/**
|
|
4
|
+
* Built-in health check that pings a `RedisProvider`.
|
|
5
|
+
*
|
|
6
|
+
* Returned by a factory rather than a class so consumers can register it
|
|
7
|
+
* declaratively without a `new`. The `check()` call uses
|
|
8
|
+
* `RedisProvider.ping()`, which never throws — it returns `false` on
|
|
9
|
+
* failure. We surface that as `ok: false` with `error: "ping failed"`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function redisHealthCheck(provider: RedisProvider, opts?: {
|
|
12
|
+
name?: string;
|
|
13
|
+
}): HealthCheck;
|
|
14
|
+
//# sourceMappingURL=redisHealthCheck.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redisHealthCheck.d.ts","sourceRoot":"","sources":["../../../src/app/health/redisHealthCheck.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAqB,MAAM,kBAAkB,CAAC;AAEvE;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,aAAa,EACvB,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC3B,WAAW,CAWb"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in health check that pings a `RedisProvider`.
|
|
3
|
+
*
|
|
4
|
+
* Returned by a factory rather than a class so consumers can register it
|
|
5
|
+
* declaratively without a `new`. The `check()` call uses
|
|
6
|
+
* `RedisProvider.ping()`, which never throws — it returns `false` on
|
|
7
|
+
* failure. We surface that as `ok: false` with `error: "ping failed"`.
|
|
8
|
+
*/
|
|
9
|
+
export function redisHealthCheck(provider, opts = {}) {
|
|
10
|
+
const name = opts.name ?? "redis";
|
|
11
|
+
return {
|
|
12
|
+
name,
|
|
13
|
+
async check() {
|
|
14
|
+
const start = performance.now();
|
|
15
|
+
const ok = await provider.ping();
|
|
16
|
+
const latencyMs = Math.round(performance.now() - start);
|
|
17
|
+
return ok ? { ok: true, latencyMs } : { ok: false, latencyMs, error: "ping failed" };
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=redisHealthCheck.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redisHealthCheck.js","sourceRoot":"","sources":["../../../src/app/health/redisHealthCheck.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAAuB,EACvB,OAA0B,EAAE;IAE5B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC;IAClC,OAAO;QACL,IAAI;QACJ,KAAK,CAAC,KAAK;YACT,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAChC,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACjC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC;YACxD,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;QACvF,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v4 `Bootstrapper` contract — formalizes the order in which app-init steps
|
|
3
|
+
* run. Replaces v3's "ordered array of `BootstrapperImplementation`s"
|
|
4
|
+
* pattern with a priority-and-dependsOn graph that the framework validates
|
|
5
|
+
* at boot.
|
|
6
|
+
*
|
|
7
|
+
* Each bootstrapper declares:
|
|
8
|
+
* - `name`: stable identifier (referenced by other bootstrappers' `dependsOn`)
|
|
9
|
+
* - `priority`: numeric — lower runs first; ties resolve by registration order
|
|
10
|
+
* - `dependsOn?`: optional list of bootstrapper names that MUST run earlier
|
|
11
|
+
* - `init(ctx)`: the actual work; receives a context object the framework supplies
|
|
12
|
+
*
|
|
13
|
+
* The plan's standard priorities (documented in the modernization plan):
|
|
14
|
+
*
|
|
15
|
+
* | Priority | Bootstrapper | Notes |
|
|
16
|
+
* |---------:|--------------------|---------------------------------------------|
|
|
17
|
+
* | 0 | InitObservability | OTel SDK shutdown registration |
|
|
18
|
+
* | 10 | InitFirebaseApp | Firebase Admin SDK init |
|
|
19
|
+
* | 20 | InitDatabase | Drizzle pool + db:migrate |
|
|
20
|
+
* | 30 | InitRedis | Redis connection + readiness |
|
|
21
|
+
* | 40 | InitMetricsServer | Prometheus port |
|
|
22
|
+
* | 50 | InitModules | Route registration |
|
|
23
|
+
* | 60 | InitJobs | Needs Redis + Modules |
|
|
24
|
+
* | 65 | InitCron | Needs Jobs (BullMQ repeatable) |
|
|
25
|
+
* | 85 | InitDevRoutes | `/dev/routes` HTML view; gated by env |
|
|
26
|
+
* | 90 | InitCustomRoutes | Downstream override hook |
|
|
27
|
+
* | 100 | InitCustomData | Last; seeds + custom init |
|
|
28
|
+
*
|
|
29
|
+
* Health routes are not a bootstrapper: `createApp()` mounts `/livez` and
|
|
30
|
+
* `/readyz` itself, and `createDb()` registers the `db.primary` check.
|
|
31
|
+
*
|
|
32
|
+
* Validation runs at boot. Misordered configs (a bootstrapper with
|
|
33
|
+
* `dependsOn: ["X"]` where X has higher priority, or X doesn't exist)
|
|
34
|
+
* throw at startup, not at first request — fail loudly, fail early.
|
|
35
|
+
*/
|
|
36
|
+
export interface BootstrapperContext {
|
|
37
|
+
/**
|
|
38
|
+
* Free-form bag the framework / consumers populate during boot. Each
|
|
39
|
+
* bootstrapper can read what earlier bootstrappers wrote and write its
|
|
40
|
+
* own outputs. Typed as `Record<string, unknown>` so the framework
|
|
41
|
+
* stays agnostic of which keys consumers add.
|
|
42
|
+
*
|
|
43
|
+
* Convention: each bootstrapper writes under a single key matching its
|
|
44
|
+
* function (e.g. InitDatabase writes `ctx.db`, InitRedis writes
|
|
45
|
+
* `ctx.redis`). The eventual App.ts narrows this to a typed view.
|
|
46
|
+
*/
|
|
47
|
+
[key: string]: unknown;
|
|
48
|
+
}
|
|
49
|
+
export interface Bootstrapper {
|
|
50
|
+
/** Stable name. Unique within a single boot. */
|
|
51
|
+
readonly name: string;
|
|
52
|
+
/** Lower priority runs first; ties resolve by registration order. */
|
|
53
|
+
readonly priority: number;
|
|
54
|
+
/** Names of bootstrappers that MUST run earlier. Validated at boot. */
|
|
55
|
+
readonly dependsOn?: readonly string[];
|
|
56
|
+
/** Run the init step. Throw to abort boot. */
|
|
57
|
+
init(ctx: BootstrapperContext): Promise<void> | void;
|
|
58
|
+
}
|
|
59
|
+
export declare class BootstrapperOrderingError extends Error {
|
|
60
|
+
constructor(message: string);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Validate the registration order:
|
|
64
|
+
* - No duplicate names
|
|
65
|
+
* - Every `dependsOn` reference resolves to a registered bootstrapper
|
|
66
|
+
* - Every `dependsOn` reference has strictly lower priority (ties not allowed —
|
|
67
|
+
* a bootstrapper depending on a same-priority peer is ambiguous)
|
|
68
|
+
*
|
|
69
|
+
* Throws `BootstrapperOrderingError` on the first violation.
|
|
70
|
+
*/
|
|
71
|
+
export declare function validateBootstrappers(bootstrappers: readonly Bootstrapper[]): void;
|
|
72
|
+
/**
|
|
73
|
+
* Sort bootstrappers by `priority` ascending, with ties resolved by
|
|
74
|
+
* original registration order (stable sort — `Array.prototype.sort` is
|
|
75
|
+
* stable in modern JS engines / TC39 spec).
|
|
76
|
+
*/
|
|
77
|
+
export declare function sortBootstrappers(bootstrappers: readonly Bootstrapper[]): Bootstrapper[];
|
|
78
|
+
export interface RunBootstrappersOptions {
|
|
79
|
+
/** Initial context. Bootstrappers mutate it as they run. */
|
|
80
|
+
context?: BootstrapperContext;
|
|
81
|
+
/**
|
|
82
|
+
* Skip the validation pass — useful only when the caller has already
|
|
83
|
+
* validated (e.g., during hot reload). Default false.
|
|
84
|
+
*/
|
|
85
|
+
skipValidation?: boolean;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Validate (unless skipped), sort, and run each bootstrapper sequentially.
|
|
89
|
+
* Returns the populated context. Throws on the first failed `init`.
|
|
90
|
+
*/
|
|
91
|
+
export declare function runBootstrappers(bootstrappers: readonly Bootstrapper[], opts?: RunBootstrappersOptions): Promise<BootstrapperContext>;
|
|
92
|
+
//# sourceMappingURL=Bootstrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Bootstrapper.d.ts","sourceRoot":"","sources":["../../../src/app/lifecycle/Bootstrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;;OASG;IACH,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,uEAAuE;IACvE,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,8CAA8C;IAC9C,IAAI,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACtD;AAED,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,SAAS,YAAY,EAAE,GAAG,IAAI,CAyBlF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,SAAS,YAAY,EAAE,GAAG,YAAY,EAAE,CAOxF;AAED,MAAM,WAAW,uBAAuB;IACtC,4DAA4D;IAC5D,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,aAAa,EAAE,SAAS,YAAY,EAAE,EACtC,IAAI,GAAE,uBAA4B,GACjC,OAAO,CAAC,mBAAmB,CAAC,CAQ9B"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v4 `Bootstrapper` contract — formalizes the order in which app-init steps
|
|
3
|
+
* run. Replaces v3's "ordered array of `BootstrapperImplementation`s"
|
|
4
|
+
* pattern with a priority-and-dependsOn graph that the framework validates
|
|
5
|
+
* at boot.
|
|
6
|
+
*
|
|
7
|
+
* Each bootstrapper declares:
|
|
8
|
+
* - `name`: stable identifier (referenced by other bootstrappers' `dependsOn`)
|
|
9
|
+
* - `priority`: numeric — lower runs first; ties resolve by registration order
|
|
10
|
+
* - `dependsOn?`: optional list of bootstrapper names that MUST run earlier
|
|
11
|
+
* - `init(ctx)`: the actual work; receives a context object the framework supplies
|
|
12
|
+
*
|
|
13
|
+
* The plan's standard priorities (documented in the modernization plan):
|
|
14
|
+
*
|
|
15
|
+
* | Priority | Bootstrapper | Notes |
|
|
16
|
+
* |---------:|--------------------|---------------------------------------------|
|
|
17
|
+
* | 0 | InitObservability | OTel SDK shutdown registration |
|
|
18
|
+
* | 10 | InitFirebaseApp | Firebase Admin SDK init |
|
|
19
|
+
* | 20 | InitDatabase | Drizzle pool + db:migrate |
|
|
20
|
+
* | 30 | InitRedis | Redis connection + readiness |
|
|
21
|
+
* | 40 | InitMetricsServer | Prometheus port |
|
|
22
|
+
* | 50 | InitModules | Route registration |
|
|
23
|
+
* | 60 | InitJobs | Needs Redis + Modules |
|
|
24
|
+
* | 65 | InitCron | Needs Jobs (BullMQ repeatable) |
|
|
25
|
+
* | 85 | InitDevRoutes | `/dev/routes` HTML view; gated by env |
|
|
26
|
+
* | 90 | InitCustomRoutes | Downstream override hook |
|
|
27
|
+
* | 100 | InitCustomData | Last; seeds + custom init |
|
|
28
|
+
*
|
|
29
|
+
* Health routes are not a bootstrapper: `createApp()` mounts `/livez` and
|
|
30
|
+
* `/readyz` itself, and `createDb()` registers the `db.primary` check.
|
|
31
|
+
*
|
|
32
|
+
* Validation runs at boot. Misordered configs (a bootstrapper with
|
|
33
|
+
* `dependsOn: ["X"]` where X has higher priority, or X doesn't exist)
|
|
34
|
+
* throw at startup, not at first request — fail loudly, fail early.
|
|
35
|
+
*/
|
|
36
|
+
export class BootstrapperOrderingError extends Error {
|
|
37
|
+
constructor(message) {
|
|
38
|
+
super(message);
|
|
39
|
+
this.name = "BootstrapperOrderingError";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Validate the registration order:
|
|
44
|
+
* - No duplicate names
|
|
45
|
+
* - Every `dependsOn` reference resolves to a registered bootstrapper
|
|
46
|
+
* - Every `dependsOn` reference has strictly lower priority (ties not allowed —
|
|
47
|
+
* a bootstrapper depending on a same-priority peer is ambiguous)
|
|
48
|
+
*
|
|
49
|
+
* Throws `BootstrapperOrderingError` on the first violation.
|
|
50
|
+
*/
|
|
51
|
+
export function validateBootstrappers(bootstrappers) {
|
|
52
|
+
const byName = new Map();
|
|
53
|
+
for (const b of bootstrappers) {
|
|
54
|
+
if (byName.has(b.name)) {
|
|
55
|
+
throw new BootstrapperOrderingError(`Duplicate bootstrapper name: "${b.name}"`);
|
|
56
|
+
}
|
|
57
|
+
byName.set(b.name, b);
|
|
58
|
+
}
|
|
59
|
+
for (const b of bootstrappers) {
|
|
60
|
+
for (const dep of b.dependsOn ?? []) {
|
|
61
|
+
const target = byName.get(dep);
|
|
62
|
+
if (!target) {
|
|
63
|
+
throw new BootstrapperOrderingError(`Bootstrapper "${b.name}" depends on "${dep}", which is not registered`);
|
|
64
|
+
}
|
|
65
|
+
if (target.priority >= b.priority) {
|
|
66
|
+
throw new BootstrapperOrderingError(`Bootstrapper "${b.name}" (priority ${b.priority}) depends on "${target.name}" ` +
|
|
67
|
+
`(priority ${target.priority}); dependencies must run strictly earlier`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Sort bootstrappers by `priority` ascending, with ties resolved by
|
|
74
|
+
* original registration order (stable sort — `Array.prototype.sort` is
|
|
75
|
+
* stable in modern JS engines / TC39 spec).
|
|
76
|
+
*/
|
|
77
|
+
export function sortBootstrappers(bootstrappers) {
|
|
78
|
+
// Pair with index so we can be explicit about tie-breaking even if the
|
|
79
|
+
// engine's sort weren't stable.
|
|
80
|
+
return bootstrappers
|
|
81
|
+
.map((b, i) => ({ b, i }))
|
|
82
|
+
.sort((a, b) => a.b.priority - b.b.priority || a.i - b.i)
|
|
83
|
+
.map((p) => p.b);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Validate (unless skipped), sort, and run each bootstrapper sequentially.
|
|
87
|
+
* Returns the populated context. Throws on the first failed `init`.
|
|
88
|
+
*/
|
|
89
|
+
export async function runBootstrappers(bootstrappers, opts = {}) {
|
|
90
|
+
if (!opts.skipValidation)
|
|
91
|
+
validateBootstrappers(bootstrappers);
|
|
92
|
+
const ordered = sortBootstrappers(bootstrappers);
|
|
93
|
+
const ctx = opts.context ?? {};
|
|
94
|
+
for (const b of ordered) {
|
|
95
|
+
await b.init(ctx);
|
|
96
|
+
}
|
|
97
|
+
return ctx;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=Bootstrapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Bootstrapper.js","sourceRoot":"","sources":["../../../src/app/lifecycle/Bootstrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AA2BH,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAClD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;IAC1C,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CAAC,aAAsC;IAC1E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC/C,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;QAC9B,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,yBAAyB,CAAC,iCAAiC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;QAClF,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;QAC9B,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,yBAAyB,CACjC,iBAAiB,CAAC,CAAC,IAAI,iBAAiB,GAAG,4BAA4B,CACxE,CAAC;YACJ,CAAC;YACD,IAAI,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAClC,MAAM,IAAI,yBAAyB,CACjC,iBAAiB,CAAC,CAAC,IAAI,eAAe,CAAC,CAAC,QAAQ,iBAAiB,MAAM,CAAC,IAAI,IAAI;oBAC9E,aAAa,MAAM,CAAC,QAAQ,2CAA2C,CAC1E,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,aAAsC;IACtE,uEAAuE;IACvE,gCAAgC;IAChC,OAAO,aAAa;SACjB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;SACzB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SACxD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrB,CAAC;AAYD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,aAAsC,EACtC,OAAgC,EAAE;IAElC,IAAI,CAAC,IAAI,CAAC,cAAc;QAAE,qBAAqB,CAAC,aAAa,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;IACjD,MAAM,GAAG,GAAwB,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IACpD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { ZodType } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Runtime route registry — load-bearing primitive for agent introspection.
|
|
4
|
+
*
|
|
5
|
+
* Replaces what OpenAPI was buying us in earlier plan drafts. For *agents*
|
|
6
|
+
* specifically this is more powerful than OpenAPI: we capture auth provider
|
|
7
|
+
* identity, permission slugs, rate-limit policy, idempotency, deprecation,
|
|
8
|
+
* and module ownership — none of which OpenAPI represents natively. And the
|
|
9
|
+
* registry stays live with the running code (no generation step, never stale).
|
|
10
|
+
*
|
|
11
|
+
* Populated by `createApp`'s route-method interceptors when consumer code
|
|
12
|
+
* calls `app.METHOD(path, ...handlers)`. The middleware factories
|
|
13
|
+
* (`validate`, `requireAuth`, `requirePermission`, `rateLimit`, `idempotency`)
|
|
14
|
+
* tag their returned handler via metaTags symbols; the interceptor walks the
|
|
15
|
+
* handler list and reads those tags to assemble a `RouteEntry`.
|
|
16
|
+
*
|
|
17
|
+
* Consumers:
|
|
18
|
+
* - MCP `list_routes` / `describe_route` / `find_route_collisions` /
|
|
19
|
+
* `execute_route` tools.
|
|
20
|
+
* - The `/dev/routes` HTML debug endpoint.
|
|
21
|
+
* - The `ship-reviewer` Claude plugin agent (convention enforcement).
|
|
22
|
+
* - `ship-api g doctor` (schema-less mutating routes flag, etc.).
|
|
23
|
+
* - v4.x OpenAPI compatibility layer (the OpenAPI generator reads from the
|
|
24
|
+
* same registry — no duplication, no two-source drift).
|
|
25
|
+
*/
|
|
26
|
+
export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS" | "HEAD";
|
|
27
|
+
export type RouteMethod = HttpMethod | "WS";
|
|
28
|
+
export interface RouteSchemas {
|
|
29
|
+
json?: ZodType;
|
|
30
|
+
query?: ZodType;
|
|
31
|
+
param?: ZodType;
|
|
32
|
+
header?: ZodType;
|
|
33
|
+
}
|
|
34
|
+
export interface RouteEntry {
|
|
35
|
+
method: RouteMethod;
|
|
36
|
+
path: string;
|
|
37
|
+
/** Module that registered this route (set by InitModules during discovery). */
|
|
38
|
+
module?: string;
|
|
39
|
+
auth: {
|
|
40
|
+
required: boolean;
|
|
41
|
+
provider?: string;
|
|
42
|
+
};
|
|
43
|
+
permissions: string[];
|
|
44
|
+
rateLimit?: {
|
|
45
|
+
windowMs: number;
|
|
46
|
+
max: number;
|
|
47
|
+
scope?: string;
|
|
48
|
+
};
|
|
49
|
+
idempotent?: boolean;
|
|
50
|
+
schemas: RouteSchemas;
|
|
51
|
+
description?: string;
|
|
52
|
+
tags?: string[];
|
|
53
|
+
deprecated?: boolean;
|
|
54
|
+
}
|
|
55
|
+
export interface RouteFilter {
|
|
56
|
+
method?: RouteMethod;
|
|
57
|
+
path?: string;
|
|
58
|
+
module?: string;
|
|
59
|
+
tag?: string;
|
|
60
|
+
}
|
|
61
|
+
export declare class RouteRegistry {
|
|
62
|
+
private entries;
|
|
63
|
+
/** Module currently being registered — set by InitModules so each captured
|
|
64
|
+
* route gets `module` populated. */
|
|
65
|
+
private currentModule;
|
|
66
|
+
/** Push a new entry. Called by `createApp`'s interceptors. */
|
|
67
|
+
add(entry: RouteEntry): void;
|
|
68
|
+
/** Run `fn` with `module` set so any routes registered inside are tagged. */
|
|
69
|
+
withModule<T>(name: string, fn: () => Promise<T> | T): Promise<T>;
|
|
70
|
+
/** All entries (defensively cloned). */
|
|
71
|
+
list(filter?: RouteFilter): RouteEntry[];
|
|
72
|
+
/** First entry matching `(method, path)` — exact path match. */
|
|
73
|
+
find(method: RouteMethod, path: string): RouteEntry | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* Find routes that would collide with a proposed `(method, path)`. Returns
|
|
76
|
+
* exact matches only (not param-pattern overlap — that's a separate
|
|
77
|
+
* route-tree concern). Empty array means safe to add.
|
|
78
|
+
*/
|
|
79
|
+
findCollisions(method: RouteMethod, path: string): RouteEntry[];
|
|
80
|
+
size(): number;
|
|
81
|
+
/** Remove all entries — primarily for tests. */
|
|
82
|
+
clear(): void;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Default framework-wide registry. `createApp` populates this. Tests should
|
|
86
|
+
* call `routeRegistry.clear()` in `afterEach` to avoid cross-test bleed.
|
|
87
|
+
*/
|
|
88
|
+
export declare const routeRegistry: RouteRegistry;
|
|
89
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/app/registry/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAE1F,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,IAAI,CAAC;AAE5C,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,YAAY,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAoB;IACnC;yCACqC;IACrC,OAAO,CAAC,aAAa,CAAqB;IAE1C,8DAA8D;IAC9D,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAQ5B,6EAA6E;IACvE,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAUvE,wCAAwC;IACxC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,UAAU,EAAE;IAIxC,gEAAgE;IAChE,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAK/D;;;;OAIG;IACH,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE;IAM/D,IAAI,IAAI,MAAM;IAId,gDAAgD;IAChD,KAAK,IAAI,IAAI;CAId;AAWD;;;GAGG;AACH,eAAO,MAAM,aAAa,eAAsB,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export class RouteRegistry {
|
|
2
|
+
entries = [];
|
|
3
|
+
/** Module currently being registered — set by InitModules so each captured
|
|
4
|
+
* route gets `module` populated. */
|
|
5
|
+
currentModule;
|
|
6
|
+
/** Push a new entry. Called by `createApp`'s interceptors. */
|
|
7
|
+
add(entry) {
|
|
8
|
+
if (this.currentModule !== undefined && entry.module === undefined) {
|
|
9
|
+
this.entries.push({ ...entry, module: this.currentModule });
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
this.entries.push(entry);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/** Run `fn` with `module` set so any routes registered inside are tagged. */
|
|
16
|
+
async withModule(name, fn) {
|
|
17
|
+
const previous = this.currentModule;
|
|
18
|
+
this.currentModule = name;
|
|
19
|
+
try {
|
|
20
|
+
return await fn();
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
this.currentModule = previous;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** All entries (defensively cloned). */
|
|
27
|
+
list(filter) {
|
|
28
|
+
return this.entries.filter((e) => matches(e, filter)).map((e) => ({ ...e }));
|
|
29
|
+
}
|
|
30
|
+
/** First entry matching `(method, path)` — exact path match. */
|
|
31
|
+
find(method, path) {
|
|
32
|
+
const match = this.entries.find((e) => e.method === method && e.path === path);
|
|
33
|
+
return match ? { ...match } : undefined;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Find routes that would collide with a proposed `(method, path)`. Returns
|
|
37
|
+
* exact matches only (not param-pattern overlap — that's a separate
|
|
38
|
+
* route-tree concern). Empty array means safe to add.
|
|
39
|
+
*/
|
|
40
|
+
findCollisions(method, path) {
|
|
41
|
+
return this.entries
|
|
42
|
+
.filter((e) => e.method === method && e.path === path)
|
|
43
|
+
.map((e) => ({ ...e }));
|
|
44
|
+
}
|
|
45
|
+
size() {
|
|
46
|
+
return this.entries.length;
|
|
47
|
+
}
|
|
48
|
+
/** Remove all entries — primarily for tests. */
|
|
49
|
+
clear() {
|
|
50
|
+
this.entries = [];
|
|
51
|
+
this.currentModule = undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function matches(entry, filter) {
|
|
55
|
+
if (!filter)
|
|
56
|
+
return true;
|
|
57
|
+
if (filter.method && entry.method !== filter.method)
|
|
58
|
+
return false;
|
|
59
|
+
if (filter.path && entry.path !== filter.path)
|
|
60
|
+
return false;
|
|
61
|
+
if (filter.module && entry.module !== filter.module)
|
|
62
|
+
return false;
|
|
63
|
+
if (filter.tag && !(entry.tags ?? []).includes(filter.tag))
|
|
64
|
+
return false;
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Default framework-wide registry. `createApp` populates this. Tests should
|
|
69
|
+
* call `routeRegistry.clear()` in `afterEach` to avoid cross-test bleed.
|
|
70
|
+
*/
|
|
71
|
+
export const routeRegistry = new RouteRegistry();
|
|
72
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/app/registry/routes.ts"],"names":[],"mappings":"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"}
|