@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,138 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AuthUrlOptions,
|
|
3
|
+
ExchangeCodeOptions,
|
|
4
|
+
OAuthAdapter,
|
|
5
|
+
OAuthClientCredentials,
|
|
6
|
+
TokenResponse,
|
|
7
|
+
} from "./OAuthAdapter.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* In-memory `OAuthAdapter` for tests + local development. Returns
|
|
11
|
+
* deterministic responses, captures every call for assertions, and
|
|
12
|
+
* lets tests preset the responses to simulate provider failures.
|
|
13
|
+
*
|
|
14
|
+
* Usage in route tests:
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* const adapter = new MockOAuthAdapter("mock-google");
|
|
18
|
+
* adapter.setExchangeResponse({ accessToken: "tok", ... });
|
|
19
|
+
* const registry = oauthAdapterRegistry(adapter);
|
|
20
|
+
* defineOAuthRoutes(app, { service, provider, adapters: registry });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export class MockOAuthAdapter implements OAuthAdapter {
|
|
24
|
+
readonly providerCode: string;
|
|
25
|
+
|
|
26
|
+
/** Each call to `buildAuthorizationUrl` is captured here. */
|
|
27
|
+
authUrlCalls: Array<{
|
|
28
|
+
credentials: OAuthClientCredentials;
|
|
29
|
+
opts: AuthUrlOptions;
|
|
30
|
+
}> = [];
|
|
31
|
+
exchangeCalls: Array<{
|
|
32
|
+
code: string;
|
|
33
|
+
credentials: OAuthClientCredentials;
|
|
34
|
+
opts?: ExchangeCodeOptions;
|
|
35
|
+
}> = [];
|
|
36
|
+
refreshCalls: Array<{
|
|
37
|
+
refreshToken: string;
|
|
38
|
+
credentials: OAuthClientCredentials;
|
|
39
|
+
}> = [];
|
|
40
|
+
revokeCalls: Array<{
|
|
41
|
+
accessToken: string;
|
|
42
|
+
credentials: OAuthClientCredentials;
|
|
43
|
+
}> = [];
|
|
44
|
+
|
|
45
|
+
private exchangeResponse: TokenResponse = {
|
|
46
|
+
accessToken: "mock-access",
|
|
47
|
+
refreshToken: "mock-refresh",
|
|
48
|
+
expiresAt: new Date(Date.now() + 3_600_000),
|
|
49
|
+
scope: "openid",
|
|
50
|
+
tokenType: "Bearer",
|
|
51
|
+
metadata: { source: "mock" },
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
private refreshResponse: TokenResponse = {
|
|
55
|
+
accessToken: "mock-access-refreshed",
|
|
56
|
+
refreshToken: "mock-refresh",
|
|
57
|
+
expiresAt: new Date(Date.now() + 3_600_000),
|
|
58
|
+
scope: "openid",
|
|
59
|
+
tokenType: "Bearer",
|
|
60
|
+
metadata: { source: "mock-refresh" },
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
private providerAccountId = "mock-provider-account-1";
|
|
64
|
+
|
|
65
|
+
/** Set in tests to make the next exchange/refresh throw. */
|
|
66
|
+
private exchangeError: Error | undefined;
|
|
67
|
+
private refreshError: Error | undefined;
|
|
68
|
+
|
|
69
|
+
constructor(providerCode = "mock") {
|
|
70
|
+
this.providerCode = providerCode;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
buildAuthorizationUrl(credentials: OAuthClientCredentials, opts: AuthUrlOptions): string {
|
|
74
|
+
this.authUrlCalls.push({ credentials, opts });
|
|
75
|
+
const params = new URLSearchParams({
|
|
76
|
+
client_id: credentials.clientId,
|
|
77
|
+
redirect_uri: credentials.redirectUri,
|
|
78
|
+
response_type: "code",
|
|
79
|
+
scope: opts.scopes.join(" "),
|
|
80
|
+
state: opts.state,
|
|
81
|
+
});
|
|
82
|
+
return `https://mock.example.test/authorize?${params.toString()}`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async exchangeCodeForTokens(
|
|
86
|
+
code: string,
|
|
87
|
+
credentials: OAuthClientCredentials,
|
|
88
|
+
opts: ExchangeCodeOptions = {},
|
|
89
|
+
): Promise<TokenResponse> {
|
|
90
|
+
this.exchangeCalls.push({ code, credentials, opts });
|
|
91
|
+
if (this.exchangeError) throw this.exchangeError;
|
|
92
|
+
return this.exchangeResponse;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async refreshTokens(
|
|
96
|
+
refreshToken: string,
|
|
97
|
+
credentials: OAuthClientCredentials,
|
|
98
|
+
): Promise<TokenResponse> {
|
|
99
|
+
this.refreshCalls.push({ refreshToken, credentials });
|
|
100
|
+
if (this.refreshError) throw this.refreshError;
|
|
101
|
+
return this.refreshResponse;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async getProviderAccountId(): Promise<string> {
|
|
105
|
+
return this.providerAccountId;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async revokeAccess(accessToken: string, credentials: OAuthClientCredentials): Promise<void> {
|
|
109
|
+
this.revokeCalls.push({ accessToken, credentials });
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ─── Test-only setters ────────────────────────────────────────────
|
|
113
|
+
|
|
114
|
+
setExchangeResponse(response: TokenResponse): this {
|
|
115
|
+
this.exchangeResponse = response;
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
setRefreshResponse(response: TokenResponse): this {
|
|
120
|
+
this.refreshResponse = response;
|
|
121
|
+
return this;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
setProviderAccountId(id: string): this {
|
|
125
|
+
this.providerAccountId = id;
|
|
126
|
+
return this;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
failNextExchange(err: Error): this {
|
|
130
|
+
this.exchangeError = err;
|
|
131
|
+
return this;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
failNextRefresh(err: Error): this {
|
|
135
|
+
this.refreshError = err;
|
|
136
|
+
return this;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v4 OAuth provider adapter contract.
|
|
3
|
+
*
|
|
4
|
+
* Provider-specific quirks (Google's `prompt=consent` to force refresh-
|
|
5
|
+
* token reissue, Microsoft's tenant-aware authority URL, Gmail's
|
|
6
|
+
* scope-narrowing helpers) live behind concrete adapter implementations;
|
|
7
|
+
* the framework only sees this interface.
|
|
8
|
+
*
|
|
9
|
+
* Adapters MUST:
|
|
10
|
+
* - Build a provider-compatible authorization URL with the supplied
|
|
11
|
+
* `state` opaque (the framework signs / verifies state — adapters
|
|
12
|
+
* just round-trip the string).
|
|
13
|
+
* - Exchange an authorization code for tokens using only the standard
|
|
14
|
+
* `OAuthClientCredentials` shape — no globals, no env reads.
|
|
15
|
+
* - Refresh tokens via the provider's documented refresh-token flow.
|
|
16
|
+
* - Return a `TokenResponse` that maps cleanly to the schema columns:
|
|
17
|
+
* `accessToken`, `refreshToken?`, `expiresAt?`, `scope?`,
|
|
18
|
+
* `tokenType?`, `metadata?`. Provider extras land in `metadata`.
|
|
19
|
+
* - Throw `OAuthAdapterError` (subclassed appropriately) on
|
|
20
|
+
* translation failures so the routes layer can map to AppError /
|
|
21
|
+
* status codes consistently.
|
|
22
|
+
*
|
|
23
|
+
* Adapters SHOULD:
|
|
24
|
+
* - Accept an injected `fetch` in their constructor so tests can
|
|
25
|
+
* swap it without monkey-patching globals.
|
|
26
|
+
* - Be fetch-based when possible — no axios / SDK requirements when
|
|
27
|
+
* the OAuth flow is plain HTTP. SDK-backed adapters (e.g.
|
|
28
|
+
* `googleapis`) declare the SDK as an optional dep so consumers
|
|
29
|
+
* who don't use those adapters don't pay for them.
|
|
30
|
+
*
|
|
31
|
+
* The interface deliberately differs from v3's
|
|
32
|
+
* `IOAuthProviderAdapter` in two ways:
|
|
33
|
+
* - State is an opaque string the framework owns end-to-end (signs +
|
|
34
|
+
* verifies + binds to user). v3 had adapters JSON-encode `userId`
|
|
35
|
+
* into state, mixing concerns; v4 keeps state opaque.
|
|
36
|
+
* - `userId: bigint` parameter is gone. The framework holds the user
|
|
37
|
+
* identity; adapters never see it. That's a security property —
|
|
38
|
+
* v3's adapters could in principle leak userId into provider
|
|
39
|
+
* telemetry by encoding it into URLs they construct.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
export interface OAuthClientCredentials {
|
|
43
|
+
clientId: string;
|
|
44
|
+
clientSecret: string;
|
|
45
|
+
redirectUri: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface AuthUrlOptions {
|
|
49
|
+
/**
|
|
50
|
+
* The signed/opaque state the framework gives the adapter to embed
|
|
51
|
+
* in the URL. Passed back to the framework on the callback for
|
|
52
|
+
* verification — adapters never inspect it.
|
|
53
|
+
*/
|
|
54
|
+
state: string;
|
|
55
|
+
/** OAuth scopes to request. Provider-specific values. */
|
|
56
|
+
scopes: readonly string[];
|
|
57
|
+
/**
|
|
58
|
+
* Provider-specific extras the cross-provider surface doesn't
|
|
59
|
+
* model (`access_type: "offline"`, `prompt: "consent"`, Microsoft
|
|
60
|
+
* `tenant`, …). Adapters may consult this freely.
|
|
61
|
+
*/
|
|
62
|
+
providerOptions?: Record<string, unknown>;
|
|
63
|
+
/**
|
|
64
|
+
* PKCE code-challenge — the SHA-256 hash of the framework-generated
|
|
65
|
+
* code-verifier, base64url-encoded. When supplied, the adapter
|
|
66
|
+
* emits `code_challenge` + `code_challenge_method` on the
|
|
67
|
+
* authorization URL.
|
|
68
|
+
*
|
|
69
|
+
* The framework's routes layer generates the verifier, computes
|
|
70
|
+
* the challenge, signs the verifier into state, and passes the
|
|
71
|
+
* challenge here. Adapters never see the verifier on this call.
|
|
72
|
+
* The verifier comes back later via `exchangeCodeForTokens`'s
|
|
73
|
+
* `opts.codeVerifier`.
|
|
74
|
+
*
|
|
75
|
+
* Server-side flows are confidential clients, so PKCE is
|
|
76
|
+
* defense-in-depth — defends against the (rare) case where the
|
|
77
|
+
* authorization code is intercepted but the client_secret isn't.
|
|
78
|
+
* OAuth 2.1 makes PKCE mandatory; the framework's posture matches.
|
|
79
|
+
*/
|
|
80
|
+
codeChallenge?: string;
|
|
81
|
+
/** PKCE challenge method. Default `"S256"`; only S256 is recommended. */
|
|
82
|
+
codeChallengeMethod?: "S256" | "plain";
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Per-call options for `exchangeCodeForTokens` / `refreshTokens`.
|
|
87
|
+
* `codeVerifier` is the PKCE counterpart to `AuthUrlOptions.codeChallenge` —
|
|
88
|
+
* the framework's routes layer recovers it from the signed state on
|
|
89
|
+
* callback and passes it here.
|
|
90
|
+
*/
|
|
91
|
+
export interface ExchangeCodeOptions {
|
|
92
|
+
/** Abort the upstream HTTP call. */
|
|
93
|
+
signal?: AbortSignal;
|
|
94
|
+
/**
|
|
95
|
+
* PKCE verifier (the raw secret the framework generated alongside
|
|
96
|
+
* the challenge). Passed verbatim into the provider's token-
|
|
97
|
+
* exchange body as `code_verifier`. Adapters that don't support
|
|
98
|
+
* PKCE (or providers that ignore the field) simply forward it.
|
|
99
|
+
*/
|
|
100
|
+
codeVerifier?: string;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface TokenResponse {
|
|
104
|
+
accessToken: string;
|
|
105
|
+
refreshToken?: string;
|
|
106
|
+
/** Computed expiry instant — adapters convert provider `expires_in` seconds. */
|
|
107
|
+
expiresAt?: Date;
|
|
108
|
+
scope?: string;
|
|
109
|
+
/** Typically `"Bearer"`; some providers omit. */
|
|
110
|
+
tokenType?: string;
|
|
111
|
+
/**
|
|
112
|
+
* Provider-specific extras (e.g. Google `id_token`, Microsoft
|
|
113
|
+
* `tenant_id`, full SDK response object) that don't fit the
|
|
114
|
+
* cross-provider columns. The schema's `metadata` jsonb column
|
|
115
|
+
* stores this verbatim.
|
|
116
|
+
*/
|
|
117
|
+
metadata?: Record<string, unknown>;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface OAuthAdapter {
|
|
121
|
+
/** Stable provider identifier. Matches the `providerCode` column. */
|
|
122
|
+
readonly providerCode: string;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Build the provider's authorization URL. Pure / synchronous —
|
|
126
|
+
* adapter callers (the routes layer) do `Response.redirect(url)`
|
|
127
|
+
* themselves.
|
|
128
|
+
*/
|
|
129
|
+
buildAuthorizationUrl(credentials: OAuthClientCredentials, opts: AuthUrlOptions): string;
|
|
130
|
+
|
|
131
|
+
/** Exchange the authorization code for an initial token pair. */
|
|
132
|
+
exchangeCodeForTokens(
|
|
133
|
+
code: string,
|
|
134
|
+
credentials: OAuthClientCredentials,
|
|
135
|
+
opts?: ExchangeCodeOptions,
|
|
136
|
+
): Promise<TokenResponse>;
|
|
137
|
+
|
|
138
|
+
/** Use the refresh token to mint a new access token. */
|
|
139
|
+
refreshTokens(
|
|
140
|
+
refreshToken: string,
|
|
141
|
+
credentials: OAuthClientCredentials,
|
|
142
|
+
opts?: { signal?: AbortSignal },
|
|
143
|
+
): Promise<TokenResponse>;
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Resolve the upstream provider's stable subject identifier from a
|
|
147
|
+
* `TokenResponse`. Used to populate `provider_account_id` on the
|
|
148
|
+
* connection row — lets a re-auth match an existing row instead of
|
|
149
|
+
* creating a duplicate when the provider changes the access token
|
|
150
|
+
* but keeps the same user.
|
|
151
|
+
*/
|
|
152
|
+
getProviderAccountId(
|
|
153
|
+
tokens: TokenResponse,
|
|
154
|
+
credentials: OAuthClientCredentials,
|
|
155
|
+
opts?: { signal?: AbortSignal },
|
|
156
|
+
): Promise<string>;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Optional revoke-access endpoint call. Best-effort; routes layer
|
|
160
|
+
* still nulls the local row even if upstream revoke fails.
|
|
161
|
+
*/
|
|
162
|
+
revokeAccess?(
|
|
163
|
+
accessToken: string,
|
|
164
|
+
credentials: OAuthClientCredentials,
|
|
165
|
+
opts?: { signal?: AbortSignal },
|
|
166
|
+
): Promise<void>;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// ─── Errors ───────────────────────────────────────────────────────────
|
|
170
|
+
|
|
171
|
+
export class OAuthAdapterError extends Error {
|
|
172
|
+
constructor(
|
|
173
|
+
public readonly providerCode: string,
|
|
174
|
+
message: string,
|
|
175
|
+
) {
|
|
176
|
+
super(message);
|
|
177
|
+
this.name = "OAuthAdapterError";
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export class TokenExchangeError extends OAuthAdapterError {
|
|
182
|
+
constructor(providerCode: string, message: string) {
|
|
183
|
+
super(providerCode, message);
|
|
184
|
+
this.name = "TokenExchangeError";
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export class TokenRefreshError extends OAuthAdapterError {
|
|
189
|
+
constructor(providerCode: string, message: string) {
|
|
190
|
+
super(providerCode, message);
|
|
191
|
+
this.name = "TokenRefreshError";
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export class InvalidCredentialsError extends OAuthAdapterError {
|
|
196
|
+
constructor(providerCode: string, message: string) {
|
|
197
|
+
super(providerCode, message);
|
|
198
|
+
this.name = "InvalidCredentialsError";
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export class OAuthRateLimitError extends OAuthAdapterError {
|
|
203
|
+
constructor(
|
|
204
|
+
providerCode: string,
|
|
205
|
+
message: string,
|
|
206
|
+
public readonly retryAfterSeconds?: number,
|
|
207
|
+
) {
|
|
208
|
+
super(providerCode, message);
|
|
209
|
+
this.name = "OAuthRateLimitError";
|
|
210
|
+
}
|
|
211
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { OAuthAdapter } from "./OAuthAdapter.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Registry of `OAuthAdapter`s keyed by `providerCode`. The routes
|
|
5
|
+
* layer does `registry.get(providerCode)` to dispatch each request
|
|
6
|
+
* to the right provider implementation.
|
|
7
|
+
*
|
|
8
|
+
* Replaces v3's `AdapterRegistry` static-class pattern with an
|
|
9
|
+
* instance-based registry — lets consumers compose multiple registries
|
|
10
|
+
* (e.g., a per-tenant subset of providers) and lets tests construct a
|
|
11
|
+
* registry with a single mock adapter without touching globals.
|
|
12
|
+
*
|
|
13
|
+
* Why instance-based: v3's `AdapterRegistry` was a static class with a
|
|
14
|
+
* hard-coded `ADAPTER_MAP`, which meant adding a provider required
|
|
15
|
+
* editing the framework. v4 pushes the choice of which providers a
|
|
16
|
+
* consumer supports out to the consumer's bootstrap code:
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* const registry = new OAuthAdapterRegistry()
|
|
20
|
+
* .register(new GoogleOAuthAdapter())
|
|
21
|
+
* .register(new MicrosoftOAuthAdapter());
|
|
22
|
+
*
|
|
23
|
+
* defineOAuthRoutes(app, { service, provider, adapters: registry });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export class OAuthAdapterRegistry {
|
|
27
|
+
private readonly adapters = new Map<string, OAuthAdapter>();
|
|
28
|
+
|
|
29
|
+
/** Add an adapter. Chainable. Throws on duplicate `providerCode`. */
|
|
30
|
+
register(adapter: OAuthAdapter): this {
|
|
31
|
+
if (this.adapters.has(adapter.providerCode)) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
`OAuthAdapterRegistry: duplicate adapter for provider "${adapter.providerCode}"`,
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
this.adapters.set(adapter.providerCode, adapter);
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Look up an adapter, returns `undefined` when not registered. */
|
|
41
|
+
get(providerCode: string): OAuthAdapter | undefined {
|
|
42
|
+
return this.adapters.get(providerCode);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Look up an adapter, throws when not registered. Use from routes
|
|
47
|
+
* layer when the request is parameterized on a provider that
|
|
48
|
+
* `mustExist` semantically.
|
|
49
|
+
*/
|
|
50
|
+
require(providerCode: string): OAuthAdapter {
|
|
51
|
+
const adapter = this.adapters.get(providerCode);
|
|
52
|
+
if (!adapter) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
`No OAuth adapter registered for provider "${providerCode}". Registered: ${this.providerCodes().join(", ") || "(none)"}.`,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
return adapter;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
has(providerCode: string): boolean {
|
|
61
|
+
return this.adapters.has(providerCode);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
providerCodes(): string[] {
|
|
65
|
+
return [...this.adapters.keys()];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
size(): number {
|
|
69
|
+
return this.adapters.size;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function oauthAdapterRegistry(...adapters: OAuthAdapter[]): OAuthAdapterRegistry {
|
|
74
|
+
const registry = new OAuthAdapterRegistry();
|
|
75
|
+
for (const a of adapters) registry.register(a);
|
|
76
|
+
return registry;
|
|
77
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MicrosoftOAuthAdapter,
|
|
3
|
+
type MicrosoftOAuthAdapterOptions,
|
|
4
|
+
} from "./MicrosoftOAuthAdapter.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Outlook-flavored Microsoft OAuth adapter — convenience subclass
|
|
8
|
+
* that pre-fills `providerCode: "outlook"`.
|
|
9
|
+
*
|
|
10
|
+
* Same OAuth 2.0 flow as `MicrosoftOAuthAdapter` (Outlook uses the
|
|
11
|
+
* same Azure AD v2.0 endpoints; Outlook/Mail-specific scopes like
|
|
12
|
+
* `https://graph.microsoft.com/Mail.Read` are caller-supplied via
|
|
13
|
+
* `AuthUrlOptions.scopes`, not adapter-specific).
|
|
14
|
+
*
|
|
15
|
+
* Why a separate class instead of a runtime tag: connection rows
|
|
16
|
+
* carry `providerCode` as the cross-table key, and consumers
|
|
17
|
+
* frequently want Outlook-scoped connections to live alongside
|
|
18
|
+
* generic Microsoft sign-in connections without colliding on the
|
|
19
|
+
* unique (account_id, provider_code) composite. Registering both
|
|
20
|
+
* `MicrosoftOAuthAdapter` (`"microsoft"`) and `OutlookOAuthAdapter`
|
|
21
|
+
* (`"outlook"`) in the same registry gives consumers two distinct
|
|
22
|
+
* provider rows per account.
|
|
23
|
+
*
|
|
24
|
+
* Usage:
|
|
25
|
+
*
|
|
26
|
+
* const adapters = oauthAdapterRegistry(
|
|
27
|
+
* new MicrosoftOAuthAdapter(),
|
|
28
|
+
* new OutlookOAuthAdapter(),
|
|
29
|
+
* );
|
|
30
|
+
*
|
|
31
|
+
* All other options forward to the underlying `MicrosoftOAuthAdapter`
|
|
32
|
+
* (tenant, fetchImpl, …).
|
|
33
|
+
*/
|
|
34
|
+
export class OutlookOAuthAdapter extends MicrosoftOAuthAdapter {
|
|
35
|
+
constructor(opts: Omit<MicrosoftOAuthAdapterOptions, "providerCode"> = {}) {
|
|
36
|
+
super({ ...opts, providerCode: "outlook" });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth module — public barrel.
|
|
3
|
+
*
|
|
4
|
+
* Multi-step OAuth flow with pluggable provider adapters
|
|
5
|
+
* (Google / Microsoft / Gmail / Outlook), state signing, and
|
|
6
|
+
* connection persistence. Wired via `defineOAuthRoutes(app, deps)`.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export { GmailOAuthAdapter } from "./adapters/GmailOAuthAdapter.js";
|
|
10
|
+
export {
|
|
11
|
+
GoogleOAuthAdapter,
|
|
12
|
+
type GoogleOAuthAdapterOptions,
|
|
13
|
+
} from "./adapters/GoogleOAuthAdapter.js";
|
|
14
|
+
export {
|
|
15
|
+
MicrosoftOAuthAdapter,
|
|
16
|
+
type MicrosoftOAuthAdapterOptions,
|
|
17
|
+
} from "./adapters/MicrosoftOAuthAdapter.js";
|
|
18
|
+
export { MockOAuthAdapter } from "./adapters/MockOAuthAdapter.js";
|
|
19
|
+
export {
|
|
20
|
+
type AuthUrlOptions,
|
|
21
|
+
InvalidCredentialsError,
|
|
22
|
+
type OAuthAdapter,
|
|
23
|
+
OAuthAdapterError,
|
|
24
|
+
type OAuthClientCredentials,
|
|
25
|
+
OAuthRateLimitError,
|
|
26
|
+
TokenExchangeError,
|
|
27
|
+
TokenRefreshError,
|
|
28
|
+
type TokenResponse,
|
|
29
|
+
} from "./adapters/OAuthAdapter.js";
|
|
30
|
+
export { OAuthAdapterRegistry, oauthAdapterRegistry } from "./adapters/OAuthAdapterRegistry.js";
|
|
31
|
+
export { OutlookOAuthAdapter } from "./adapters/OutlookOAuthAdapter.js";
|
|
32
|
+
export {
|
|
33
|
+
OAUTH_PERMISSION_DEFINITIONS,
|
|
34
|
+
OAUTH_PERMISSIONS,
|
|
35
|
+
type OAuthPermission,
|
|
36
|
+
} from "./permissions.js";
|
|
37
|
+
export {
|
|
38
|
+
buildOAuthApp,
|
|
39
|
+
defineOAuthRoutes,
|
|
40
|
+
type OAuthCredentialsResolver,
|
|
41
|
+
type OAuthRoutesDeps,
|
|
42
|
+
validateReturnTo,
|
|
43
|
+
} from "./routes.js";
|
|
44
|
+
export {
|
|
45
|
+
authorizationHeader,
|
|
46
|
+
isActive,
|
|
47
|
+
isExpired,
|
|
48
|
+
isExpiringSoon,
|
|
49
|
+
type NewOAuthConnection,
|
|
50
|
+
needsRefresh,
|
|
51
|
+
type OAuthConnection,
|
|
52
|
+
oauthConnections,
|
|
53
|
+
oauthConnectionsRelations,
|
|
54
|
+
} from "./schema.js";
|
|
55
|
+
export { OAuthConnectionService } from "./services/OAuthConnectionService.js";
|
|
56
|
+
export {
|
|
57
|
+
InvalidStateError,
|
|
58
|
+
type SignStateOptions,
|
|
59
|
+
type StatePayload,
|
|
60
|
+
type StateSecret,
|
|
61
|
+
signState,
|
|
62
|
+
type VerifyStateOptions,
|
|
63
|
+
verifyState,
|
|
64
|
+
} from "./state.js";
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* OAuth state replay defense (F16). Default in-memory cache ships
|
|
68
|
+
* with the framework; consumers running behind a load balancer
|
|
69
|
+
* implement `StateJtiCache` against shared storage (e.g. Redis) and
|
|
70
|
+
* pass it via `OAuthRoutesDeps.stateJtiCache`.
|
|
71
|
+
*/
|
|
72
|
+
export { InMemoryStateJtiCache, type StateJtiCache } from "./stateJtiCache.js";
|
|
73
|
+
/**
|
|
74
|
+
* `@internal` OIDC id_token verifier (F13). No adapter currently
|
|
75
|
+
* consumes id_token as an identity decision; this helper exists so
|
|
76
|
+
* any future code path that does MUST route through it (signature +
|
|
77
|
+
* iss/aud/exp + nonce echo against framework-signed state).
|
|
78
|
+
*/
|
|
79
|
+
export { type VerifyIdTokenOptions, verifyIdToken } from "./verifyIdToken.js";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "oauth",
|
|
3
|
+
"description": "OAuth 2.0 authentication on the v4 substrate — pluggable provider adapters, Drizzle-backed token storage, Hono routes. State lives in the URL `state` param; tokens persist in DB; no express-session.",
|
|
4
|
+
"version": "2.0.0-alpha.1",
|
|
5
|
+
"dependencies": ["accounts"],
|
|
6
|
+
"npmDependencies": {},
|
|
7
|
+
"requiredEnvVars": [],
|
|
8
|
+
"optionalEnvVars": [
|
|
9
|
+
"OAUTH_GOOGLE_CLIENT_ID",
|
|
10
|
+
"OAUTH_GOOGLE_CLIENT_SECRET",
|
|
11
|
+
"OAUTH_GMAIL_REDIRECT_URI",
|
|
12
|
+
"OAUTH_GOOGLE_CONTACTS_REDIRECT_URI",
|
|
13
|
+
"OAUTH_MICROSOFT_CLIENT_ID",
|
|
14
|
+
"OAUTH_MICROSOFT_CLIENT_SECRET",
|
|
15
|
+
"OAUTH_OUTLOOK_REDIRECT_URI"
|
|
16
|
+
],
|
|
17
|
+
"postInstall": [
|
|
18
|
+
"Add the schema to your composed schema: `createApp({ schema: { ...accountsSchema, oauthConnections, oauthConnectionsRelations } })`",
|
|
19
|
+
"Wire the routes: `defineOAuthRoutes(app, { service, provider, adapters })`",
|
|
20
|
+
"Configure OAuth credentials in .env for the providers you support",
|
|
21
|
+
"Generate the migration: `npm run db:generate`"
|
|
22
|
+
]
|
|
23
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permission slugs for the oauth module.
|
|
3
|
+
*
|
|
4
|
+
* v3 enforced authorization via @HasPermission decorators on controller
|
|
5
|
+
* methods; v4 enforces it via `requirePermission(slug)` middleware at
|
|
6
|
+
* the route. The permission rows themselves are seeded by the consuming
|
|
7
|
+
* app.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { PermissionDefinition } from "@sixthsummit/ship-api";
|
|
11
|
+
|
|
12
|
+
export const OAUTH_PERMISSIONS = {
|
|
13
|
+
/** View one's own connections (typical scope for end-user-facing endpoints). */
|
|
14
|
+
readSelf: "oauth:connections:read-self",
|
|
15
|
+
/** View any connection (admin-style; for support/audit UIs). */
|
|
16
|
+
readAny: "oauth:connections:read-any",
|
|
17
|
+
/** Initiate a new OAuth connection on one's own account. */
|
|
18
|
+
connect: "oauth:connections:connect",
|
|
19
|
+
/** Revoke / disconnect a connection. */
|
|
20
|
+
disconnect: "oauth:connections:disconnect",
|
|
21
|
+
/** Force-refresh an access token. */
|
|
22
|
+
refresh: "oauth:connections:refresh",
|
|
23
|
+
} as const;
|
|
24
|
+
|
|
25
|
+
export type OAuthPermission = (typeof OAUTH_PERMISSIONS)[keyof typeof OAUTH_PERMISSIONS];
|
|
26
|
+
|
|
27
|
+
export const OAUTH_PERMISSION_DEFINITIONS = [
|
|
28
|
+
{
|
|
29
|
+
slug: OAUTH_PERMISSIONS.readSelf,
|
|
30
|
+
label: "View Own OAuth Connections",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
slug: OAUTH_PERMISSIONS.readAny,
|
|
34
|
+
label: "View Any OAuth Connection (Admin)",
|
|
35
|
+
},
|
|
36
|
+
{ slug: OAUTH_PERMISSIONS.connect, label: "Initiate OAuth Connection" },
|
|
37
|
+
{ slug: OAUTH_PERMISSIONS.disconnect, label: "Disconnect OAuth Provider" },
|
|
38
|
+
{ slug: OAUTH_PERMISSIONS.refresh, label: "Force-Refresh OAuth Token" },
|
|
39
|
+
] as const satisfies readonly PermissionDefinition[];
|