@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,105 @@
|
|
|
1
|
+
import type { Context, MiddlewareHandler } from "hono";
|
|
2
|
+
import type { RateLimitBackend } from "../../app/services/rateLimit/RateLimitBackend.js";
|
|
3
|
+
import { logger as defaultLogger } from "../../observability/logger.js";
|
|
4
|
+
/**
|
|
5
|
+
* `rateLimit({ windowMs, max, ... })` — Hono middleware factory.
|
|
6
|
+
*
|
|
7
|
+
* Replaces v3's in-memory `RateLimitMiddleware`. Production-default backend
|
|
8
|
+
* is `RedisSlidingWindowBackend` (atomic Lua sliding-window log); v4.0 also
|
|
9
|
+
* ships `InMemorySlidingWindowBackend` for tests + dev fallback.
|
|
10
|
+
*
|
|
11
|
+
* Headers (RFC-draft `RateLimit-*`):
|
|
12
|
+
* - `RateLimit-Limit: <max>`
|
|
13
|
+
* - `RateLimit-Remaining: <max - used>`
|
|
14
|
+
* - `RateLimit-Policy: <max>;w=<window-seconds>`
|
|
15
|
+
* Optional legacy headers (`X-RateLimit-Limit/Remaining/Reset`) emitted when
|
|
16
|
+
* `legacyHeaders: true` for clients that haven't moved to the draft yet.
|
|
17
|
+
*
|
|
18
|
+
* On rejection: throws `RateLimitError` (mapped to 429 by registerErrorHandlers)
|
|
19
|
+
* after setting `Retry-After: <seconds>`. The middleware sets headers on the
|
|
20
|
+
* outgoing response *before* throwing so the 429 response carries them.
|
|
21
|
+
*
|
|
22
|
+
* Redis-unavailable behavior is configurable, NOT a silent fallback:
|
|
23
|
+
* - `'deny'` (default, fail-closed) — returns RateLimitError as if the
|
|
24
|
+
* ceiling were exceeded. Safer default; the user gets a real 429
|
|
25
|
+
* instead of unintentional unlimited access.
|
|
26
|
+
* - `'allow'` (fail-open) — calls next() without enforcement. Logs a
|
|
27
|
+
* warning so operators can detect Redis flapping.
|
|
28
|
+
*
|
|
29
|
+
* Tagged `RATE_LIMIT_META` so `createApp` populates the route registry.
|
|
30
|
+
*/
|
|
31
|
+
export interface RateLimitOptions {
|
|
32
|
+
/** Window length in milliseconds. */
|
|
33
|
+
windowMs: number;
|
|
34
|
+
/** Maximum requests per key per window. */
|
|
35
|
+
max: number;
|
|
36
|
+
/** Backend implementation. Default: a shared in-memory backend; production
|
|
37
|
+
* consumers pass a `RedisSlidingWindowBackend`. */
|
|
38
|
+
backend: RateLimitBackend;
|
|
39
|
+
/**
|
|
40
|
+
* Compose the bucket key from the request. Default: authenticated user
|
|
41
|
+
* ID (from `c.get('user').id`) when set, else the client IP. The request
|
|
42
|
+
* path is *not* included by default — for per-route limits, instantiate
|
|
43
|
+
* a separate `rateLimit({...})` per route.
|
|
44
|
+
*/
|
|
45
|
+
keyGenerator?: (c: Context) => string;
|
|
46
|
+
/**
|
|
47
|
+
* Namespace appended to the bucket key (e.g., `"login"` for a tighter
|
|
48
|
+
* limiter on `POST /accounts/login`). Default: empty.
|
|
49
|
+
*/
|
|
50
|
+
scope?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Behavior when the backend throws (e.g., Redis unreachable):
|
|
53
|
+
* - `'deny'` (default): treat as over-limit, throw RateLimitError.
|
|
54
|
+
* - `'allow'`: log a warning, call next() without enforcement.
|
|
55
|
+
*
|
|
56
|
+
* **F28 — security note on `'allow'`.** `onBackendError: 'allow'`
|
|
57
|
+
* **removes rate limiting entirely** during any window where the
|
|
58
|
+
* backend is unavailable — login / signup / password-reset
|
|
59
|
+
* endpoints become unbounded for the duration of the outage. Don't
|
|
60
|
+
* pick `'allow'` as a workaround for flaky Redis: fix Redis first
|
|
61
|
+
* (HA failover, connection pool tuning, a separate Redis tier
|
|
62
|
+
* for rate-limit state). Choose `'allow'` only with a deliberate
|
|
63
|
+
* threat-model decision that the availability cost of brief
|
|
64
|
+
* unlimited access during outages outweighs the security cost.
|
|
65
|
+
* Common deployments where `'allow'` is defensible: internal-only
|
|
66
|
+
* APIs behind VPN auth where rate limiting is UX-shaping rather
|
|
67
|
+
* than security; public APIs with WAF-layer rate limiting
|
|
68
|
+
* upstream. Public-facing SaaS authentication endpoints are
|
|
69
|
+
* exactly where `'allow'` is wrong.
|
|
70
|
+
*/
|
|
71
|
+
onBackendError?: "allow" | "deny";
|
|
72
|
+
/** Emit `X-RateLimit-*` headers in addition to the RFC draft `RateLimit-*` set. */
|
|
73
|
+
legacyHeaders?: boolean;
|
|
74
|
+
/** Override the framework default pino logger. */
|
|
75
|
+
logger?: typeof defaultLogger;
|
|
76
|
+
/**
|
|
77
|
+
* CIDR allowlist for upstream proxies. The default key generator
|
|
78
|
+
* trusts `X-Forwarded-For` **only** when the immediate peer's IP
|
|
79
|
+
* falls inside one of these ranges; otherwise XFF is ignored and
|
|
80
|
+
* the peer IP wins. The framework default is the empty list — the
|
|
81
|
+
* secure, fail-closed posture for adopters who haven't declared
|
|
82
|
+
* their topology.
|
|
83
|
+
*
|
|
84
|
+
* In production, set this to the public CIDR ranges of your CDN /
|
|
85
|
+
* load balancer (Cloudflare, AWS ALB, Fastly, Google Cloud Armor,
|
|
86
|
+
* etc.). The rightmost-untrusted-IP walker then returns the real
|
|
87
|
+
* client IP from XFF, skipping each known proxy hop.
|
|
88
|
+
*
|
|
89
|
+
* Example (Cloudflare, abbreviated):
|
|
90
|
+
* `trustProxy: ["173.245.48.0/20", "103.21.244.0/22", "2400:cb00::/32", ...]`
|
|
91
|
+
*
|
|
92
|
+
* `["0.0.0.0/0", "::/0"]` trusts every peer — useful in unit tests
|
|
93
|
+
* where the peer IP cannot be observed, **never** in production.
|
|
94
|
+
*/
|
|
95
|
+
trustProxy?: readonly string[];
|
|
96
|
+
/**
|
|
97
|
+
* Resolve the immediate peer IP from the Hono `Context`. Default:
|
|
98
|
+
* read `c.env.incoming.socket.remoteAddress` (Node adapter). Tests
|
|
99
|
+
* and non-Node runtimes (Cloudflare, Deno, Bun) override this with
|
|
100
|
+
* an env-specific reader.
|
|
101
|
+
*/
|
|
102
|
+
resolvePeerIp?: (c: Context) => string | undefined;
|
|
103
|
+
}
|
|
104
|
+
export declare function rateLimit(opts: RateLimitOptions): MiddlewareHandler;
|
|
105
|
+
//# sourceMappingURL=rateLimit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rateLimit.d.ts","sourceRoot":"","sources":["../../../src/http/middleware/rateLimit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kDAAkD,CAAC;AACzF,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAKxE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,qCAAqC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ;wDACoD;IACpD,OAAO,EAAE,gBAAgB,CAAC;IAC1B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;IACtC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;;;;;;;;;;;OAmBG;IACH,cAAc,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAClC,mFAAmF;IACnF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kDAAkD;IAClD,MAAM,CAAC,EAAE,OAAO,aAAa,CAAC;IAC9B;;;;;;;;;;;;;;;;;;OAkBG;IACH,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;CACpD;AAiDD,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,iBAAiB,CA2DnE"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { logger as defaultLogger } from "../../observability/logger.js";
|
|
2
|
+
import { RateLimitError } from "../errors/RateLimitError.js";
|
|
3
|
+
import { compileTrustProxy, resolveClientIp } from "../utils/clientIp.js";
|
|
4
|
+
import { RATE_LIMIT_META, setMetaTag } from "../utils/metaTags.js";
|
|
5
|
+
function defaultResolvePeerIp(c) {
|
|
6
|
+
// Node adapter exposes the underlying IncomingMessage via `c.env.incoming`.
|
|
7
|
+
// Cloudflare / Deno / Bun runtimes pass `resolvePeerIp` explicitly.
|
|
8
|
+
const env = c.env;
|
|
9
|
+
return env?.incoming?.socket?.remoteAddress;
|
|
10
|
+
}
|
|
11
|
+
function makeDefaultKeyGenerator(trustList, resolvePeerIp) {
|
|
12
|
+
return (c) => {
|
|
13
|
+
// Prefer authenticated user when present — auth-bound limits are
|
|
14
|
+
// never affected by IP trust, since the key is identity-based.
|
|
15
|
+
const user = c.get("user");
|
|
16
|
+
if (user?.id)
|
|
17
|
+
return `user:${user.id}`;
|
|
18
|
+
const peerIp = resolvePeerIp(c);
|
|
19
|
+
const xff = c.req.header("x-forwarded-for");
|
|
20
|
+
return `ip:${resolveClientIp({ peerIp, xff, trustProxy: trustList })}`;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function setHeaders(c, used, limit, windowMs, resetAtMs, legacy) {
|
|
24
|
+
const remaining = Math.max(0, limit - used);
|
|
25
|
+
const windowSec = Math.ceil(windowMs / 1000);
|
|
26
|
+
const resetEpochSec = Math.ceil(resetAtMs / 1000);
|
|
27
|
+
// RFC-draft headers (draft-ietf-httpapi-ratelimit-headers-10).
|
|
28
|
+
c.header("RateLimit-Limit", String(limit));
|
|
29
|
+
c.header("RateLimit-Remaining", String(remaining));
|
|
30
|
+
c.header("RateLimit-Policy", `${limit};w=${windowSec}`);
|
|
31
|
+
if (legacy) {
|
|
32
|
+
c.header("X-RateLimit-Limit", String(limit));
|
|
33
|
+
c.header("X-RateLimit-Remaining", String(remaining));
|
|
34
|
+
c.header("X-RateLimit-Reset", String(resetEpochSec));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function rateLimit(opts) {
|
|
38
|
+
if (opts.windowMs <= 0 || opts.max <= 0) {
|
|
39
|
+
throw new Error("rateLimit(): windowMs and max must be positive");
|
|
40
|
+
}
|
|
41
|
+
const trustList = compileTrustProxy(opts.trustProxy);
|
|
42
|
+
const resolvePeerIp = opts.resolvePeerIp ?? defaultResolvePeerIp;
|
|
43
|
+
const keyGen = opts.keyGenerator ?? makeDefaultKeyGenerator(trustList, resolvePeerIp);
|
|
44
|
+
const onBackendError = opts.onBackendError ?? "deny";
|
|
45
|
+
const log = opts.logger ?? defaultLogger;
|
|
46
|
+
const scopePrefix = opts.scope ? `${opts.scope}:` : "";
|
|
47
|
+
const middleware = async (c, next) => {
|
|
48
|
+
const key = scopePrefix + keyGen(c);
|
|
49
|
+
const now = Date.now();
|
|
50
|
+
let result;
|
|
51
|
+
try {
|
|
52
|
+
result = await opts.backend.check({
|
|
53
|
+
key,
|
|
54
|
+
windowMs: opts.windowMs,
|
|
55
|
+
max: opts.max,
|
|
56
|
+
now,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
// Backend failure (e.g., Redis down). Apply the configured policy.
|
|
61
|
+
log.warn({ err, key, policy: onBackendError }, "ratelimit.backend_error");
|
|
62
|
+
if (onBackendError === "allow")
|
|
63
|
+
return next();
|
|
64
|
+
// 'deny' — fail closed
|
|
65
|
+
const retryAfterSec = Math.max(1, Math.ceil(opts.windowMs / 1000));
|
|
66
|
+
throw new RateLimitError(retryAfterSec, "Rate limiter unavailable");
|
|
67
|
+
}
|
|
68
|
+
setHeaders(c, result.used, result.limit, opts.windowMs, result.resetAtMs, opts.legacyHeaders ?? false);
|
|
69
|
+
if (!result.allowed) {
|
|
70
|
+
const retryAfterSec = Math.max(1, Math.ceil((result.resetAtMs - now) / 1000));
|
|
71
|
+
c.header("Retry-After", String(retryAfterSec));
|
|
72
|
+
throw new RateLimitError(retryAfterSec);
|
|
73
|
+
}
|
|
74
|
+
return next();
|
|
75
|
+
};
|
|
76
|
+
const tag = {
|
|
77
|
+
windowMs: opts.windowMs,
|
|
78
|
+
max: opts.max,
|
|
79
|
+
scope: opts.scope,
|
|
80
|
+
};
|
|
81
|
+
setMetaTag(middleware, RATE_LIMIT_META, tag);
|
|
82
|
+
return middleware;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=rateLimit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rateLimit.js","sourceRoot":"","sources":["../../../src/http/middleware/rateLimit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { MiddlewareHandler } from "hono";
|
|
2
|
+
import type { AuthenticatedAccount, AuthProvider } from "../../app/auth/AuthProvider.js";
|
|
3
|
+
/**
|
|
4
|
+
* `requireAuth({ provider, ... })` — Hono middleware factory that runs the
|
|
5
|
+
* configured `AuthProvider` chain (verify + resolve) and attaches the
|
|
6
|
+
* authenticated `Account` to `c.set('user', ...)`.
|
|
7
|
+
*
|
|
8
|
+
* Replaces v3's `JwtAuthMiddleware`. Key differences:
|
|
9
|
+
*
|
|
10
|
+
* 1. **Pluggable**. Backed by the `AuthProvider` interface; Firebase is
|
|
11
|
+
* adapter #1, but any v4.x adapter (Better-Auth / Clerk / WorkOS / …)
|
|
12
|
+
* drops in without changing this middleware.
|
|
13
|
+
*
|
|
14
|
+
* 2. **Silent fall-through is opt-in**. The v3 default (no token →
|
|
15
|
+
* `next()` without user) was a footgun. v4 throws `AuthenticationError`
|
|
16
|
+
* when a token is missing unless `optional: true` is set explicitly.
|
|
17
|
+
*
|
|
18
|
+
* 3. **Tagged for the route registry**. `createApp`'s interceptor reads
|
|
19
|
+
* the `AUTH_META` tag to populate the route registry with auth state
|
|
20
|
+
* so MCP tools, `ship-reviewer`, and `/dev/routes` know whether each
|
|
21
|
+
* route requires auth.
|
|
22
|
+
*
|
|
23
|
+
* 4. **Throws AppErrors**, not direct responses. `app.onError(...)` formats
|
|
24
|
+
* them — keeps the response shape consistent across the framework.
|
|
25
|
+
*
|
|
26
|
+
* Failure mapping:
|
|
27
|
+
* - `missing-token` + `optional: false` → 401 `AuthenticationError`
|
|
28
|
+
* - `missing-token` + `optional: true` → `next()` with no user / claims
|
|
29
|
+
* - any other verify failure (invalid / expired / revoked / issuer-mismatch)
|
|
30
|
+
* → 401 `AuthenticationError` regardless of `optional` (a present-but-bad
|
|
31
|
+
* token is always rejected)
|
|
32
|
+
* - verify ok + resolve returns null + `onUnknownAccount: 'reject'` (default)
|
|
33
|
+
* → 403 `AuthorizationError`
|
|
34
|
+
* - verify ok + resolve null + `onUnknownAccount: 'next'` → `next()` with
|
|
35
|
+
* `claims` set but no `user`
|
|
36
|
+
*
|
|
37
|
+
* On success: sets `c.set('user', account)` and `c.set('claims', claims)`,
|
|
38
|
+
* publishes `account.id` to `RequestContext.userId` (so audit-stamping and
|
|
39
|
+
* structured logging see the actor), then `next()`.
|
|
40
|
+
*/
|
|
41
|
+
export interface RequireAuthOptions<TAccount extends AuthenticatedAccount = AuthenticatedAccount> {
|
|
42
|
+
/** The AuthProvider to use. Required. */
|
|
43
|
+
provider: AuthProvider<TAccount>;
|
|
44
|
+
/**
|
|
45
|
+
* If true, missing tokens fall through to `next()` without throwing. Default
|
|
46
|
+
* `false`. Use this for endpoints that serve unauthenticated traffic with
|
|
47
|
+
* degraded data (e.g., a public profile page that shows extra fields when
|
|
48
|
+
* logged in).
|
|
49
|
+
*/
|
|
50
|
+
optional?: boolean;
|
|
51
|
+
}
|
|
52
|
+
/** Hono context-variable keys this middleware sets on success. */
|
|
53
|
+
export declare const AUTH_CONTEXT_KEYS: {
|
|
54
|
+
user: "user";
|
|
55
|
+
claims: "claims";
|
|
56
|
+
};
|
|
57
|
+
export declare function requireAuth<TAccount extends AuthenticatedAccount = AuthenticatedAccount>(opts: RequireAuthOptions<TAccount>): MiddlewareHandler;
|
|
58
|
+
//# sourceMappingURL=requireAuth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requireAuth.d.ts","sourceRoot":"","sources":["../../../src/http/middleware/requireAuth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,KAAK,EAEV,oBAAoB,EACpB,YAAY,EAEb,MAAM,gCAAgC,CAAC;AAMxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,MAAM,WAAW,kBAAkB,CAAC,QAAQ,SAAS,oBAAoB,GAAG,oBAAoB;IAC9F,yCAAyC;IACzC,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,kEAAkE;AAClE,eAAO,MAAM,iBAAiB;;;CAG7B,CAAC;AAYF,wBAAgB,WAAW,CAAC,QAAQ,SAAS,oBAAoB,GAAG,oBAAoB,EACtF,IAAI,EAAE,kBAAkB,CAAC,QAAQ,CAAC,GACjC,iBAAiB,CAmDnB"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { setRequestContextField } from "../../app/context/RequestContext.js";
|
|
2
|
+
import { AuthenticationError } from "../errors/AuthenticationError.js";
|
|
3
|
+
import { AuthorizationError } from "../errors/AuthorizationError.js";
|
|
4
|
+
import { AUTH_META, setMetaTag } from "../utils/metaTags.js";
|
|
5
|
+
/** Hono context-variable keys this middleware sets on success. */
|
|
6
|
+
export const AUTH_CONTEXT_KEYS = {
|
|
7
|
+
user: "user",
|
|
8
|
+
claims: "claims",
|
|
9
|
+
};
|
|
10
|
+
function buildProviderContext(c) {
|
|
11
|
+
const headers = {};
|
|
12
|
+
// Hono normalizes header names to lowercase; AuthProvider adapters
|
|
13
|
+
// (firebase) expect lowercase too.
|
|
14
|
+
c.req.raw.headers.forEach((value, key) => {
|
|
15
|
+
headers[key.toLowerCase()] = value;
|
|
16
|
+
});
|
|
17
|
+
return { headers };
|
|
18
|
+
}
|
|
19
|
+
export function requireAuth(opts) {
|
|
20
|
+
const { provider } = opts;
|
|
21
|
+
const optional = opts.optional ?? false;
|
|
22
|
+
const middleware = async (c, next) => {
|
|
23
|
+
const providerCtx = buildProviderContext(c);
|
|
24
|
+
const verifyResult = await provider.verify(providerCtx);
|
|
25
|
+
if (!verifyResult.ok) {
|
|
26
|
+
if (verifyResult.reason === "missing-token") {
|
|
27
|
+
if (optional)
|
|
28
|
+
return next();
|
|
29
|
+
throw new AuthenticationError(verifyResult.message ?? "Authentication required");
|
|
30
|
+
}
|
|
31
|
+
// present-but-bad token is always rejected, even when optional=true
|
|
32
|
+
throw new AuthenticationError(verifyResult.message ?? `Authentication failed (${verifyResult.reason})`);
|
|
33
|
+
}
|
|
34
|
+
const claims = verifyResult.claims;
|
|
35
|
+
const account = await provider.resolve(claims);
|
|
36
|
+
if (account === null) {
|
|
37
|
+
const policy = provider.onUnknownAccount ?? "reject";
|
|
38
|
+
if (policy === "next") {
|
|
39
|
+
c.set(AUTH_CONTEXT_KEYS.claims, claims);
|
|
40
|
+
return next();
|
|
41
|
+
}
|
|
42
|
+
// 'create' is the provider's responsibility — if a provider wants
|
|
43
|
+
// first-sight account creation it does it inside `resolve()` itself.
|
|
44
|
+
// Here we treat 'create' as 'reject' (no-op) since we can't synthesize
|
|
45
|
+
// an account.
|
|
46
|
+
throw new AuthorizationError("No account registered for this credential");
|
|
47
|
+
}
|
|
48
|
+
c.set(AUTH_CONTEXT_KEYS.user, account);
|
|
49
|
+
c.set(AUTH_CONTEXT_KEYS.claims, claims);
|
|
50
|
+
// Publish the resolved account id to the request context so the logger,
|
|
51
|
+
// `DrizzleEntityService` audit-stamping (createdBy / updatedBy), and OTel
|
|
52
|
+
// spans all see the actor. No-op (returns false) outside an active context.
|
|
53
|
+
setRequestContextField("userId", account.id);
|
|
54
|
+
return next();
|
|
55
|
+
};
|
|
56
|
+
const tag = {
|
|
57
|
+
required: !optional,
|
|
58
|
+
providerName: provider.name,
|
|
59
|
+
};
|
|
60
|
+
setMetaTag(middleware, AUTH_META, tag);
|
|
61
|
+
return middleware;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=requireAuth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requireAuth.js","sourceRoot":"","sources":["../../../src/http/middleware/requireAuth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { MiddlewareHandler } from "hono";
|
|
2
|
+
/**
|
|
3
|
+
* `requirePermission(...slugs)` — Hono middleware factory that enforces
|
|
4
|
+
* the authenticated user has at least one of the supplied permission slugs
|
|
5
|
+
* (OR semantics within a single call).
|
|
6
|
+
*
|
|
7
|
+
* Replaces v3's `@HasPermission` decorator. To express AND across multiple
|
|
8
|
+
* permission groups, chain multiple `requirePermission()` middlewares —
|
|
9
|
+
* `createApp`'s registry interceptor unions slugs across calls so the
|
|
10
|
+
* registry shows the full set, and the runtime checks each call gates
|
|
11
|
+
* independently.
|
|
12
|
+
*
|
|
13
|
+
* Must run *after* a `requireAuth(...)` middleware on the same route — if
|
|
14
|
+
* `c.get('user')` is unset, this throws `AuthenticationError`. The user
|
|
15
|
+
* object must implement `hasPermission(slug)`; if not, this throws an
|
|
16
|
+
* Error (configuration issue → 500).
|
|
17
|
+
*
|
|
18
|
+
* Tagged with `PERMISSION_META` so `createApp`'s interceptor and downstream
|
|
19
|
+
* tooling (MCP `describe_route`, `ship-reviewer`, `/dev/routes`) see the
|
|
20
|
+
* permission slugs the route requires.
|
|
21
|
+
*/
|
|
22
|
+
export declare function requirePermission(...slugs: string[]): MiddlewareHandler;
|
|
23
|
+
//# sourceMappingURL=requirePermission.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requirePermission.d.ts","sourceRoot":"","sources":["../../../src/http/middleware/requirePermission.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAM9C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAqCvE"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { AuthenticationError } from "../errors/AuthenticationError.js";
|
|
2
|
+
import { AuthorizationError } from "../errors/AuthorizationError.js";
|
|
3
|
+
import { PERMISSION_META, setMetaTag } from "../utils/metaTags.js";
|
|
4
|
+
/**
|
|
5
|
+
* `requirePermission(...slugs)` — Hono middleware factory that enforces
|
|
6
|
+
* the authenticated user has at least one of the supplied permission slugs
|
|
7
|
+
* (OR semantics within a single call).
|
|
8
|
+
*
|
|
9
|
+
* Replaces v3's `@HasPermission` decorator. To express AND across multiple
|
|
10
|
+
* permission groups, chain multiple `requirePermission()` middlewares —
|
|
11
|
+
* `createApp`'s registry interceptor unions slugs across calls so the
|
|
12
|
+
* registry shows the full set, and the runtime checks each call gates
|
|
13
|
+
* independently.
|
|
14
|
+
*
|
|
15
|
+
* Must run *after* a `requireAuth(...)` middleware on the same route — if
|
|
16
|
+
* `c.get('user')` is unset, this throws `AuthenticationError`. The user
|
|
17
|
+
* object must implement `hasPermission(slug)`; if not, this throws an
|
|
18
|
+
* Error (configuration issue → 500).
|
|
19
|
+
*
|
|
20
|
+
* Tagged with `PERMISSION_META` so `createApp`'s interceptor and downstream
|
|
21
|
+
* tooling (MCP `describe_route`, `ship-reviewer`, `/dev/routes`) see the
|
|
22
|
+
* permission slugs the route requires.
|
|
23
|
+
*/
|
|
24
|
+
export function requirePermission(...slugs) {
|
|
25
|
+
if (slugs.length === 0) {
|
|
26
|
+
throw new Error("requirePermission(): at least one slug must be provided");
|
|
27
|
+
}
|
|
28
|
+
const middleware = async (c, next) => {
|
|
29
|
+
const user = c.get("user");
|
|
30
|
+
if (!user) {
|
|
31
|
+
throw new AuthenticationError("requirePermission: no authenticated user — apply requireAuth(...) before this middleware");
|
|
32
|
+
}
|
|
33
|
+
if (typeof user.hasPermission !== "function") {
|
|
34
|
+
throw new Error("requirePermission: the resolved user does not implement hasPermission(slug). " +
|
|
35
|
+
"Ensure your AuthProvider's resolve() returns an Account that does.");
|
|
36
|
+
}
|
|
37
|
+
for (const slug of slugs) {
|
|
38
|
+
const ok = await user.hasPermission(slug);
|
|
39
|
+
if (ok)
|
|
40
|
+
return next();
|
|
41
|
+
}
|
|
42
|
+
throw new AuthorizationError(slugs.length === 1
|
|
43
|
+
? `Missing required permission: ${slugs[0]}`
|
|
44
|
+
: `Requires one of: ${slugs.join(", ")}`);
|
|
45
|
+
};
|
|
46
|
+
const tag = { permissions: [...slugs] };
|
|
47
|
+
setMetaTag(middleware, PERMISSION_META, tag);
|
|
48
|
+
return middleware;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=requirePermission.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requirePermission.js","sourceRoot":"","sources":["../../../src/http/middleware/requirePermission.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,eAAe,EAAuB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAExF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAG,KAAe;IAClD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,UAAU,GAAsB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACtD,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAe,CAAqC,CAAC;QAExE,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,mBAAmB,CAC3B,0FAA0F,CAC3F,CAAC;QACJ,CAAC;QAED,IAAI,OAAO,IAAI,CAAC,aAAa,KAAK,UAAU,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CACb,+EAA+E;gBAC7E,oEAAoE,CACvE,CAAC;QACJ,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAC1C,IAAI,EAAE;gBAAE,OAAO,IAAI,EAAE,CAAC;QACxB,CAAC;QAED,MAAM,IAAI,kBAAkB,CAC1B,KAAK,CAAC,MAAM,KAAK,CAAC;YAChB,CAAC,CAAC,gCAAgC,KAAK,CAAC,CAAC,CAAC,EAAE;YAC5C,CAAC,CAAC,oBAAoB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC3C,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,GAAG,GAAmB,EAAE,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;IACxD,UAAU,CAAC,UAAU,EAAE,eAAe,EAAE,GAAG,CAAC,CAAC;IAE7C,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Context, MiddlewareHandler } from "hono";
|
|
2
|
+
/**
|
|
3
|
+
* `resolveTenant()` — opt-in middleware that resolves the active tenant for the
|
|
4
|
+
* request and publishes it to `RequestContext.tenantId`.
|
|
5
|
+
*
|
|
6
|
+
* The framework convention is: code reads the active tenant from
|
|
7
|
+
* `RequestContext.tenantId`, NEVER from `account.tenantId` directly. That
|
|
8
|
+
* indirection is what keeps a future one-tenant-per-user → membership move
|
|
9
|
+
* (Model A → B) a one-middleware change — swap this resolver and every
|
|
10
|
+
* downstream read is unaffected.
|
|
11
|
+
*
|
|
12
|
+
* Default (Model A — one tenant per account): read `tenantId` off the
|
|
13
|
+
* authenticated account that `requireAuth` placed on the Hono context. Wire it
|
|
14
|
+
* AFTER `requireAuth`:
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* app.use("*", requireAuth({ provider }));
|
|
18
|
+
* app.use("*", resolveTenant());
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* For custom resolution (a tenant header, a sub-domain, a membership lookup),
|
|
22
|
+
* pass `resolve`:
|
|
23
|
+
*
|
|
24
|
+
* ```ts
|
|
25
|
+
* app.use("*", resolveTenant({ resolve: (c) => c.req.header("x-tenant-id") }));
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* This is a thin, opt-in helper — single-tenant products never wire it and
|
|
29
|
+
* `RequestContext.tenantId` stays `undefined`. Tenant *enforcement*
|
|
30
|
+
* (auto-scoping every query) is deferred to V8; this only resolves + publishes.
|
|
31
|
+
*/
|
|
32
|
+
export interface ResolveTenantOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Custom resolver. Receives the Hono context and returns the active tenant id
|
|
35
|
+
* (or `undefined` / `null` to leave `RequestContext.tenantId` unset). Default:
|
|
36
|
+
* read `tenantId` off the authenticated account (`c.get("user")`).
|
|
37
|
+
*/
|
|
38
|
+
resolve?: (c: Context) => string | null | undefined | Promise<string | null | undefined>;
|
|
39
|
+
}
|
|
40
|
+
export declare function resolveTenant(opts?: ResolveTenantOptions): MiddlewareHandler;
|
|
41
|
+
//# sourceMappingURL=resolveTenant.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveTenant.d.ts","sourceRoot":"","sources":["../../../src/http/middleware/resolveTenant.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAIvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CAC1F;AAED,wBAAgB,aAAa,CAAC,IAAI,GAAE,oBAAyB,GAAG,iBAAiB,CAchF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { setRequestContextField } from "../../app/context/RequestContext.js";
|
|
2
|
+
import { AUTH_CONTEXT_KEYS } from "./requireAuth.js";
|
|
3
|
+
export function resolveTenant(opts = {}) {
|
|
4
|
+
const resolve = opts.resolve ??
|
|
5
|
+
((c) => {
|
|
6
|
+
const account = c.get(AUTH_CONTEXT_KEYS.user);
|
|
7
|
+
return account?.tenantId;
|
|
8
|
+
});
|
|
9
|
+
return async (c, next) => {
|
|
10
|
+
const tenantId = await resolve(c);
|
|
11
|
+
// No-op (returns false) when called outside an active RequestContext.
|
|
12
|
+
if (tenantId)
|
|
13
|
+
setRequestContextField("tenantId", tenantId);
|
|
14
|
+
return next();
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=resolveTenant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveTenant.js","sourceRoot":"","sources":["../../../src/http/middleware/resolveTenant.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAyCrD,MAAM,UAAU,aAAa,CAAC,OAA6B,EAAE;IAC3D,MAAM,OAAO,GACX,IAAI,CAAC,OAAO;QACZ,CAAC,CAAC,CAAU,EAAE,EAAE;YACd,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAa,CAAsC,CAAC;YAC5F,OAAO,OAAO,EAAE,QAAQ,CAAC;QAC3B,CAAC,CAAC,CAAC;IAEL,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACvB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;QAClC,sEAAsE;QACtE,IAAI,QAAQ;YAAE,sBAAsB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC3D,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
import type { SSEStreamingApi } from "hono/streaming";
|
|
3
|
+
/**
|
|
4
|
+
* `streamSSE(c, fn, opts?)` — framework wrapper around `hono/streaming`'s
|
|
5
|
+
* SSE helper. Adds an OTel span around the streaming callback's lifetime
|
|
6
|
+
* and a documented home for v4.x SSE-related helpers (LLM streaming, etc.).
|
|
7
|
+
*
|
|
8
|
+
* Re-exports `SSEStreamingApi` so consumers don't have to import from two
|
|
9
|
+
* paths to type their stream callback.
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { streamSSE } from "@sixthsummit/ship-api/http/streaming/sse";
|
|
14
|
+
*
|
|
15
|
+
* app.get("/feed", requireAuth({ provider }), (c) =>
|
|
16
|
+
* streamSSE(c, async (stream) => {
|
|
17
|
+
* for await (const event of someEventSource()) {
|
|
18
|
+
* if (stream.aborted) break; // honor client disconnect
|
|
19
|
+
* await stream.writeSSE({ event: event.type, data: JSON.stringify(event) });
|
|
20
|
+
* }
|
|
21
|
+
* }, { spanName: "feed.subscribe" }),
|
|
22
|
+
* );
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export type { SSEStreamingApi };
|
|
26
|
+
export interface StreamSSEOptions {
|
|
27
|
+
/** OTel span name. Default `"http.sse"`. */
|
|
28
|
+
spanName?: string;
|
|
29
|
+
}
|
|
30
|
+
export declare function streamSSE(c: Context, fn: (stream: SSEStreamingApi) => Promise<void>, opts?: StreamSSEOptions): Response;
|
|
31
|
+
//# sourceMappingURL=sse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/http/streaming/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAItD;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC,MAAM,WAAW,gBAAgB;IAC/B,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,SAAS,CACvB,CAAC,EAAE,OAAO,EACV,EAAE,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,EAC9C,IAAI,GAAE,gBAAqB,GAC1B,QAAQ,CAOV"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { streamSSE as honoStreamSSE } from "hono/streaming";
|
|
2
|
+
import { withSpan } from "../../observability/tracing.js";
|
|
3
|
+
export function streamSSE(c, fn, opts = {}) {
|
|
4
|
+
const spanName = opts.spanName ?? "http.sse";
|
|
5
|
+
return honoStreamSSE(c, async (stream) => {
|
|
6
|
+
await withSpan(spanName, async () => {
|
|
7
|
+
await fn(stream);
|
|
8
|
+
});
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=sse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../../../src/http/streaming/sse.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAgC1D,MAAM,UAAU,SAAS,CACvB,CAAU,EACV,EAA8C,EAC9C,OAAyB,EAAE;IAE3B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,UAAU,CAAC;IAC7C,OAAO,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACvC,MAAM,QAAQ,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;YAClC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
import { logger as defaultLogger } from "../../observability/logger.js";
|
|
3
|
+
/**
|
|
4
|
+
* `streamLLM(c, events, opts?)` — Hono-aware SSE bridge for LLM stream
|
|
5
|
+
* events. Pipes any `AsyncIterable<{ type, ... }>` (typically the
|
|
6
|
+
* `streamComplete()` output of an `LLMProvider` adapter from
|
|
7
|
+
* `libraries/ai`) through `streamSSE`, with client-disconnect
|
|
8
|
+
* propagation upstream.
|
|
9
|
+
*
|
|
10
|
+
* Event format:
|
|
11
|
+
* - `event:` field = the iterator value's `type` field
|
|
12
|
+
* - `data:` field = JSON-serialized rest of the value (everything
|
|
13
|
+
* except `type`)
|
|
14
|
+
*
|
|
15
|
+
* Disconnect handling: when the request client disconnects,
|
|
16
|
+
* `stream.aborted` flips true. We notice between iterator ticks and
|
|
17
|
+
* call `iterator.return?.()` so the upstream generator can run its
|
|
18
|
+
* `finally` (closes provider stream, cancels in-flight HTTP, etc.).
|
|
19
|
+
*
|
|
20
|
+
* Errors: if the iterator throws, the error is forwarded as a final
|
|
21
|
+
* `event: error` SSE event with `{ message }` payload, then the
|
|
22
|
+
* stream closes. The optional `onError` hook is called *before* the
|
|
23
|
+
* error event is written so consumers can log / record without
|
|
24
|
+
* blocking the close.
|
|
25
|
+
*
|
|
26
|
+
* Provider-agnostic by design — no import from `libraries/ai`. The
|
|
27
|
+
* library's `StreamEvent` union (`start` / `text_delta` /
|
|
28
|
+
* `tool_use_*` / `stop`) is just one valid event source; consumers
|
|
29
|
+
* with a different shape (custom event taxonomy) can pipe through
|
|
30
|
+
* unchanged.
|
|
31
|
+
*
|
|
32
|
+
* Usage:
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { streamLLM } from "@sixthsummit/ship-api/http/streaming/streamLLM";
|
|
35
|
+
* import { AnthropicAdapter } from "@sixthsummit/ship-api/libraries/ai";
|
|
36
|
+
*
|
|
37
|
+
* const llm = new AnthropicAdapter({ apiKey: env.ANTHROPIC_API_KEY });
|
|
38
|
+
*
|
|
39
|
+
* app.post("/chat", validate("json", schema), async (c) => {
|
|
40
|
+
* const { prompt } = c.req.valid("json");
|
|
41
|
+
* const stream = llm.streamComplete({
|
|
42
|
+
* model: "claude-opus-4-7",
|
|
43
|
+
* messages: [{ role: "user", content: prompt }],
|
|
44
|
+
* });
|
|
45
|
+
* return streamLLM(c, stream, { spanName: "chat.stream" });
|
|
46
|
+
* });
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export interface StreamLLMOptions {
|
|
50
|
+
/** OTel span name. Default `"llm.stream"`. */
|
|
51
|
+
spanName?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Called once if the upstream iterator throws, before the final
|
|
54
|
+
* `event: error` SSE write. Use to log / record the failure;
|
|
55
|
+
* throwing here is swallowed so the close still completes.
|
|
56
|
+
*/
|
|
57
|
+
onError?: (err: Error) => Promise<void> | void;
|
|
58
|
+
/**
|
|
59
|
+
* Override how the SSE event id field is generated. Defaults to a
|
|
60
|
+
* monotonically-incrementing counter — sufficient for replay scope
|
|
61
|
+
* within a single response.
|
|
62
|
+
*/
|
|
63
|
+
generateEventId?: (event: LLMStreamEvent, index: number) => string;
|
|
64
|
+
/**
|
|
65
|
+
* Maximum serialized bytes per event payload (F15). Events whose
|
|
66
|
+
* `JSON.stringify(payload)` exceeds this are skipped + logged +
|
|
67
|
+
* counted on the `stream.event.dropped_oversized` OTel counter.
|
|
68
|
+
* Default 256 KB. A misbehaving upstream provider that emits
|
|
69
|
+
* multi-megabyte single events (e.g. a duplicated tool-call
|
|
70
|
+
* argument) would otherwise amplify into a bandwidth + client-
|
|
71
|
+
* memory DoS at the consumer.
|
|
72
|
+
*/
|
|
73
|
+
maxEventBytes?: number;
|
|
74
|
+
/**
|
|
75
|
+
* Tag attached to the `dropped_oversized` counter and the warn
|
|
76
|
+
* line emitted on oversize. Useful for distinguishing "Anthropic
|
|
77
|
+
* stream went wild" from "OpenAI stream went wild" in dashboards.
|
|
78
|
+
* Defaults to the event's `type` field at log time.
|
|
79
|
+
*/
|
|
80
|
+
provider?: string;
|
|
81
|
+
/** Override the framework default pino logger (tests). */
|
|
82
|
+
logger?: typeof defaultLogger;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Minimum shape `streamLLM` requires. Any object with a string `type`
|
|
86
|
+
* and arbitrary other JSON-serializable fields fits — including the
|
|
87
|
+
* full `StreamEvent` union from `libraries/ai`.
|
|
88
|
+
*/
|
|
89
|
+
export interface LLMStreamEvent {
|
|
90
|
+
type: string;
|
|
91
|
+
[key: string]: unknown;
|
|
92
|
+
}
|
|
93
|
+
export declare function streamLLM(c: Context, events: AsyncIterable<LLMStreamEvent>, opts?: StreamLLMOptions): Response;
|
|
94
|
+
//# sourceMappingURL=streamLLM.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamLLM.d.ts","sourceRoot":"","sources":["../../../src/http/streaming/streamLLM.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,+BAA+B,CAAC;AA8BxE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC/C;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACnE;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,OAAO,aAAa,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,wBAAgB,SAAS,CACvB,CAAC,EAAE,OAAO,EACV,MAAM,EAAE,aAAa,CAAC,cAAc,CAAC,EACrC,IAAI,GAAE,gBAAqB,GAC1B,QAAQ,CAoDV"}
|