@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,162 @@
|
|
|
1
|
+
import { DeleteObjectCommand, GetObjectCommand, HeadObjectCommand, ListObjectsV2Command, PutObjectCommand, } from "@aws-sdk/client-s3";
|
|
2
|
+
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
3
|
+
import { BadRequestError } from "../../../http/errors/BadRequestError.js";
|
|
4
|
+
/**
|
|
5
|
+
* Default upper bound on `signedUrl` TTL in seconds. 24 hours — long
|
|
6
|
+
* enough for typical share-link UX, short enough that a leaked URL is
|
|
7
|
+
* a bounded, auditable window rather than an indefinite back door.
|
|
8
|
+
* Override per-adapter via `S3StorageAdapterOptions.maxExpiresInSec`.
|
|
9
|
+
*/
|
|
10
|
+
const DEFAULT_MAX_EXPIRES_IN_SEC = 86_400;
|
|
11
|
+
export class S3StorageAdapter {
|
|
12
|
+
client;
|
|
13
|
+
bucket;
|
|
14
|
+
keyPrefix;
|
|
15
|
+
maxExpiresInSec;
|
|
16
|
+
constructor(opts) {
|
|
17
|
+
this.client = opts.client;
|
|
18
|
+
this.bucket = opts.bucket;
|
|
19
|
+
this.keyPrefix = opts.keyPrefix ?? "";
|
|
20
|
+
this.maxExpiresInSec = opts.maxExpiresInSec ?? DEFAULT_MAX_EXPIRES_IN_SEC;
|
|
21
|
+
if (this.maxExpiresInSec <= 0) {
|
|
22
|
+
throw new Error(`S3StorageAdapter: maxExpiresInSec must be positive (got ${this.maxExpiresInSec})`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
k(key) {
|
|
26
|
+
return this.keyPrefix + key;
|
|
27
|
+
}
|
|
28
|
+
/** Strip the prefix from a key returned by the SDK so callers see what they asked for. */
|
|
29
|
+
unk(awsKey) {
|
|
30
|
+
return awsKey.startsWith(this.keyPrefix) ? awsKey.slice(this.keyPrefix.length) : awsKey;
|
|
31
|
+
}
|
|
32
|
+
async bodyToS3(body) {
|
|
33
|
+
if (Buffer.isBuffer(body))
|
|
34
|
+
return body;
|
|
35
|
+
if (body instanceof Uint8Array)
|
|
36
|
+
return body;
|
|
37
|
+
if (body instanceof Blob)
|
|
38
|
+
return new Uint8Array(await body.arrayBuffer());
|
|
39
|
+
if (typeof body.getReader === "function") {
|
|
40
|
+
const reader = body.getReader();
|
|
41
|
+
const chunks = [];
|
|
42
|
+
while (true) {
|
|
43
|
+
const { done, value } = await reader.read();
|
|
44
|
+
if (done)
|
|
45
|
+
break;
|
|
46
|
+
if (value)
|
|
47
|
+
chunks.push(value);
|
|
48
|
+
}
|
|
49
|
+
return Buffer.concat(chunks);
|
|
50
|
+
}
|
|
51
|
+
throw new Error("S3StorageAdapter: unsupported body type");
|
|
52
|
+
}
|
|
53
|
+
async put(key, body, opts = {}) {
|
|
54
|
+
const buf = await this.bodyToS3(body);
|
|
55
|
+
const command = new PutObjectCommand({
|
|
56
|
+
Bucket: this.bucket,
|
|
57
|
+
Key: this.k(key),
|
|
58
|
+
Body: buf,
|
|
59
|
+
ContentType: opts.contentType,
|
|
60
|
+
CacheControl: opts.cacheControl,
|
|
61
|
+
Metadata: opts.metadata,
|
|
62
|
+
});
|
|
63
|
+
const response = await this.client.send(command);
|
|
64
|
+
return {
|
|
65
|
+
key,
|
|
66
|
+
size: buf.byteLength,
|
|
67
|
+
contentType: opts.contentType,
|
|
68
|
+
etag: response.ETag,
|
|
69
|
+
metadata: opts.metadata,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
async get(key) {
|
|
73
|
+
try {
|
|
74
|
+
const response = await this.client.send(new GetObjectCommand({ Bucket: this.bucket, Key: this.k(key) }));
|
|
75
|
+
const body = response.Body;
|
|
76
|
+
if (!body)
|
|
77
|
+
return null;
|
|
78
|
+
// The SDK exposes Body as a `Readable | ReadableStream | Blob`
|
|
79
|
+
// depending on runtime; transformToWebStream() unifies it.
|
|
80
|
+
const stream = typeof body.transformToWebStream === "function"
|
|
81
|
+
? body.transformToWebStream()
|
|
82
|
+
: body;
|
|
83
|
+
const meta = {
|
|
84
|
+
key,
|
|
85
|
+
size: response.ContentLength ?? 0,
|
|
86
|
+
contentType: response.ContentType,
|
|
87
|
+
lastModified: response.LastModified,
|
|
88
|
+
etag: response.ETag,
|
|
89
|
+
metadata: response.Metadata,
|
|
90
|
+
};
|
|
91
|
+
return { stream, meta };
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
if (isS3NotFound(err))
|
|
95
|
+
return null;
|
|
96
|
+
throw err;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async exists(key) {
|
|
100
|
+
try {
|
|
101
|
+
await this.client.send(new HeadObjectCommand({ Bucket: this.bucket, Key: this.k(key) }));
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
if (isS3NotFound(err))
|
|
106
|
+
return false;
|
|
107
|
+
throw err;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async delete(key) {
|
|
111
|
+
await this.client.send(new DeleteObjectCommand({ Bucket: this.bucket, Key: this.k(key) }));
|
|
112
|
+
}
|
|
113
|
+
async list(prefix = "", opts = {}) {
|
|
114
|
+
const response = await this.client.send(new ListObjectsV2Command({
|
|
115
|
+
Bucket: this.bucket,
|
|
116
|
+
Prefix: this.k(prefix),
|
|
117
|
+
MaxKeys: opts.maxKeys ?? 1000,
|
|
118
|
+
ContinuationToken: opts.continuationToken,
|
|
119
|
+
}));
|
|
120
|
+
const objects = (response.Contents ?? []).map((entry) => ({
|
|
121
|
+
key: this.unk(entry.Key ?? ""),
|
|
122
|
+
size: entry.Size ?? 0,
|
|
123
|
+
lastModified: entry.LastModified,
|
|
124
|
+
etag: entry.ETag,
|
|
125
|
+
}));
|
|
126
|
+
return {
|
|
127
|
+
objects,
|
|
128
|
+
nextContinuationToken: response.IsTruncated ? response.NextContinuationToken : undefined,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
async signedUrl(key, opts = {}) {
|
|
132
|
+
const expiresIn = opts.expiresInSec ?? 900;
|
|
133
|
+
if (expiresIn <= 0 || expiresIn > this.maxExpiresInSec) {
|
|
134
|
+
throw new BadRequestError(`Signed URL TTL out of range: ${expiresIn}s (must be > 0 and <= ${this.maxExpiresInSec}s)`);
|
|
135
|
+
}
|
|
136
|
+
const method = opts.method ?? "GET";
|
|
137
|
+
if (method === "PUT") {
|
|
138
|
+
const command = new PutObjectCommand({
|
|
139
|
+
Bucket: this.bucket,
|
|
140
|
+
Key: this.k(key),
|
|
141
|
+
ContentType: opts.contentType,
|
|
142
|
+
});
|
|
143
|
+
return getSignedUrl(this.client, command, { expiresIn });
|
|
144
|
+
}
|
|
145
|
+
const command = new GetObjectCommand({ Bucket: this.bucket, Key: this.k(key) });
|
|
146
|
+
return getSignedUrl(this.client, command, { expiresIn });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/** Detect "key not found" across the SDK's error variants. */
|
|
150
|
+
function isS3NotFound(err) {
|
|
151
|
+
if (typeof err !== "object" || err === null)
|
|
152
|
+
return false;
|
|
153
|
+
const e = err;
|
|
154
|
+
if (e.name === "NoSuchKey" || e.name === "NotFound")
|
|
155
|
+
return true;
|
|
156
|
+
if (e.Code === "NoSuchKey" || e.Code === "NotFound")
|
|
157
|
+
return true;
|
|
158
|
+
if (e.$metadata?.httpStatusCode === 404)
|
|
159
|
+
return true;
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=S3StorageAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"S3StorageAdapter.js","sourceRoot":"","sources":["../../../../src/app/services/storage/S3StorageAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `StorageService` — framework-wide blob/object storage abstraction.
|
|
3
|
+
*
|
|
4
|
+
* Three adapters ship in v4.0:
|
|
5
|
+
* - `DiskStorageAdapter` (this batch) — local filesystem; tests + dev.
|
|
6
|
+
* - `S3StorageAdapter` (next batch) — `@aws-sdk/client-s3` as optional
|
|
7
|
+
* peer dep; production default for AWS.
|
|
8
|
+
* - `GCSStorageAdapter` (next batch) — `@google-cloud/storage` as
|
|
9
|
+
* optional peer dep; Sixth Summit's GCP default.
|
|
10
|
+
*
|
|
11
|
+
* The interface is intentionally narrow — `put` / `get` / `exists` /
|
|
12
|
+
* `delete` / `list` / `signedUrl` — so future adapters (R2, Azure Blob,
|
|
13
|
+
* Cloudflare KV-as-blob) can plug in without API churn. Per-adapter
|
|
14
|
+
* options that don't fit the common shape go in the constructor, not the
|
|
15
|
+
* interface.
|
|
16
|
+
*/
|
|
17
|
+
export type StorageBody = Buffer | Uint8Array | ReadableStream | Blob | File;
|
|
18
|
+
export interface StorageObjectMeta {
|
|
19
|
+
/** Object key relative to the adapter's namespace (no leading "/"). */
|
|
20
|
+
key: string;
|
|
21
|
+
/** Size in bytes. */
|
|
22
|
+
size: number;
|
|
23
|
+
/** MIME type if recorded. */
|
|
24
|
+
contentType?: string;
|
|
25
|
+
/** Last-modified timestamp if the adapter reports it. */
|
|
26
|
+
lastModified?: Date;
|
|
27
|
+
/** Adapter-specific entity tag (md5, opaque, etc.). */
|
|
28
|
+
etag?: string;
|
|
29
|
+
/** User-supplied metadata recorded at put-time. */
|
|
30
|
+
metadata?: Record<string, string>;
|
|
31
|
+
}
|
|
32
|
+
export interface PutOptions {
|
|
33
|
+
contentType?: string;
|
|
34
|
+
cacheControl?: string;
|
|
35
|
+
metadata?: Record<string, string>;
|
|
36
|
+
}
|
|
37
|
+
export interface ListOptions {
|
|
38
|
+
/** Max objects per page. Default 1000. */
|
|
39
|
+
maxKeys?: number;
|
|
40
|
+
/** Opaque cursor returned by the previous page. */
|
|
41
|
+
continuationToken?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface ListResult {
|
|
44
|
+
objects: StorageObjectMeta[];
|
|
45
|
+
nextContinuationToken?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface SignedUrlOptions {
|
|
48
|
+
/**
|
|
49
|
+
* TTL in seconds. Default 900 (15 min). Bounded by the adapter's
|
|
50
|
+
* `maxExpiresInSec` (default 86400 = 24h); values exceeding the
|
|
51
|
+
* ceiling throw `BadRequestError`.
|
|
52
|
+
*
|
|
53
|
+
* The ceiling defends multi-tenant deployments: a long-lived
|
|
54
|
+
* signed URL survives session revocation, role changes, and tenant
|
|
55
|
+
* migrations, so any leak (logs, share-link UX, analytics, browser
|
|
56
|
+
* history forwarded to support) becomes a window of cross-tenant
|
|
57
|
+
* data exposure with no audit trail. Per-adapter configurable when
|
|
58
|
+
* a higher ceiling is genuinely required.
|
|
59
|
+
*/
|
|
60
|
+
expiresInSec?: number;
|
|
61
|
+
/** `"GET"` (download) or `"PUT"` (browser-direct upload). Default `"GET"`. */
|
|
62
|
+
method?: "GET" | "PUT";
|
|
63
|
+
/** Required `Content-Type` for PUT pre-signed URLs. */
|
|
64
|
+
contentType?: string;
|
|
65
|
+
}
|
|
66
|
+
export interface GetResult {
|
|
67
|
+
/** Streaming body. The caller must drain or cancel. */
|
|
68
|
+
stream: ReadableStream;
|
|
69
|
+
meta: StorageObjectMeta;
|
|
70
|
+
}
|
|
71
|
+
export interface StorageService {
|
|
72
|
+
/** Upload `body` under `key`. Returns the recorded metadata. */
|
|
73
|
+
put(key: string, body: StorageBody, opts?: PutOptions): Promise<StorageObjectMeta>;
|
|
74
|
+
/** Returns `null` when the object doesn't exist. */
|
|
75
|
+
get(key: string): Promise<GetResult | null>;
|
|
76
|
+
exists(key: string): Promise<boolean>;
|
|
77
|
+
delete(key: string): Promise<void>;
|
|
78
|
+
list(prefix?: string, opts?: ListOptions): Promise<ListResult>;
|
|
79
|
+
/**
|
|
80
|
+
* Pre-signed URL for direct browser GET / PUT. Optional — adapters that
|
|
81
|
+
* can't sign (e.g., the disk adapter without a separate file server)
|
|
82
|
+
* should throw a clear error. Consumers that need signed URLs can branch
|
|
83
|
+
* on `if ("signedUrl" in service)` or assume the production adapter
|
|
84
|
+
* always implements it.
|
|
85
|
+
*/
|
|
86
|
+
signedUrl?(key: string, opts?: SignedUrlOptions): Promise<string>;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=StorageService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StorageService.d.ts","sourceRoot":"","sources":["../../../../src/app/services/storage/StorageService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,cAAc,GAAG,IAAI,GAAG,IAAI,CAAC;AAE7E,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,GAAG,EAAE,MAAM,CAAC;IACZ,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACvB,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,uDAAuD;IACvD,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,iBAAiB,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,gEAAgE;IAChE,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAEnF,oDAAoD;IACpD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAE5C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAE/D;;;;;;OAMG;IACH,SAAS,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACnE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `StorageService` — framework-wide blob/object storage abstraction.
|
|
3
|
+
*
|
|
4
|
+
* Three adapters ship in v4.0:
|
|
5
|
+
* - `DiskStorageAdapter` (this batch) — local filesystem; tests + dev.
|
|
6
|
+
* - `S3StorageAdapter` (next batch) — `@aws-sdk/client-s3` as optional
|
|
7
|
+
* peer dep; production default for AWS.
|
|
8
|
+
* - `GCSStorageAdapter` (next batch) — `@google-cloud/storage` as
|
|
9
|
+
* optional peer dep; Sixth Summit's GCP default.
|
|
10
|
+
*
|
|
11
|
+
* The interface is intentionally narrow — `put` / `get` / `exists` /
|
|
12
|
+
* `delete` / `list` / `signedUrl` — so future adapters (R2, Azure Blob,
|
|
13
|
+
* Cloudflare KV-as-blob) can plug in without API churn. Per-adapter
|
|
14
|
+
* options that don't fit the common shape go in the constructor, not the
|
|
15
|
+
* interface.
|
|
16
|
+
*/
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=StorageService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StorageService.js","sourceRoot":"","sources":["../../../../src/app/services/storage/StorageService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { DiskStorageAdapter, type DiskStorageAdapterOptions } from "./DiskStorageAdapter.js";
|
|
2
|
+
export { GCSStorageAdapter, type GCSStorageAdapterOptions } from "./GCSStorageAdapter.js";
|
|
3
|
+
export { S3StorageAdapter, type S3StorageAdapterOptions } from "./S3StorageAdapter.js";
|
|
4
|
+
export type { GetResult, ListOptions, ListResult, PutOptions, SignedUrlOptions, StorageBody, StorageObjectMeta, StorageService, } from "./StorageService.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/app/services/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAC7F,OAAO,EAAE,iBAAiB,EAAE,KAAK,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAE1F,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACvF,YAAY,EACV,SAAS,EACT,WAAW,EACX,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EACjB,cAAc,GACf,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/app/services/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAkC,MAAM,yBAAyB,CAAC;AAC7F,OAAO,EAAE,iBAAiB,EAAiC,MAAM,wBAAwB,CAAC;AAE1F,OAAO,EAAE,gBAAgB,EAAgC,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context validators for common data access patterns
|
|
3
|
+
*/
|
|
4
|
+
export declare class ContextValidators {
|
|
5
|
+
/**
|
|
6
|
+
* Validates that the user can only access their own data
|
|
7
|
+
*/
|
|
8
|
+
static ownData(req: any, entity: any): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Validates that the user can access data they created
|
|
11
|
+
*/
|
|
12
|
+
static ownCreatedData(req: any, entity: any): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Validates that the user can access data in their organization/group
|
|
15
|
+
*/
|
|
16
|
+
static sameOrganization(req: any, entity: any): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Validates that the user can access data they have a relationship with
|
|
19
|
+
*/
|
|
20
|
+
static hasRelationship(req: any, entity: any, relationshipField: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Validates that the user can access data based on a custom field comparison
|
|
23
|
+
*/
|
|
24
|
+
static customField(req: any, entity: any, fieldPath: string): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Validates that the user can access data based on multiple conditions (AND logic)
|
|
27
|
+
*/
|
|
28
|
+
static and(...validators: Array<(req: any, entity: any) => boolean>): (req: any, entity: any) => boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Validates that the user can access data based on multiple conditions (OR logic)
|
|
31
|
+
*/
|
|
32
|
+
static or(...validators: Array<(req: any, entity: any) => boolean>): (req: any, entity: any) => boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Validates that the user has admin privileges (bypasses context checks)
|
|
35
|
+
*/
|
|
36
|
+
static adminBypass(req: any, entity: any): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Validates that the user can access data based on a custom function
|
|
39
|
+
*/
|
|
40
|
+
static custom(validator: (req: any, entity: any) => boolean): (req: any, entity: any) => boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Helper to get nested object values using dot notation
|
|
43
|
+
*/
|
|
44
|
+
private static getNestedValue;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=ContextValidators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContextValidators.d.ts","sourceRoot":"","sources":["../../../src/app/utils/ContextValidators.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,iBAAiB;IAC5B;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,OAAO;IAK9C;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,OAAO;IAKrD;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,OAAO;IAKvD;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO;IAKjF;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAOrE;;OAEG;IACH,MAAM,CAAC,GAAG,CACR,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,OAAO,CAAC,GACvD,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,OAAO;IAMrC;;OAEG;IACH,MAAM,CAAC,EAAE,CACP,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,OAAO,CAAC,GACvD,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,OAAO;IAMrC;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,OAAO;IAIlD;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,OAAO,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,OAAO;IAIhG;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;CAG9B"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context validators for common data access patterns
|
|
3
|
+
*/
|
|
4
|
+
export class ContextValidators {
|
|
5
|
+
/**
|
|
6
|
+
* Validates that the user can only access their own data
|
|
7
|
+
*/
|
|
8
|
+
static ownData(req, entity) {
|
|
9
|
+
if (!req.user || !entity)
|
|
10
|
+
return false;
|
|
11
|
+
return req.user.id === entity.accountId || req.user.id === entity.userId;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Validates that the user can access data they created
|
|
15
|
+
*/
|
|
16
|
+
static ownCreatedData(req, entity) {
|
|
17
|
+
if (!req.user || !entity)
|
|
18
|
+
return false;
|
|
19
|
+
return req.user.id === entity.createdById || req.user.id === entity.authorId;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Validates that the user can access data in their organization/group
|
|
23
|
+
*/
|
|
24
|
+
static sameOrganization(req, entity) {
|
|
25
|
+
if (!req.user || !entity)
|
|
26
|
+
return false;
|
|
27
|
+
return req.user.organizationId === entity.organizationId || req.user.groupId === entity.groupId;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Validates that the user can access data they have a relationship with
|
|
31
|
+
*/
|
|
32
|
+
static hasRelationship(req, entity, relationshipField) {
|
|
33
|
+
if (!req.user || !entity)
|
|
34
|
+
return false;
|
|
35
|
+
return req.user.id === entity[relationshipField];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Validates that the user can access data based on a custom field comparison
|
|
39
|
+
*/
|
|
40
|
+
static customField(req, entity, fieldPath) {
|
|
41
|
+
if (!req.user || !entity)
|
|
42
|
+
return false;
|
|
43
|
+
const fieldValue = ContextValidators.getNestedValue(entity, fieldPath);
|
|
44
|
+
return req.user.id === fieldValue;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Validates that the user can access data based on multiple conditions (AND logic)
|
|
48
|
+
*/
|
|
49
|
+
static and(...validators) {
|
|
50
|
+
return (req, entity) => {
|
|
51
|
+
return validators.every((validator) => validator(req, entity));
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Validates that the user can access data based on multiple conditions (OR logic)
|
|
56
|
+
*/
|
|
57
|
+
static or(...validators) {
|
|
58
|
+
return (req, entity) => {
|
|
59
|
+
return validators.some((validator) => validator(req, entity));
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Validates that the user has admin privileges (bypasses context checks)
|
|
64
|
+
*/
|
|
65
|
+
static adminBypass(req, entity) {
|
|
66
|
+
return req.user?.hasPermission("admin") || req.user?.hasPermission("superuser");
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Validates that the user can access data based on a custom function
|
|
70
|
+
*/
|
|
71
|
+
static custom(validator) {
|
|
72
|
+
return validator;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Helper to get nested object values using dot notation
|
|
76
|
+
*/
|
|
77
|
+
static getNestedValue(obj, path) {
|
|
78
|
+
return path.split(".").reduce((current, key) => current?.[key], obj);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=ContextValidators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContextValidators.js","sourceRoot":"","sources":["../../../src/app/utils/ContextValidators.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `defineEnv` — boot-time environment validation.
|
|
3
|
+
*
|
|
4
|
+
* Accepts any schema with a `safeParse(data) -> { success, data | error }` shape
|
|
5
|
+
* (Zod 3, Zod 4, Valibot adapter, etc.) so the framework stays validator-agnostic
|
|
6
|
+
* at the type level. On failure: prints a structured "missing/invalid: VAR (type)"
|
|
7
|
+
* report and exits with code 1 *before* the app boots.
|
|
8
|
+
*
|
|
9
|
+
* Replaces the v3 pattern of scattered `process.env.FOO || ""` reads with a single
|
|
10
|
+
* typed env object. Eliminates the class of "mystery runtime errors from a typo'd
|
|
11
|
+
* env var" by failing loudly at startup.
|
|
12
|
+
*/
|
|
13
|
+
export interface EnvSchemaIssue {
|
|
14
|
+
path: ReadonlyArray<PropertyKey>;
|
|
15
|
+
message: string;
|
|
16
|
+
code?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface EnvSchemaError {
|
|
19
|
+
issues: ReadonlyArray<EnvSchemaIssue>;
|
|
20
|
+
}
|
|
21
|
+
export type EnvSafeParseResult<T> = {
|
|
22
|
+
success: true;
|
|
23
|
+
data: T;
|
|
24
|
+
} | {
|
|
25
|
+
success: false;
|
|
26
|
+
error: EnvSchemaError;
|
|
27
|
+
};
|
|
28
|
+
export interface EnvSchema<T> {
|
|
29
|
+
safeParse(data: unknown): EnvSafeParseResult<T>;
|
|
30
|
+
}
|
|
31
|
+
export interface DefineEnvOptions {
|
|
32
|
+
/** Source of env vars. Defaults to `process.env`. */
|
|
33
|
+
source?: NodeJS.ProcessEnv;
|
|
34
|
+
/**
|
|
35
|
+
* Override the failure handler. Default logs a report and calls `process.exit(1)`.
|
|
36
|
+
* Useful in tests so a bad fixture doesn't kill the test runner.
|
|
37
|
+
*/
|
|
38
|
+
onFailure?: (issues: ReadonlyArray<EnvSchemaIssue>) => never;
|
|
39
|
+
/**
|
|
40
|
+
* Logger for the failure report. Defaults to `console.error`.
|
|
41
|
+
* In v4 this will default to the framework's pino logger.
|
|
42
|
+
*/
|
|
43
|
+
logger?: Pick<Console, "error">;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Replace common secret-value shapes with `<redacted>` before logging.
|
|
47
|
+
*
|
|
48
|
+
* Framework-default Zod messages don't include the raw value (e.g.
|
|
49
|
+
* "String must contain at least 32 character(s)"), but consumer
|
|
50
|
+
* schemas using `.refine((v) => …, { message: `got "${v}"` })` or
|
|
51
|
+
* transform-based validators that include the raw value will spill
|
|
52
|
+
* the secret through this `console.error` path — observability
|
|
53
|
+
* stacks (Stackdriver, Datadog, Loki) capture stdout/stderr by
|
|
54
|
+
* default, and the secret then becomes searchable, indexed, and
|
|
55
|
+
* forwarded across systems. A regex scrub here is the last line of
|
|
56
|
+
* defense before that boundary.
|
|
57
|
+
*
|
|
58
|
+
* The patterns are intentionally narrow (named token shapes) plus
|
|
59
|
+
* one generic-high-entropy catch-all. False positives are limited
|
|
60
|
+
* to error messages that happen to contain ≥32 contiguous
|
|
61
|
+
* base64-alphabet characters with no separators — rare in legit
|
|
62
|
+
* Zod messages.
|
|
63
|
+
*/
|
|
64
|
+
export declare function scrubSecrets(message: string): string;
|
|
65
|
+
/**
|
|
66
|
+
* Validate process.env against a schema. Returns the typed env on success;
|
|
67
|
+
* exits the process with a structured error report on failure.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* import { z } from "zod";
|
|
71
|
+
* const schema = z.object({
|
|
72
|
+
* PORT: z.coerce.number().int().positive().default(3000),
|
|
73
|
+
* DATABASE_URL: z.string().url(),
|
|
74
|
+
* SESSION_SECRET: z.string().min(32),
|
|
75
|
+
* });
|
|
76
|
+
* export const env = defineEnv(schema);
|
|
77
|
+
* // env.PORT is typed as number, env.DATABASE_URL as string, etc.
|
|
78
|
+
*/
|
|
79
|
+
export declare function defineEnv<T>(schema: EnvSchema<T>, opts?: DefineEnvOptions): T;
|
|
80
|
+
//# sourceMappingURL=defineEnv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineEnv.d.ts","sourceRoot":"","sources":["../../../src/app/utils/defineEnv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,cAAc;IAM7B,IAAI,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;CACvC;AAED,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAC5B;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GAC1B;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,CAAC;AAE9C,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAC3B;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,cAAc,CAAC,KAAK,KAAK,CAAC;IAC7D;;;OAGG;IACH,MAAM,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOpD;AAqCD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,GAAE,gBAAqB,GAAG,CAAC,CAUjF"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `defineEnv` — boot-time environment validation.
|
|
3
|
+
*
|
|
4
|
+
* Accepts any schema with a `safeParse(data) -> { success, data | error }` shape
|
|
5
|
+
* (Zod 3, Zod 4, Valibot adapter, etc.) so the framework stays validator-agnostic
|
|
6
|
+
* at the type level. On failure: prints a structured "missing/invalid: VAR (type)"
|
|
7
|
+
* report and exits with code 1 *before* the app boots.
|
|
8
|
+
*
|
|
9
|
+
* Replaces the v3 pattern of scattered `process.env.FOO || ""` reads with a single
|
|
10
|
+
* typed env object. Eliminates the class of "mystery runtime errors from a typo'd
|
|
11
|
+
* env var" by failing loudly at startup.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Replace common secret-value shapes with `<redacted>` before logging.
|
|
15
|
+
*
|
|
16
|
+
* Framework-default Zod messages don't include the raw value (e.g.
|
|
17
|
+
* "String must contain at least 32 character(s)"), but consumer
|
|
18
|
+
* schemas using `.refine((v) => …, { message: `got "${v}"` })` or
|
|
19
|
+
* transform-based validators that include the raw value will spill
|
|
20
|
+
* the secret through this `console.error` path — observability
|
|
21
|
+
* stacks (Stackdriver, Datadog, Loki) capture stdout/stderr by
|
|
22
|
+
* default, and the secret then becomes searchable, indexed, and
|
|
23
|
+
* forwarded across systems. A regex scrub here is the last line of
|
|
24
|
+
* defense before that boundary.
|
|
25
|
+
*
|
|
26
|
+
* The patterns are intentionally narrow (named token shapes) plus
|
|
27
|
+
* one generic-high-entropy catch-all. False positives are limited
|
|
28
|
+
* to error messages that happen to contain ≥32 contiguous
|
|
29
|
+
* base64-alphabet characters with no separators — rare in legit
|
|
30
|
+
* Zod messages.
|
|
31
|
+
*/
|
|
32
|
+
export function scrubSecrets(message) {
|
|
33
|
+
if (typeof message !== "string" || message.length === 0)
|
|
34
|
+
return message;
|
|
35
|
+
let out = message;
|
|
36
|
+
for (const pattern of SECRET_PATTERNS) {
|
|
37
|
+
out = out.replace(pattern, "<redacted>");
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
// Ordered most-specific → least-specific so named shapes don't get
|
|
42
|
+
// pre-swallowed by the generic high-entropy catch.
|
|
43
|
+
const SECRET_PATTERNS = [
|
|
44
|
+
// JWT-shaped (three base64url segments separated by `.`)
|
|
45
|
+
/eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g,
|
|
46
|
+
// OpenAI / Anthropic-style `sk-…` keys
|
|
47
|
+
/\bsk-[A-Za-z0-9_-]{20,}\b/g,
|
|
48
|
+
// Slack tokens (`xoxb-…`, `xoxp-…`, `xoxa-…`)
|
|
49
|
+
/\bxox[abp]-[A-Za-z0-9-]{10,}\b/g,
|
|
50
|
+
// AWS access key IDs
|
|
51
|
+
/\bAKIA[0-9A-Z]{16}\b/g,
|
|
52
|
+
// Generic high-entropy: contiguous run of 32+ base64-ish characters
|
|
53
|
+
// with no spaces. Last resort for "we don't know the prefix but
|
|
54
|
+
// the value is obviously a token."
|
|
55
|
+
/[A-Za-z0-9+/=_-]{32,}/g,
|
|
56
|
+
];
|
|
57
|
+
function defaultOnFailure(issues, logger) {
|
|
58
|
+
logger.error("");
|
|
59
|
+
logger.error("✗ Environment validation failed. The app cannot start.");
|
|
60
|
+
logger.error("");
|
|
61
|
+
for (const issue of issues) {
|
|
62
|
+
const path = issue.path.length > 0 ? issue.path.join(".") : "<root>";
|
|
63
|
+
const safeMessage = scrubSecrets(issue.message);
|
|
64
|
+
logger.error(` • ${path}: ${safeMessage}${issue.code ? ` [${issue.code}]` : ""}`);
|
|
65
|
+
}
|
|
66
|
+
logger.error("");
|
|
67
|
+
logger.error(`Total: ${issues.length} issue(s). Fix the env vars listed above and restart.`);
|
|
68
|
+
logger.error("");
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Validate process.env against a schema. Returns the typed env on success;
|
|
73
|
+
* exits the process with a structured error report on failure.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* import { z } from "zod";
|
|
77
|
+
* const schema = z.object({
|
|
78
|
+
* PORT: z.coerce.number().int().positive().default(3000),
|
|
79
|
+
* DATABASE_URL: z.string().url(),
|
|
80
|
+
* SESSION_SECRET: z.string().min(32),
|
|
81
|
+
* });
|
|
82
|
+
* export const env = defineEnv(schema);
|
|
83
|
+
* // env.PORT is typed as number, env.DATABASE_URL as string, etc.
|
|
84
|
+
*/
|
|
85
|
+
export function defineEnv(schema, opts = {}) {
|
|
86
|
+
const source = opts.source ?? process.env;
|
|
87
|
+
const logger = opts.logger ?? console;
|
|
88
|
+
const onFailure = opts.onFailure ?? ((issues) => defaultOnFailure(issues, logger));
|
|
89
|
+
const result = schema.safeParse(source);
|
|
90
|
+
if (result.success) {
|
|
91
|
+
return result.data;
|
|
92
|
+
}
|
|
93
|
+
return onFailure(result.error.issues);
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=defineEnv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineEnv.js","sourceRoot":"","sources":["../../../src/app/utils/defineEnv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAwCH;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IACxE,IAAI,GAAG,GAAG,OAAO,CAAC;IAClB,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;QACtC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,mEAAmE;AACnE,mDAAmD;AACnD,MAAM,eAAe,GAAsB;IACzC,yDAAyD;IACzD,gEAAgE;IAChE,uCAAuC;IACvC,4BAA4B;IAC5B,8CAA8C;IAC9C,iCAAiC;IACjC,qBAAqB;IACrB,uBAAuB;IACvB,oEAAoE;IACpE,gEAAgE;IAChE,mCAAmC;IACnC,wBAAwB;CACzB,CAAC;AAEF,SAAS,gBAAgB,CACvB,MAAqC,EACrC,MAA8B;IAE9B,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACjB,MAAM,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;IACvE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACjB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QACrE,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACrF,CAAC;IACD,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACjB,MAAM,CAAC,KAAK,CAAC,UAAU,MAAM,CAAC,MAAM,uDAAuD,CAAC,CAAC;IAC7F,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,SAAS,CAAI,MAAoB,EAAE,OAAyB,EAAE;IAC5E,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC;IACtC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAEnF,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IACD,OAAO,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC"}
|