@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,110 @@
|
|
|
1
|
+
import pino from "pino";
|
|
2
|
+
import { requestContextStore } from "../app/context/RequestContext.js";
|
|
3
|
+
// Re-export the context primitives so the logger module remains a one-stop
|
|
4
|
+
// import for code that wants both `logger` and request-context helpers, while
|
|
5
|
+
// keeping the canonical store in `app/context/RequestContext.ts`.
|
|
6
|
+
export { getRequestContext, runWithRequestContext, setRequestContextField, } from "../app/context/RequestContext.js";
|
|
7
|
+
/**
|
|
8
|
+
* Structured logger built on pino. Replaces the v3 `Logger` console-wrapper.
|
|
9
|
+
*
|
|
10
|
+
* - **ND-JSON** in production; **pino-pretty** in dev / local.
|
|
11
|
+
* - **Redaction** of standard secret-bearing paths (`Authorization`, cookies,
|
|
12
|
+
* `password`, `token`, `secret`, `apiKey`, Firebase / GCP credentials blobs).
|
|
13
|
+
* - **Request context** propagation via the canonical framework-wide
|
|
14
|
+
* `AsyncLocalStorage` (see `app/context/RequestContext.ts`). Any code running
|
|
15
|
+
* inside `runWithRequestContext({ requestId, userId, tenantId }, fn)` gets
|
|
16
|
+
* those fields auto-attached to every log line via pino's `mixin`, without
|
|
17
|
+
* callsite changes. The same context flows into `DrizzleEntityService`
|
|
18
|
+
* lifecycle hooks (audit / CDC / multi-tenancy) — single SoT.
|
|
19
|
+
* - Forward-compatible with `@opentelemetry/instrumentation-pino`, which
|
|
20
|
+
* auto-injects `trace_id` / `span_id` / `trace_flags` once the OTel SDK is
|
|
21
|
+
* running. No mixin work required there.
|
|
22
|
+
*/
|
|
23
|
+
const DEFAULT_REDACT_PATHS = [
|
|
24
|
+
// Top-level secret-bearing keys (pino's `*.foo` wildcard matches one level
|
|
25
|
+
// of nesting, not top-level — list these separately).
|
|
26
|
+
"password",
|
|
27
|
+
"token",
|
|
28
|
+
"secret",
|
|
29
|
+
"apiKey",
|
|
30
|
+
// Common one-level-nested locations (e.g., `user.password`, `body.token`).
|
|
31
|
+
"*.password",
|
|
32
|
+
"*.token",
|
|
33
|
+
"*.secret",
|
|
34
|
+
"*.apiKey",
|
|
35
|
+
// Auth headers in their usual containers.
|
|
36
|
+
"req.headers.authorization",
|
|
37
|
+
"req.headers.cookie",
|
|
38
|
+
"request.headers.authorization",
|
|
39
|
+
"request.headers.cookie",
|
|
40
|
+
"headers.authorization",
|
|
41
|
+
"headers.cookie",
|
|
42
|
+
// App / framework keys with non-generic shapes.
|
|
43
|
+
"firebaseCredentials",
|
|
44
|
+
"gcpCredentialsJson",
|
|
45
|
+
"FIREBASE_CREDENTIALS",
|
|
46
|
+
"GCP_CREDENTIALS_JSON",
|
|
47
|
+
"SESSION_SECRET",
|
|
48
|
+
];
|
|
49
|
+
function isPrettyEnvByDefault() {
|
|
50
|
+
const env = process.env.ENVIRONMENT_NAME ?? process.env.NODE_ENV ?? "";
|
|
51
|
+
return env === "local" || env === "dev" || env === "development" || env === "";
|
|
52
|
+
}
|
|
53
|
+
function buildOptions(opts) {
|
|
54
|
+
const redactPaths = opts.extraRedactPaths
|
|
55
|
+
? [...DEFAULT_REDACT_PATHS, ...opts.extraRedactPaths]
|
|
56
|
+
: DEFAULT_REDACT_PATHS;
|
|
57
|
+
return {
|
|
58
|
+
level: opts.level ?? process.env.LOG_LEVEL ?? "info",
|
|
59
|
+
redact: {
|
|
60
|
+
paths: [...redactPaths],
|
|
61
|
+
censor: "[REDACTED]",
|
|
62
|
+
},
|
|
63
|
+
mixin() {
|
|
64
|
+
const ctx = requestContextStore.getStore();
|
|
65
|
+
if (!ctx)
|
|
66
|
+
return {};
|
|
67
|
+
const out = {};
|
|
68
|
+
if (ctx.requestId !== undefined)
|
|
69
|
+
out.requestId = ctx.requestId;
|
|
70
|
+
if (ctx.userId !== undefined)
|
|
71
|
+
out.userId = ctx.userId;
|
|
72
|
+
if (ctx.tenantId !== undefined)
|
|
73
|
+
out.tenantId = ctx.tenantId;
|
|
74
|
+
if (ctx.extra)
|
|
75
|
+
Object.assign(out, ctx.extra);
|
|
76
|
+
return out;
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export function createLogger(opts = {}) {
|
|
81
|
+
const options = buildOptions(opts);
|
|
82
|
+
// Explicit destination wins (test hook).
|
|
83
|
+
if (opts.destination) {
|
|
84
|
+
return pino(options, opts.destination);
|
|
85
|
+
}
|
|
86
|
+
const usePretty = opts.pretty ?? isPrettyEnvByDefault();
|
|
87
|
+
if (usePretty) {
|
|
88
|
+
return pino({
|
|
89
|
+
...options,
|
|
90
|
+
transport: {
|
|
91
|
+
target: "pino-pretty",
|
|
92
|
+
options: {
|
|
93
|
+
colorize: true,
|
|
94
|
+
translateTime: "SYS:HH:MM:ss.l",
|
|
95
|
+
ignore: "pid,hostname",
|
|
96
|
+
singleLine: false,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
// Production / staging: ND-JSON to stdout (pino default).
|
|
102
|
+
return pino(options);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Default framework-wide logger. Most callsites should import this and either
|
|
106
|
+
* use it directly or call `logger.child({ module: "<name>" })` for a scoped
|
|
107
|
+
* sub-logger.
|
|
108
|
+
*/
|
|
109
|
+
export const logger = createLogger();
|
|
110
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/observability/logger.ts"],"names":[],"mappings":"AAAA,OAAO,IAAyC,MAAM,MAAM,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAEvE,2EAA2E;AAC3E,8EAA8E;AAC9E,kEAAkE;AAClE,OAAO,EACL,iBAAiB,EAEjB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,kCAAkC,CAAC;AAE1C;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,oBAAoB,GAAsB;IAC9C,2EAA2E;IAC3E,sDAAsD;IACtD,UAAU;IACV,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,2EAA2E;IAC3E,YAAY;IACZ,SAAS;IACT,UAAU;IACV,UAAU;IACV,0CAA0C;IAC1C,2BAA2B;IAC3B,oBAAoB;IACpB,+BAA+B;IAC/B,wBAAwB;IACxB,uBAAuB;IACvB,gBAAgB;IAChB,gDAAgD;IAChD,qBAAqB;IACrB,oBAAoB;IACpB,sBAAsB;IACtB,sBAAsB;IACtB,gBAAgB;CACjB,CAAC;AAEF,SAAS,oBAAoB;IAC3B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC;IACvE,OAAO,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,aAAa,IAAI,GAAG,KAAK,EAAE,CAAC;AACjF,CAAC;AAuBD,SAAS,YAAY,CAAC,IAAyB;IAC7C,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB;QACvC,CAAC,CAAC,CAAC,GAAG,oBAAoB,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC;QACrD,CAAC,CAAC,oBAAoB,CAAC;IAEzB,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK,IAAK,OAAO,CAAC,GAAG,CAAC,SAAoC,IAAI,MAAM;QAChF,MAAM,EAAE;YACN,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC;YACvB,MAAM,EAAE,YAAY;SACrB;QACD,KAAK;YACH,MAAM,GAAG,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAC;YAC3C,IAAI,CAAC,GAAG;gBAAE,OAAO,EAAE,CAAC;YACpB,MAAM,GAAG,GAA4B,EAAE,CAAC;YACxC,IAAI,GAAG,CAAC,SAAS,KAAK,SAAS;gBAAE,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;YAC/D,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS;gBAAE,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;YACtD,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS;gBAAE,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;YAC5D,IAAI,GAAG,CAAC,KAAK;gBAAE,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;YAC7C,OAAO,GAAG,CAAC;QACb,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAA4B,EAAE;IACzD,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAEnC,yCAAyC;IACzC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,IAAI,oBAAoB,EAAE,CAAC;IACxD,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;YACV,GAAG,OAAO;YACV,SAAS,EAAE;gBACT,MAAM,EAAE,aAAa;gBACrB,OAAO,EAAE;oBACP,QAAQ,EAAE,IAAI;oBACd,aAAa,EAAE,gBAAgB;oBAC/B,MAAM,EAAE,cAAc;oBACtB,UAAU,EAAE,KAAK;iBAClB;aACF;SACF,CAAC,CAAC;IACL,CAAC;IAED,0DAA0D;IAC1D,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAW,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/observability/metrics.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,cAAc,8CAA8C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/observability/metrics.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,cAAc,8CAA8C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otel.d.ts","sourceRoot":"","sources":["../../src/observability/otel.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,cAAc,0CAA0C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otel.js","sourceRoot":"","sources":["../../src/observability/otel.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,cAAc,0CAA0C,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log-safe identifying fields of an error: its `code`, `name` and `syscall`,
|
|
3
|
+
* never its message. Database and network error messages can contain the
|
|
4
|
+
* host, port, user or database name, so only these short identifiers are kept
|
|
5
|
+
* (for Postgres the SQLSTATE such as `28P01`, or a Node code such as
|
|
6
|
+
* `ECONNREFUSED` with the failing `syscall`).
|
|
7
|
+
*/
|
|
8
|
+
export interface SafeErrorFields {
|
|
9
|
+
errorCode?: string | number;
|
|
10
|
+
errorName?: string;
|
|
11
|
+
syscall?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function safeErrorFields(error: unknown): SafeErrorFields;
|
|
14
|
+
//# sourceMappingURL=safeErrorFields.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safeErrorFields.d.ts","sourceRoot":"","sources":["../../src/observability/safeErrorFields.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAQ/D"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function safeErrorFields(error) {
|
|
2
|
+
const fields = {};
|
|
3
|
+
if (error === null || typeof error !== "object")
|
|
4
|
+
return fields;
|
|
5
|
+
const { code, name, syscall } = error;
|
|
6
|
+
if (typeof code === "string" || typeof code === "number")
|
|
7
|
+
fields.errorCode = code;
|
|
8
|
+
if (typeof name === "string")
|
|
9
|
+
fields.errorName = name;
|
|
10
|
+
if (typeof syscall === "string")
|
|
11
|
+
fields.syscall = syscall;
|
|
12
|
+
return fields;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=safeErrorFields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safeErrorFields.js","sourceRoot":"","sources":["../../src/observability/safeErrorFields.ts"],"names":[],"mappings":"AAaA,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IAC/D,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,KAA8D,CAAC;IAC/F,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC;IAClF,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC;IACtD,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;IAC1D,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../../src/observability/tracing.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,cAAc,8CAA8C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracing.js","sourceRoot":"","sources":["../../src/observability/tracing.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,cAAc,8CAA8C,CAAC"}
|
package/lib/package.json
ADDED
package/lib/testing.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,cAAc,2BAA2B,CAAC"}
|
package/lib/testing.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,cAAc,2BAA2B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,196 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sixthsummit/ship-api",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "4.1.1",
|
|
4
|
+
"description": "ShipAPI Framework — TypeScript backend on Hono + Drizzle + pluggable AuthProvider + BullMQ + OpenTelemetry. Designed to be edited by AI coding agents.",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"ship-api": "./cli/ship-api.js"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"typescript",
|
|
12
|
+
"hono",
|
|
13
|
+
"drizzle",
|
|
14
|
+
"firebase",
|
|
15
|
+
"api",
|
|
16
|
+
"framework",
|
|
17
|
+
"rest",
|
|
18
|
+
"rpc",
|
|
19
|
+
"authentication",
|
|
20
|
+
"authorization",
|
|
21
|
+
"middleware",
|
|
22
|
+
"bullmq",
|
|
23
|
+
"opentelemetry",
|
|
24
|
+
"ai-agents",
|
|
25
|
+
"claude-code",
|
|
26
|
+
"boilerplate",
|
|
27
|
+
"cli"
|
|
28
|
+
],
|
|
29
|
+
"author": "Scott Gibson",
|
|
30
|
+
"license": "Apache-2.0",
|
|
31
|
+
"type": "module",
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"types": "./lib/index.d.ts",
|
|
35
|
+
"import": "./lib/index.js",
|
|
36
|
+
"default": "./lib/index.js"
|
|
37
|
+
},
|
|
38
|
+
"./client": {
|
|
39
|
+
"types": "./lib/client.d.ts",
|
|
40
|
+
"import": "./lib/client.js",
|
|
41
|
+
"default": "./lib/client.js"
|
|
42
|
+
},
|
|
43
|
+
"./contract": {
|
|
44
|
+
"types": "./lib/contract/index.d.ts",
|
|
45
|
+
"import": "./lib/contract/index.js",
|
|
46
|
+
"default": "./lib/contract/index.js"
|
|
47
|
+
},
|
|
48
|
+
"./contract/application": {
|
|
49
|
+
"types": "./lib/contract/application.d.ts",
|
|
50
|
+
"import": "./lib/contract/application.js",
|
|
51
|
+
"default": "./lib/contract/application.js"
|
|
52
|
+
},
|
|
53
|
+
"./contract/openapi": {
|
|
54
|
+
"types": "./lib/contract/openapi.d.ts",
|
|
55
|
+
"import": "./lib/contract/openapi.js",
|
|
56
|
+
"default": "./lib/contract/openapi.js"
|
|
57
|
+
},
|
|
58
|
+
"./contract/project": {
|
|
59
|
+
"types": "./lib/contract/project.d.ts",
|
|
60
|
+
"import": "./lib/contract/project.js",
|
|
61
|
+
"default": "./lib/contract/project.js"
|
|
62
|
+
},
|
|
63
|
+
"./contract/schema": {
|
|
64
|
+
"types": "./lib/contract/schema.d.ts",
|
|
65
|
+
"import": "./lib/contract/schema.js",
|
|
66
|
+
"default": "./lib/contract/schema.js"
|
|
67
|
+
},
|
|
68
|
+
"./hono": {
|
|
69
|
+
"types": "./lib/hono/index.d.ts",
|
|
70
|
+
"import": "./lib/hono/index.js",
|
|
71
|
+
"default": "./lib/hono/index.js"
|
|
72
|
+
},
|
|
73
|
+
"./drizzle": {
|
|
74
|
+
"types": "./lib/drizzle/index.d.ts",
|
|
75
|
+
"import": "./lib/drizzle/index.js",
|
|
76
|
+
"default": "./lib/drizzle/index.js"
|
|
77
|
+
},
|
|
78
|
+
"./kernel": {
|
|
79
|
+
"types": "./lib/kernel/index.d.ts",
|
|
80
|
+
"import": "./lib/kernel/index.js",
|
|
81
|
+
"default": "./lib/kernel/index.js"
|
|
82
|
+
},
|
|
83
|
+
"./rate-limit": {
|
|
84
|
+
"types": "./lib/app/services/rateLimit/index.d.ts",
|
|
85
|
+
"import": "./lib/app/services/rateLimit/index.js",
|
|
86
|
+
"default": "./lib/app/services/rateLimit/index.js"
|
|
87
|
+
},
|
|
88
|
+
"./*": {
|
|
89
|
+
"types": "./lib/*.d.ts",
|
|
90
|
+
"import": "./lib/*.js",
|
|
91
|
+
"default": "./lib/*.js"
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"dependencies": {
|
|
95
|
+
"@hono/node-server": "^1.19.14",
|
|
96
|
+
"@hono/node-ws": "^1.3.0",
|
|
97
|
+
"@hono/zod-validator": "^0.7.6",
|
|
98
|
+
"@opentelemetry/api": "^1.9.1",
|
|
99
|
+
"@opentelemetry/auto-instrumentations-node": "^0.80.0",
|
|
100
|
+
"@opentelemetry/exporter-prometheus": "^0.222.0",
|
|
101
|
+
"@opentelemetry/resources": "^2.11.0",
|
|
102
|
+
"@opentelemetry/sdk-metrics": "^2.11.0",
|
|
103
|
+
"@opentelemetry/sdk-node": "^0.222.0",
|
|
104
|
+
"@opentelemetry/semantic-conventions": "^1.43.0",
|
|
105
|
+
"@sixthsummit/ship-cli": "^1.2.0",
|
|
106
|
+
"@sixthsummit/ship-contract": "^1.3.0",
|
|
107
|
+
"@sixthsummit/ship-core": "^1.1.1",
|
|
108
|
+
"@sixthsummit/ship-drizzle": "^1.2.0",
|
|
109
|
+
"@sixthsummit/ship-hono": "^1.2.0",
|
|
110
|
+
"@sixthsummit/ship-observability-otel": "^1.2.0",
|
|
111
|
+
"async": "^3.2.4",
|
|
112
|
+
"bullmq": "^5.76.3",
|
|
113
|
+
"chalk": "^5.3.0",
|
|
114
|
+
"commander": "^12.0.0",
|
|
115
|
+
"drizzle-orm": "^0.45.2",
|
|
116
|
+
"drizzle-zod": "^0.8.3",
|
|
117
|
+
"file-type": "^21.3.4",
|
|
118
|
+
"firebase-admin": "^13.10.0",
|
|
119
|
+
"hono": "^4.13.7",
|
|
120
|
+
"ioredis": "^5.10.1",
|
|
121
|
+
"jose": "^6.2.3",
|
|
122
|
+
"lru-cache": "^11.3.5",
|
|
123
|
+
"msgpackr": "^1.11.10",
|
|
124
|
+
"pg": "^8.16.3",
|
|
125
|
+
"pino": "^9.14.0",
|
|
126
|
+
"pino-pretty": "^13.1.3",
|
|
127
|
+
"tsx": "^4.20.3",
|
|
128
|
+
"zod": "^4.3.6",
|
|
129
|
+
"zod-to-json-schema": "^3.25.2"
|
|
130
|
+
},
|
|
131
|
+
"peerDependencies": {
|
|
132
|
+
"@sixthsummit/ship-testing": "^1.2.0",
|
|
133
|
+
"typescript": ">=5"
|
|
134
|
+
},
|
|
135
|
+
"peerDependenciesMeta": {
|
|
136
|
+
"@sixthsummit/ship-testing": {
|
|
137
|
+
"optional": true
|
|
138
|
+
},
|
|
139
|
+
"typescript": {
|
|
140
|
+
"optional": true
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
"engines": {
|
|
144
|
+
"node": ">=22"
|
|
145
|
+
},
|
|
146
|
+
"files": [
|
|
147
|
+
"lib/",
|
|
148
|
+
"cli/ship-api.js",
|
|
149
|
+
"cli/commands/add.js",
|
|
150
|
+
"cli/commands/contract.js",
|
|
151
|
+
"cli/commands/create.js",
|
|
152
|
+
"cli/commands/dev.js",
|
|
153
|
+
"cli/commands/doctor.js",
|
|
154
|
+
"cli/commands/generate.js",
|
|
155
|
+
"cli/commands/graph.js",
|
|
156
|
+
"cli/commands/migrate-orm.js",
|
|
157
|
+
"cli/commands/update.js",
|
|
158
|
+
"templates/",
|
|
159
|
+
"README.md",
|
|
160
|
+
"LICENSE",
|
|
161
|
+
"CHANGELOG.md",
|
|
162
|
+
"NOTICE"
|
|
163
|
+
],
|
|
164
|
+
"publishConfig": {
|
|
165
|
+
"registry": "https://registry.npmjs.org",
|
|
166
|
+
"access": "public"
|
|
167
|
+
},
|
|
168
|
+
"repository": {
|
|
169
|
+
"type": "git",
|
|
170
|
+
"url": "git+https://github.com/SixthSummit/Ship.git",
|
|
171
|
+
"directory": "packages/core"
|
|
172
|
+
},
|
|
173
|
+
"devDependencies": {
|
|
174
|
+
"@aws-sdk/client-s3": "^3.1038.0",
|
|
175
|
+
"@aws-sdk/s3-request-presigner": "^3.1038.0",
|
|
176
|
+
"@bull-board/api": "^7.0.0",
|
|
177
|
+
"@bull-board/hono": "^7.0.0",
|
|
178
|
+
"@google-cloud/storage": "^7.19.0",
|
|
179
|
+
"@opentelemetry/sdk-trace-base": "^2.11.0",
|
|
180
|
+
"@sixthsummit/ship-testing": "^1.2.0",
|
|
181
|
+
"@testcontainers/localstack": "^12.0.1",
|
|
182
|
+
"@testcontainers/postgresql": "^12.0.1",
|
|
183
|
+
"@types/pg": "^8.15.6",
|
|
184
|
+
"drizzle-kit": "^0.31.10",
|
|
185
|
+
"testcontainers": "^12.0.1"
|
|
186
|
+
},
|
|
187
|
+
"scripts": {
|
|
188
|
+
"build": "node ../../scripts/clean-package.mjs && tsc && node ../../scripts/build-core.js",
|
|
189
|
+
"test": "vitest run",
|
|
190
|
+
"test:watch": "vitest",
|
|
191
|
+
"test:coverage": "vitest run --coverage",
|
|
192
|
+
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
193
|
+
"lint": "eslint src/",
|
|
194
|
+
"type-check": "tsc --noEmit -p tsconfig.check.json"
|
|
195
|
+
}
|
|
6
196
|
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qa-brief
|
|
3
|
+
description: Generate a Sherpa-ready QA brief from a backend diff. Use when the user asks for "QA brief", "Sherpa brief", "test cases for QA", or when the `/ship:sherpa-brief` slash command fires. Walks the diff in a ShipAPI consumer app, enumerates new/changed routes, auth + permission requirements, validation surfaces, and AppError-driven sad paths, and writes a plain-English brief that the QA can paste into Sherpa's `/explore` and `/generate-test` commands. Read-only — emits markdown, never edits source.
|
|
4
|
+
tools: Read, Grep, Glob, Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are **qa-brief**, the QA-handoff agent for ShipAPI v4. Your output is what an engineer would have hand-written for QA today — but generated from the diff, with no engineer admin work.
|
|
8
|
+
|
|
9
|
+
You produce a markdown brief. You never edit source. You never propose code changes.
|
|
10
|
+
|
|
11
|
+
## Your audience
|
|
12
|
+
|
|
13
|
+
The QA at Sixth Summit who uses **Sherpa** (`../sherpa` — a separate Claude-Code-driven toolkit). They paste flows into Sherpa's `/explore` and `/generate-test` commands, and Sherpa walks the live web app via Playwright MCP to generate specs. They do **not** read TypeScript, route signatures, or middleware chains — your flows must be plain English.
|
|
14
|
+
|
|
15
|
+
## When you fire
|
|
16
|
+
|
|
17
|
+
- The user asks "write a QA brief" / "Sherpa brief" / "what should QA test for this branch?"
|
|
18
|
+
- The `/ship:sherpa-brief` slash command invokes you
|
|
19
|
+
- The `sherpa-brief.yml` GitHub Action invokes you headless (in that case, env vars `BASE_REF`, `HEAD_REF`, `PR_TITLE`, `PR_BODY`, `PR_NUMBER`, `REPO`, `BRANCH` may be set)
|
|
20
|
+
|
|
21
|
+
## Inputs you read
|
|
22
|
+
|
|
23
|
+
1. **Diff** — compute via `git diff $BASE_REF..$HEAD_REF` (or default `git diff main..HEAD`). Scope to files that affect observable backend behavior: `modules/**/*.ts`, `packages/core/src/http/**/*.ts`, `packages/core/src/app/schema/**/*.ts`. Ignore `*.test.ts`, `lib/`, `dist/`, `node_modules/`.
|
|
24
|
+
2. **PR context** — `PR_TITLE` + `PR_BODY` when set; otherwise the last few commit messages on the branch.
|
|
25
|
+
3. **Route registry** — if a ShipAPI dev server is running and the MCP `list_routes` / `describe_route` tools are available, use them to enumerate routes precisely. In CI / headless mode the MCP server is **not** available — fall back to static parse: grep for `app.get(` / `app.post(` / `app.put(` / `app.patch(` / `app.delete(` in the changed files.
|
|
26
|
+
4. **Auth / permission chain** — look for `requireAuth({ provider })` and `requirePermission("...")` middleware on each touched route. Routes lacking `requireAuth` are public.
|
|
27
|
+
5. **Validation surface** — look for `validate("json"|"query"|"param", <schema>)` middleware. The schema name (e.g. `createWidgetSchema`) hints at the input shape; read the schema definition if it's in the diff or in `modules/<name>/validation/schemas.ts`.
|
|
28
|
+
6. **AppError taxonomy** — `throw new NotFoundError(...)` / `BadRequestError` / `ConflictError` / `ForbiddenError` etc. inside touched handlers. Each one is a sad path worth exercising.
|
|
29
|
+
7. **BullMQ + outbox** — `defineJob(...)`, `OutboxEventEmitter.emit(...)`, `defineCron(...)` in the diff indicate async side effects that QA can't observe in a single request. Note them explicitly under "What this brief did NOT cover."
|
|
30
|
+
|
|
31
|
+
## Output shape (exact)
|
|
32
|
+
|
|
33
|
+
Emit markdown with these sections, in this order. Plain English in the "Flows to test" section — no code, no curl snippets, no route paths.
|
|
34
|
+
|
|
35
|
+
```markdown
|
|
36
|
+
# QA brief — <feature title>
|
|
37
|
+
|
|
38
|
+
> **Stack:** ShipAPI (backend) | **Repo:** `<owner/repo>` | **Branch:** `<branch>` | **PR:** #<n>
|
|
39
|
+
|
|
40
|
+
## What changed (engineer's summary)
|
|
41
|
+
<1–3 lines pulled from PR_BODY / commit messages — not a diff dump>
|
|
42
|
+
|
|
43
|
+
## Surface area
|
|
44
|
+
- **New:**
|
|
45
|
+
- POST /api/widgets — create a widget (requires `widgets:create`)
|
|
46
|
+
- GET /api/widgets/:id — read a widget (requires `widgets:read`)
|
|
47
|
+
- **Changed:**
|
|
48
|
+
- PATCH /api/accounts/:id — now requires `accounts:write` (was public)
|
|
49
|
+
- **Removed:**
|
|
50
|
+
- DELETE /api/legacy/foo
|
|
51
|
+
|
|
52
|
+
## Flows to test (paste these into Sherpa's `/explore` one at a time)
|
|
53
|
+
1. A signed-in user with the **widgets:create** permission opens the widgets page, creates a widget named "Test", and sees it in the list.
|
|
54
|
+
2. A signed-in user **without** widgets:create tries to create a widget and gets a clear permission-denied message — no widget is created.
|
|
55
|
+
3. An unauthenticated visitor going to the widgets page is redirected to sign-in.
|
|
56
|
+
4. Creating a widget with an empty name shows an inline validation error and the widget is not saved.
|
|
57
|
+
5. <…one numbered flow per observable behavior change…>
|
|
58
|
+
|
|
59
|
+
## Auth / permission paths touched
|
|
60
|
+
- `widgets:create` (new) — needs a fixture user with this permission for happy-path tests
|
|
61
|
+
- `widgets:read` (new) — same
|
|
62
|
+
- `accounts:write` (existing) — re-verify after the PATCH change
|
|
63
|
+
|
|
64
|
+
## Likely sad paths worth exercising
|
|
65
|
+
- <pull from AppError throws> — e.g. "Submitting a widget with a name longer than 200 chars returns a validation error."
|
|
66
|
+
- <middleware-driven> — e.g. "Replaying a request with a repeated Idempotency-Key returns the cached response, not a duplicate."
|
|
67
|
+
- <middleware-driven> — e.g. "Sending requests above the rate limit returns 429."
|
|
68
|
+
|
|
69
|
+
## What this brief did NOT cover
|
|
70
|
+
- UI affordances on the consuming frontend — see the **companion ShipAngular brief** (if any) for that half.
|
|
71
|
+
- Async job side effects — this diff enqueues `<job-name>` via the outbox; QA cannot observe it inside a single browser flow. Verify via logs / dashboards.
|
|
72
|
+
- Anything outside the diff range (`<base>..<head>`).
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Style rules
|
|
76
|
+
|
|
77
|
+
- **No code in flows.** "POST /api/widgets" appears only in **Surface area**, never in **Flows to test**. Flows are descriptions of user behavior.
|
|
78
|
+
- **One flow = one numbered item.** No nested bullets, no "and also…". QA copy-pastes single items into `/explore` and Sherpa generates one spec per flow.
|
|
79
|
+
- **Each flow includes a happy-path or sad-path frame.** "A user with X does Y and sees Z" or "A user without X tries Y and sees Z." Never "the system validates Y" — that's not testable in a browser.
|
|
80
|
+
- **Permissions named in plain words.** `widgets:create` is fine in the auth section; in flows say "a user with the widgets:create permission".
|
|
81
|
+
- **No reference to `requireAuth` / `validate()` / Hono / middleware.** That's framework vocabulary, not QA vocabulary.
|
|
82
|
+
|
|
83
|
+
## Mode selection
|
|
84
|
+
|
|
85
|
+
**Live (with dev server + MCP):** prefer `list_routes` for surface area enumeration; it's authoritative.
|
|
86
|
+
|
|
87
|
+
**Headless (in GitHub Action):** use `git diff` + grep. Detect this mode by checking for the env var `GITHUB_ACTIONS=true` or by the absence of the MCP tools.
|
|
88
|
+
|
|
89
|
+
## When the diff is empty or non-substantive
|
|
90
|
+
|
|
91
|
+
If the diff touches only `*.test.ts`, generated migrations, or non-handler files, emit:
|
|
92
|
+
|
|
93
|
+
```markdown
|
|
94
|
+
# QA brief — <title>
|
|
95
|
+
|
|
96
|
+
No observable backend behavior changes detected in this diff (tests / migrations / generated only). No QA flows to enumerate. The ShipAngular brief (if any) covers the user-facing half.
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Do not invent flows to fill space. A short honest brief beats a long fabricated one.
|
|
100
|
+
|
|
101
|
+
## What you DO NOT do
|
|
102
|
+
|
|
103
|
+
- Do not run tests, lint, type-check, or build.
|
|
104
|
+
- Do not propose code changes or convention fixes — that's `ship-reviewer`'s job.
|
|
105
|
+
- Do not generate Playwright code — that's Sherpa's job after the QA pastes your flows.
|
|
106
|
+
- Do not ask the user clarifying questions when run from a hook or the GitHub Action — emit the brief and exit.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Generate a Sherpa-ready QA brief from the current branch's backend diff. Plain-English flows the QA pastes into Sherpa's /explore. Engineer admin work goes to zero.
|
|
3
|
+
argument-hint: "[--base <ref>]"
|
|
4
|
+
allowed-tools: Bash, Agent
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Run **qa-brief** against the current branch's diff.
|
|
8
|
+
|
|
9
|
+
**Base ref resolution** (in order):
|
|
10
|
+
1. `$1` if present and parseable as `--base <ref>`
|
|
11
|
+
2. `BASE_REF` env var if set (the GitHub Action sets this)
|
|
12
|
+
3. Default: the merge-base with `main` (`git merge-base main HEAD`)
|
|
13
|
+
|
|
14
|
+
**Head ref:** `HEAD_REF` env var if set, otherwise `HEAD`.
|
|
15
|
+
|
|
16
|
+
**PR context** (optional, set by the workflow when available):
|
|
17
|
+
- `PR_TITLE`, `PR_BODY`, `PR_NUMBER`, `REPO`, `BRANCH` env vars feed the brief's header
|
|
18
|
+
|
|
19
|
+
Scope the diff to files that affect observable backend behavior. The agent will compute the diff itself; just pass the resolved base + head refs in the prompt.
|
|
20
|
+
|
|
21
|
+
Invoke the **qa-brief** subagent. Surface its markdown output as the response — do not summarize, do not editorialize.
|
|
22
|
+
|
|
23
|
+
If `--base` was passed but doesn't resolve to a valid ref, fall back to the default and note the fallback in a one-line prefix above the brief.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
alwaysApply: true
|
|
3
|
+
description: "API development guidelines for ShipAPI v4 (Hono + Drizzle)"
|
|
4
|
+
tags: ["api", "hono", "drizzle", "zod"]
|
|
5
|
+
globs: ["modules/**/*.ts", "src/index.ts"]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# API Development Guidelines
|
|
9
|
+
|
|
10
|
+
## Module structure
|
|
11
|
+
|
|
12
|
+
Each feature module under `modules/<name>/` follows the canonical 7-file shape:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
modules/<name>/
|
|
16
|
+
├── schema.ts # Drizzle pgTable + relations + types
|
|
17
|
+
├── permissions.ts # module:resource:action slug constants
|
|
18
|
+
├── validation/schemas.ts # Zod schemas (.strict() on objects)
|
|
19
|
+
├── services/<NameSingular>Service.ts # extends DrizzleEntityService<typeof table>
|
|
20
|
+
├── routes.ts # buildXxxApp(deps) → mounts at root; defineXxxRoutes escape hatch
|
|
21
|
+
├── index.ts # barrel
|
|
22
|
+
└── module.json # metadata
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Scaffold with `ship-api g module <name>` (full shape) or `ship-api g resource <name> --fields "..."` (CRUD shortcut).
|
|
26
|
+
|
|
27
|
+
## Routes
|
|
28
|
+
|
|
29
|
+
- Each route chains: `requireAuth({ provider })` → `requirePermission(slug)` → `validate("json"|"query"|"param", schema)` → handler.
|
|
30
|
+
- **Each module exposes `buildXxxApp(deps)`** returning its **own** sub-app (built on `createModuleApp("xxx")`); the consumer mounts it with `root.route("/", buildXxxApp(deps))`. Modules keep absolute paths (`/posts`, `/posts/:id`), so the client shape (`api.posts.$get`) and route registry are unchanged. Mounting bounded sub-apps — rather than threading one shared `app` through every module's `defineXxxRoutes` — keeps `tsc`'s route-type instantiation bounded so the typed client scales to many modules.
|
|
31
|
+
- **`defineXxxRoutes(app, deps)` is kept as an advanced / back-compat escape hatch**, but threading one shared `app` through several modules detonates `tsc` (TS2589 / "instantiation excessively deep"), collapsing the `hc()` client to `never`. Prefer `buildXxxApp`. When you do use it, return the chained app (a `(app) => void` shape loses the type chain) and stay generic over Hono's schema param `S`.
|
|
32
|
+
- **Cross-cutting middleware (`registerErrorHandlers`, `httpLogger`, CORS) lives on the root only** — a module sub-app must not set its own `onError` or `use("*")`.
|
|
33
|
+
- Use proper HTTP methods (GET, POST, PUT, PATCH, DELETE). Plural nouns for collections (`/posts`, `/posts/:id`).
|
|
34
|
+
- Status codes: 200 (success), 201 (created), 204 (no body), 400 (validation), 401 (auth), 403 (permission), 404 (not found), 409 (conflict), 422 (semantic validation), 429 (rate limit), 500 (unhandled).
|
|
35
|
+
|
|
36
|
+
## Validation
|
|
37
|
+
|
|
38
|
+
- Register Zod schemas via `validate("json"|"query"|"param", schema)`. Read parsed input with `c.req.valid("json"|...)`.
|
|
39
|
+
- **Never use `c.req.json()` / `c.req.query()` / `c.req.param()` directly** — the route registry, typed client, and (eventual) OpenAPI all read off the registered schema. The framework's `no-restricted-syntax` ESLint rule fires on raw use.
|
|
40
|
+
- Use `.strict()` on object schemas to reject unknown fields.
|
|
41
|
+
- Co-locate request + response Zod schemas in `validation/schemas.ts`. Export inferred types via `z.infer`.
|
|
42
|
+
- Derive create / update schemas from Drizzle tables using `drizzle-zod` where possible.
|
|
43
|
+
|
|
44
|
+
## Services
|
|
45
|
+
|
|
46
|
+
- Extend `DrizzleEntityService<typeof table>` for inherited CRUD (`get`, `getAll`, `list`, `count`, `create`, `update`, `delete` + `*WithContext` variants).
|
|
47
|
+
- Override `getDefaultSearchFields()` / `getDefaultRelations()` per module.
|
|
48
|
+
- Add domain methods on the service; keep route handlers thin (delegate to the service).
|
|
49
|
+
- Use `withTransaction(db, tx => ...)` for multi-step operations.
|
|
50
|
+
- For queue-after-commit correctness, **never enqueue BullMQ jobs inside a transaction** — use the outbox pattern via `OutboxEventEmitter.emit({...}, { tx })`.
|
|
51
|
+
|
|
52
|
+
## Errors
|
|
53
|
+
|
|
54
|
+
- Throw from the AppError taxonomy: `NotFoundError`, `BadRequestError`, `UnauthorizedError`, `ForbiddenError`, `ConflictError`, `ValidationError`, `RateLimitError`, etc.
|
|
55
|
+
- Never shape error responses inside handlers. `registerErrorHandlers(app)` (called once at boot) handles the JSON shape uniformly.
|
|
56
|
+
- Don't expose internal stack traces or DB error details. The error handler strips them in production.
|
|
57
|
+
|
|
58
|
+
## Migrations
|
|
59
|
+
|
|
60
|
+
- **Never hand-write SQL migrations.** Generate them from schema source: `npm run db:generate -- --name <description>`.
|
|
61
|
+
- The framework's plugin `PreToolUse` hook (`block-migration-edit.sh`) blocks edits to `src/db/migrations/*.sql` to enforce this.
|
|
62
|
+
- Apply with `npm run db:migrate`. Inspect with `npm run db:studio`.
|
|
63
|
+
- Schema lives in `modules/<name>/schema.ts` (per module) and is composed in `src/db/schema.ts`. Use `...baseFields` for audit columns.
|
|
64
|
+
|
|
65
|
+
## Logging
|
|
66
|
+
|
|
67
|
+
- Import: `import { logger } from "@sixthsummit/ship-api/observability/logger"`.
|
|
68
|
+
- **Never `console.log` / `console.error` / `console.warn`.** They lose request-id and trace context that pino + OpenTelemetry inject automatically.
|
|
69
|
+
- Log structured: `logger.info({ accountId, action }, "user did thing")`, not `logger.info("user " + accountId + " did thing")`.
|
|
70
|
+
|
|
71
|
+
## Environment
|
|
72
|
+
|
|
73
|
+
- All `process.env` access goes through `src/environment.ts` via `defineEnv(zodSchema)`. The function fail-fasts at boot with structured errors for missing/invalid vars.
|
|
74
|
+
- **Never `process.env.X` outside `src/environment.ts`.** The framework's `no-restricted-globals` ESLint rule catches violations.
|
|
75
|
+
|
|
76
|
+
## Idempotency, rate limit, CSRF
|
|
77
|
+
|
|
78
|
+
- Mutating routes that may be retried (payment, email send, account creation): apply `idempotency({ ttlSec, scope })` middleware. Clients send `Idempotency-Key` header.
|
|
79
|
+
- Rate-limit sensitive routes: `rateLimit({ windowMs, max, keyGenerator, scope })`. Default behavior on Redis unavailable is fail-closed.
|
|
80
|
+
- CSRF default is Origin / Sec-Fetch-Site checking on mutating requests. For double-submit-cookie protection, opt in with `csrf({ doubleSubmit: true })`.
|