@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,166 @@
|
|
|
1
|
+
# Agents Guide — your ShipAPI v4 app
|
|
2
|
+
|
|
3
|
+
This is the entry-point doc for any AI coding agent (Claude Code, Cursor, Codex, etc.) working in this app. Read it before doing anything.
|
|
4
|
+
|
|
5
|
+
## What this is
|
|
6
|
+
|
|
7
|
+
A TypeScript backend on **Hono + Drizzle + pluggable AuthProvider + BullMQ + OpenTelemetry**, scaffolded from `@sixthsummit/ship-api` v4. The framework is your dependency at `node_modules/@sixthsummit/ship-api/`; you write modules, schemas, routes, jobs, and tests against its primitives.
|
|
8
|
+
|
|
9
|
+
The framework's full agent guide lives at `https://github.com/SixthSummit/Ship/blob/main/AGENTS.md`. This doc is the consumer-side projection — patterns and gotchas that apply *inside this app*, not the framework's monorepo.
|
|
10
|
+
|
|
11
|
+
## Where things live
|
|
12
|
+
|
|
13
|
+
- `src/index.ts` — bootstrap only: load instrumentation, then dynamically import the server.
|
|
14
|
+
- `src/instrumentation.ts` — the early OpenTelemetry boundary; no application imports.
|
|
15
|
+
- `src/server.ts` — `createApp()` root; mount each module sub-app via `root.route("/", buildXxxApp(deps))`; `serve()`.
|
|
16
|
+
- `src/environment.ts` — `defineEnv(zodSchema)`. **The only application-config boundary for `process.env`; `instrumentation.ts` is the intentional early exception.**
|
|
17
|
+
- `src/db/schema.ts` — composed Drizzle schema (module schema fragments + your tables; the framework ships no default tables).
|
|
18
|
+
- `src/db/migrations/` — `drizzle-kit`-generated SQL. **Never hand-edit.**
|
|
19
|
+
- `src/config/modules.ts` — placeholder for planned module auto-wiring; today, wire modules in `src/server.ts`.
|
|
20
|
+
- `src/modules/<name>/` — your feature modules. Canonical 7-file shape: `schema.ts`, `permissions.ts`, `validation/schemas.ts`, `services/<NameSingular>Service.ts`, `routes.ts`, `index.ts`, `module.json`.
|
|
21
|
+
- `tests/` — integration tests.
|
|
22
|
+
- `drizzle.config.ts` — `drizzle-kit` config consumed by the `db:*` scripts.
|
|
23
|
+
- `docker-compose.yml` — Postgres + Redis + OTel collector for `ship-api dev`.
|
|
24
|
+
- `ship-api.config.ts` — Claude Code plugin activation marker (don't delete).
|
|
25
|
+
|
|
26
|
+
## Run, test, build
|
|
27
|
+
|
|
28
|
+
- `npm install` — install deps.
|
|
29
|
+
- `ship-api dev` — recommended dev workflow. Brings up Docker Compose deps, runs `tsx watch src/index.ts`, polls `/livez` until ready, prints the URL.
|
|
30
|
+
- `npm run build` — build to `lib/`.
|
|
31
|
+
- `npm start` — run built output.
|
|
32
|
+
- `npm test` — Vitest. The scaffold ships with `src/index.test.ts` as a sample (exercises `createApp` via `app.request("/...")` without booting a server) — use it as the pattern for your own tests; service tests next to the service, route tests at `src/modules/<name>/routes.test.ts`.
|
|
33
|
+
- `npm run lint` — ESLint.
|
|
34
|
+
- `npm run format` — Prettier write.
|
|
35
|
+
- `npm run type-check` — `tsc --noEmit`.
|
|
36
|
+
- `npm run db:generate -- --name <description>` — generate a migration from schema diffs.
|
|
37
|
+
- `npm run db:migrate` — apply pending migrations.
|
|
38
|
+
- `npm run db:studio` — Drizzle Studio web UI.
|
|
39
|
+
|
|
40
|
+
## Adding a feature
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
# Full canonical 7-file module shape (schema / permissions / validation /
|
|
44
|
+
# service / routes / index + module.json)
|
|
45
|
+
ship-api g module billing
|
|
46
|
+
|
|
47
|
+
# Or — when you already know the columns — a CRUD resource in one go:
|
|
48
|
+
ship-api g resource posts --fields "title:string,body:text,published:boolean,publishedAt:timestamp?"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
> Scaffolding stamps a `scaffold.tool` breadcrumb into `module.json` for the by-tool delivery metric. Claude Code auto-detects; **Cursor users should export `SHIP_API_SCAFFOLD_TOOL=cursor`** first (Cursor has no reliable env marker), so the metric attributes correctly.
|
|
52
|
+
|
|
53
|
+
Then customize the generated files:
|
|
54
|
+
|
|
55
|
+
1. **Schema** — `src/modules/<name>/schema.ts` defines the Drizzle `pgTable` + relations + types. Use `...baseFields` for audit columns (`createdAt`, `updatedAt`, `deletedAt`, `createdBy`, `updatedBy`).
|
|
56
|
+
2. **Permissions** — `src/modules/<name>/permissions.ts` exports `module:resource:action` slug constants.
|
|
57
|
+
3. **Validation** — `src/modules/<name>/validation/schemas.ts` defines the Zod schemas. Use `.strict()` on object schemas.
|
|
58
|
+
4. **Service** — `src/modules/<name>/services/<NameSingular>Service.ts` extends `DrizzleEntityService<typeof table>`. Override `getDefaultSearchFields()` / `getDefaultRelations()` per module. Add domain-specific methods.
|
|
59
|
+
5. **Routes** — `src/modules/<name>/routes.ts` exports `buildXxxApp(deps)`, which returns the module's **own** sub-app via `defineXxxRoutes(createModuleApp("xxx"), deps)`. Each route chains: `requireAuth({ provider })` → `requirePermission(slug)` → `validate("json"|"query"|"param", schema)` → handler. `defineXxxRoutes(app, deps)` is kept as an advanced escape hatch (return the chained app, stay schema-generic) but threading one shared app through several modules detonates `tsc` — see the foot-gun note below.
|
|
60
|
+
6. **Compose** — mount each module sub-app onto the root in `src/server.ts`: `const app = root.route("/", buildXxxApp(deps))` (chaining the mounts), then `export type ShipApiClient = typeof app`. Modules keep their absolute paths, so the client shape is unchanged; cross-cutting concerns (`registerErrorHandlers`, `httpLogger`, CORS) live on the root only.
|
|
61
|
+
7. **Tests** — `<NameSingular>Service.test.ts` (fake-DB unit) + `routes.test.ts` (full-chain integration).
|
|
62
|
+
8. **Migration** — `npm run db:generate -- --name add_<name>_<change>` then commit the generated SQL.
|
|
63
|
+
|
|
64
|
+
## Conventions you must follow
|
|
65
|
+
|
|
66
|
+
The full rules are in `.cursor/rules/`. Read them when relevant. Indexed:
|
|
67
|
+
|
|
68
|
+
- @.cursor/rules/api.mdc — RESTful design, response shapes, error handling, **never write migrations manually**
|
|
69
|
+
- @.cursor/rules/typescript.mdc — coding standards, type / null safety
|
|
70
|
+
- @.cursor/rules/testing.mdc — Vitest patterns, mocking, route + service test shapes
|
|
71
|
+
- @.cursor/rules/security.mdc — Firebase auth, RBAC, permission system
|
|
72
|
+
- @.cursor/rules/commits.mdc — Conventional Commits
|
|
73
|
+
|
|
74
|
+
## Things agents commonly get wrong
|
|
75
|
+
|
|
76
|
+
- **Don't read `process.env` directly** outside `src/environment.ts` / `defineEnv()` and the early `src/instrumentation.ts` boundary. Module + handler code routes through the validated `env` object.
|
|
77
|
+
- **Don't hand-write SQL migrations.** Use `drizzle-kit generate` from schema source. The framework's plugin `PreToolUse` hook (`block-migration-edit.sh`) blocks edits to `src/db/migrations/*.sql` to enforce this.
|
|
78
|
+
- **Don't `console.log`.** Use `logger` from `@sixthsummit/ship-api/observability/logger`. `console.*` writes lose request-id + trace context.
|
|
79
|
+
- **Don't import from `node_modules/@sixthsummit/ship-api/lib/`.** Those are build artifacts. Import from package-export paths (`@sixthsummit/ship-api`, `@sixthsummit/ship-api/client`, etc.).
|
|
80
|
+
- **Don't use `c.req.json()` / `c.req.query()` / `c.req.param()`** directly. Register a Zod schema with `validate("json"|"query"|"param", schema)` and read via `c.req.valid(...)`. The route registry, typed client, and (eventual) OpenAPI all read off the registered schema. ESLint's `no-restricted-syntax` rule fires on raw use.
|
|
81
|
+
- **Don't import raw Drizzle operators (`eq`/`and`/`sql`/…) into a service.** Express queries via `DrizzleEntityService` + the `QueryOptions` DSL (raw Drizzle belongs in `src/db` / schema files). ESLint's `@typescript-eslint/no-restricted-imports` rule fires on a raw `drizzle-orm` value import outside the data-access layer; for specialized access (row locking, raw SQL) add a justified `eslint-disable`. Type-only imports are fine.
|
|
82
|
+
- **Don't skip `requireAuth({ provider })` / `requirePermission(slug)` middleware** on protected routes — authorization runs at the route, not on the controller.
|
|
83
|
+
- **Don't shape error responses inside handlers** — throw from the AppError taxonomy (`NotFoundError`, `BadRequestError`, etc.). `registerErrorHandlers(app)` shapes the JSON response uniformly.
|
|
84
|
+
- **Don't enqueue BullMQ jobs inside a transaction** — risks "queued before commit". Use the **outbox pattern** via `OutboxEventEmitter.emit({...}, { tx })`.
|
|
85
|
+
- **Don't thread one shared `app` through several `defineXxxRoutes` calls.** That accumulates one giant route-type and detonates `tsc` (TS2589). Build each module as its own sub-app with `buildXxxApp(deps)` (on `createModuleApp("xxx")`) and mount it via `root.route("/", buildXxxApp(deps))`. If you reach for the raw `defineXxxRoutes(app, ...)` escape hatch, keep it schema-generic and **return** the chained `app` (never `(app) => void`) so RPC types survive on `hc<ShipApiClient>()` consumers.
|
|
86
|
+
- **Don't commit secrets.** Env vars only.
|
|
87
|
+
|
|
88
|
+
## Consuming this app from clients
|
|
89
|
+
|
|
90
|
+
The cross-framework contract is `hc()` typed-client over your app's chained-app type. **No codegen.** Schema changes flow:
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
Drizzle table → drizzle-zod → zValidator → c.req.valid() → hc<ShipApiClient>()
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
through TypeScript types end-to-end.
|
|
97
|
+
|
|
98
|
+
**Server side** — mount each module sub-app on the root, then pin the typed-app alias:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
// src/server.ts
|
|
102
|
+
import { createApp, registerErrorHandlers, httpLogger } from "@sixthsummit/ship-api";
|
|
103
|
+
import { buildAccountsApp } from "./modules/accounts";
|
|
104
|
+
|
|
105
|
+
const root = createApp({ cors });
|
|
106
|
+
registerErrorHandlers(root); // root owns cross-cutting concerns
|
|
107
|
+
root.use("*", httpLogger());
|
|
108
|
+
|
|
109
|
+
const app = root
|
|
110
|
+
.route("/", buildAccountsApp({ service: new AccountService(db), provider }));
|
|
111
|
+
export type ShipApiClient = typeof app; // api.accounts.$get — flat shape
|
|
112
|
+
export { app };
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Client side** (web / mobile / another service) — import the type only:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import { hc } from "@sixthsummit/ship-api/client";
|
|
119
|
+
import type { ShipApiClient } from "@my-org/api/app";
|
|
120
|
+
|
|
121
|
+
export const api = hc<ShipApiClient>(BASE_URL, { init: { credentials: "include" } });
|
|
122
|
+
const me = await api.me.$get();
|
|
123
|
+
if (me.ok) { const account = await me.json(); /* typed end-to-end */ }
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## How to verify your work
|
|
127
|
+
|
|
128
|
+
1. `npm run type-check` — passes.
|
|
129
|
+
2. `npm run lint` — passes (the `no-restricted-syntax` rule catches raw `c.req.json/query/param`).
|
|
130
|
+
3. `npm test` — passes.
|
|
131
|
+
4. `npx vitest run src/modules/<name>/` — module-specific tests pass.
|
|
132
|
+
5. If you touched routes — hit them via curl against `ship-api dev` and confirm status code, response shape, auth behavior.
|
|
133
|
+
6. If you touched the schema — `npm run db:generate -- --name <description>` produces a sane SQL diff.
|
|
134
|
+
|
|
135
|
+
## Claude Code specifics
|
|
136
|
+
|
|
137
|
+
The `@sixthsummit/ship-api-claude-plugin` auto-activates in this workspace (it detects the `ship-api.config.ts` marker file). You get:
|
|
138
|
+
|
|
139
|
+
- **Slash commands**: `/ship:lint-conventions [--diff|--all]`, `/ship:new-module <description>`, `/ship:add-job <name> -m <module>`, `/ship:add-cron <name> -m <module>`, `/ship:add-migration <name>`, `/ship:trace-request <request-id>`, `/ship:sherpa-brief [--base <ref>]`
|
|
140
|
+
- **Agents**: `ship-architect` (designs new modules), `ship-codegen` (executes a plan), `ship-reviewer` (audits a diff for v4 conventions — auto-fires on `Edit`/`Write` to `modules/**/*.ts` via the PostToolUse hook), `qa-brief` (generates a Sherpa-ready QA brief from the branch diff — invoked by the `sherpa-brief.yml` workflow on PR-to-`dev` and push-to-`dev`)
|
|
141
|
+
- **Skills**: ship-api-conventions, ship-module-pattern, ship-drizzle-migrations, ship-bullmq-jobs, ship-otel-debugging
|
|
142
|
+
- **MCP server tools**: `list_routes`, `describe_route`, `find_route_collisions`, `execute_route` (the load-bearing one — runs requests through the live middleware chain with pre-flight schema validation)
|
|
143
|
+
|
|
144
|
+
Tooling tips:
|
|
145
|
+
|
|
146
|
+
- Use `Edit` over `Write` for existing files.
|
|
147
|
+
- Use the `Explore` subagent for broad code searches; use direct `Grep`/`Read` for known paths.
|
|
148
|
+
- Don't spin long-running processes (`npm run dev`, `tsx watch`, etc.) — they stall the agent loop. Use `ship-api dev` only when the user explicitly asks; otherwise leave it to them.
|
|
149
|
+
- For UI / integration verification, ask the user to verify in their browser; don't claim "tested" without evidence.
|
|
150
|
+
- The plugin's MCP `execute_route` tool is the right way to drive routes during agent iteration; pre-flight schema validation surfaces schema errors *as* schema errors, not as opaque 500s.
|
|
151
|
+
|
|
152
|
+
## QA handoff (Sherpa briefs)
|
|
153
|
+
|
|
154
|
+
A `.github/workflows/sherpa-brief.yml` ships with this template. It auto-generates a plain-English QA brief from each branch's diff and hands it to the QA team via [Sherpa](https://github.com/sixthsummit/sherpa), with **zero engineer admin work**:
|
|
155
|
+
|
|
156
|
+
- **On PR-to-`dev`** — posts (or updates) a sticky preview comment on the PR. Informational; engineers can ignore it.
|
|
157
|
+
- **On push to `dev`** — posts the final brief to the QA Slack channel (`SLACK_QA_WEBHOOK_URL`) and uploads `brief.md` as a workflow artifact.
|
|
158
|
+
|
|
159
|
+
The brief is generated by the framework's `qa-brief` agent and contains plain-English flows the QA pastes into Sherpa's `/explore` — no Playwright code, no curl snippets. Editor-agnostic: Cursor and Claude Code engineers both get the same output via the CI path.
|
|
160
|
+
|
|
161
|
+
Add these repo secrets (Settings → Secrets and variables → Actions):
|
|
162
|
+
|
|
163
|
+
- `ANTHROPIC_API_KEY` — required for the headless agent run.
|
|
164
|
+
- `SLACK_QA_WEBHOOK_URL` — Incoming Webhook for the QA channel. Optional — the push-to-dev step skips Slack with a warning if unset.
|
|
165
|
+
|
|
166
|
+
If your deploy branch isn't `dev`, search-and-replace `dev` in the workflow's `on:` block. Local preview (Claude Code only): `/ship:sherpa-brief`. Full reference: [ShipAPI docs → Tooling → Sherpa QA briefs](https://docs.shipapi.dev/tooling/sherpa-qa-briefs).
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# {{PROJECT_NAME}}
|
|
2
|
+
|
|
3
|
+
A ShipAPI v4 application — TypeScript backend on Hono + Drizzle + pluggable AuthProvider + BullMQ + OpenTelemetry. The framework is your dependency at `node_modules/@sixthsummit/ship-api/`; you write modules, schemas, routes, jobs, and tests against its primitives.
|
|
4
|
+
|
|
5
|
+
## Agent onboarding
|
|
6
|
+
|
|
7
|
+
Read `AGENTS.md` first — it covers what this app is, where things live, how to run/test/build, the canonical "add a feature" flow, common agent mistakes, and how to verify your work. The rules in `.cursor/rules/` (also `@`-imported below) are the canonical conventions; AGENTS.md is the entry-point that points at them.
|
|
8
|
+
|
|
9
|
+
@AGENTS.md
|
|
10
|
+
|
|
11
|
+
## Project rules
|
|
12
|
+
|
|
13
|
+
@.cursor/rules/api.mdc
|
|
14
|
+
@.cursor/rules/typescript.mdc
|
|
15
|
+
@.cursor/rules/testing.mdc
|
|
16
|
+
@.cursor/rules/security.mdc
|
|
17
|
+
@.cursor/rules/commits.mdc
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# {{PROJECT_NAME}}
|
|
2
|
+
|
|
3
|
+
A ShipAPI v4 application. Generated by `npx ship-api create my-app`.
|
|
4
|
+
|
|
5
|
+
## Stack
|
|
6
|
+
|
|
7
|
+
- **HTTP**: Hono (`@hono/node-server`)
|
|
8
|
+
- **Validation**: Zod 4 + `@hono/zod-validator`
|
|
9
|
+
- **ORM**: Drizzle (Postgres)
|
|
10
|
+
- **Auth**: Pluggable `AuthProvider` (Firebase by default)
|
|
11
|
+
- **Jobs**: BullMQ
|
|
12
|
+
- **Observability**: pino + OpenTelemetry (auto-instrumented)
|
|
13
|
+
- **Typed client**: `hc<ShipApiClient>()` — schema → types → client, no codegen
|
|
14
|
+
|
|
15
|
+
## Quick start
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
# 1. Install deps
|
|
19
|
+
npm install
|
|
20
|
+
|
|
21
|
+
# 2. Copy + populate env
|
|
22
|
+
cp .env.example .env
|
|
23
|
+
# Generate a 32-byte OAUTH_STATE_SECRET (any of these works):
|
|
24
|
+
# openssl rand -hex 32
|
|
25
|
+
# node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
|
|
26
|
+
|
|
27
|
+
# 3. Bring up dependencies + start dev server in one shot
|
|
28
|
+
ship-api dev
|
|
29
|
+
# (Brings up Docker Compose for Postgres / Redis / OTel collector,
|
|
30
|
+
# then `tsx watch src/index.ts`, then waits for /livez to go green
|
|
31
|
+
# before printing the URL.)
|
|
32
|
+
|
|
33
|
+
# 4. Run migrations against the dev db
|
|
34
|
+
npm run db:generate -- --name initial
|
|
35
|
+
npm run db:migrate
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Common workflows
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
ship-api g module billing # scaffold a CRUD module
|
|
42
|
+
ship-api g resource posts \
|
|
43
|
+
--fields "title:string,body:text,published:boolean,publishedAt:timestamp?"
|
|
44
|
+
# CRUD module from a field spec
|
|
45
|
+
ship-api g middleware rate-limit-by-key # add a Hono middleware
|
|
46
|
+
ship-api g job send-invoice-email -m billing # add a BullMQ job stub
|
|
47
|
+
|
|
48
|
+
ship-api g doctor # project health check
|
|
49
|
+
ship-api migrate-orm <path> # codemod TypeORM entities → Drizzle
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Project layout
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
.
|
|
56
|
+
├── ship-api.config.ts — Claude Code plugin activation marker
|
|
57
|
+
├── drizzle.config.ts — drizzle-kit configuration (db:* scripts)
|
|
58
|
+
├── docker-compose.yml — Postgres + Redis + OTel collector
|
|
59
|
+
├── src/
|
|
60
|
+
│ ├── index.ts — instrument first, then dynamically load server
|
|
61
|
+
│ ├── instrumentation.ts — early OpenTelemetry bootstrap boundary
|
|
62
|
+
│ ├── server.ts — createApp + module composition + serve
|
|
63
|
+
│ ├── environment.ts — defineEnv(zodSchema) — boundary for process.env
|
|
64
|
+
│ ├── config/
|
|
65
|
+
│ │ └── modules.ts — placeholder for planned auto-wiring (wire in index.ts)
|
|
66
|
+
│ ├── db/
|
|
67
|
+
│ │ ├── schema.ts — composed schema (module fragments + your tables)
|
|
68
|
+
│ │ └── migrations/ — drizzle-kit-generated SQL
|
|
69
|
+
│ └── modules/ — your feature modules (one subdir per feature)
|
|
70
|
+
│ └── (created via `ship-api add <module>` / `g module <name>`)
|
|
71
|
+
└── tests/ — integration tests
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Conventions
|
|
75
|
+
|
|
76
|
+
The framework's load-bearing conventions are documented in:
|
|
77
|
+
|
|
78
|
+
- **AGENTS.md** at the repo root — the entry-point doc for AI coding agents.
|
|
79
|
+
- The Claude Code plugin's skills (auto-loaded when this file is in the workspace).
|
|
80
|
+
- The framework's `.cursor/rules/*.mdc` (synced into the plugin's SKILL.md files).
|
|
81
|
+
|
|
82
|
+
The shortest version:
|
|
83
|
+
|
|
84
|
+
- Routes: each module exposes `buildXxxApp(deps)` returning its own sub-app (on `createModuleApp("xxx")`); mount via `root.route("/", buildXxxApp(deps))` (preserves RPC types end-to-end via `hc<ShipApiClient>()`, and keeps `tsc` bounded as modules grow). `defineXxxRoutes(app, deps)` is a kept escape hatch — threading one shared app through several modules detonates `tsc`.
|
|
85
|
+
- Auth: `requireAuth({ provider })` runs the AuthProvider chain; `requirePermission(slug)` enforces against the resolved user.
|
|
86
|
+
- Validation: `validate("json" | "query" | "param", schema)` wraps `zValidator`; handlers read parsed input via `c.req.valid("json" | …)`. Never `c.req.json()` directly.
|
|
87
|
+
- Errors: throw from the AppError taxonomy (`NotFoundError`, `BadRequestError`, etc.); `registerErrorHandlers(app)` shapes the JSON response.
|
|
88
|
+
- Services: extend `DrizzleEntityService<typeof table>` for inherited CRUD + soft-delete + audit auto-stamping.
|
|
89
|
+
- Migrations: `drizzle-kit generate` from schema source. Never hand-edit `src/db/migrations/*.sql`.
|
|
90
|
+
- Logging: `import { logger } from "@sixthsummit/ship-api/observability/logger"`. Never `console.log`.
|
|
91
|
+
- Env: route application config through the validated `env` object. Only the
|
|
92
|
+
early `instrumentation.ts` boundary reads standard OTel variables directly.
|
|
93
|
+
- Permissions: per-action slug naming (`module:resource:action`), exported as constants.
|
|
94
|
+
|
|
95
|
+
## Migrating from v3
|
|
96
|
+
|
|
97
|
+
See [docs/MIGRATION_V3_TO_V4.md](https://github.com/SixthSummit/Ship/blob/main/docs/MIGRATION_V3_TO_V4.md) at the framework repo for the codemod-assisted parallel-path migration walkthrough.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
node_modules/
|
|
2
|
+
dist/
|
|
3
|
+
.env
|
|
4
|
+
.env.local
|
|
5
|
+
.env.*.local
|
|
6
|
+
|
|
7
|
+
# Drizzle
|
|
8
|
+
src/db/migrations/meta/
|
|
9
|
+
.drizzle/
|
|
10
|
+
|
|
11
|
+
# Build / cache
|
|
12
|
+
*.tsbuildinfo
|
|
13
|
+
.turbo/
|
|
14
|
+
|
|
15
|
+
# OS
|
|
16
|
+
.DS_Store
|
|
17
|
+
Thumbs.db
|
|
18
|
+
|
|
19
|
+
# Editor
|
|
20
|
+
.vscode/
|
|
21
|
+
.idea/
|
|
22
|
+
|
|
23
|
+
# Coverage
|
|
24
|
+
coverage/
|
|
25
|
+
|
|
26
|
+
# Wrangler (only relevant if you opt into edge runtime)
|
|
27
|
+
.wrangler/
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Local-stack dependency services for `ship-api dev`.
|
|
2
|
+
#
|
|
3
|
+
# `ship-api dev` runs `docker compose up -d` against the services below
|
|
4
|
+
# (Postgres + Redis + Jaeger), then runs the app via `tsx watch` on the
|
|
5
|
+
# host so source edits hot-reload without rebuilding a container.
|
|
6
|
+
#
|
|
7
|
+
# Bring everything up manually with:
|
|
8
|
+
# docker compose up -d
|
|
9
|
+
#
|
|
10
|
+
# Reset volumes (drops Postgres data) with:
|
|
11
|
+
# docker compose down -v
|
|
12
|
+
#
|
|
13
|
+
# Run the app inside Docker too (CI / smoke / parity checks): see Dockerfile;
|
|
14
|
+
# `ship-api dev` does not start an api service from this compose file —
|
|
15
|
+
# `tsx watch` on the host is the dev-loop default.
|
|
16
|
+
|
|
17
|
+
services:
|
|
18
|
+
postgres:
|
|
19
|
+
container_name: ship-api-postgres
|
|
20
|
+
image: postgres:16
|
|
21
|
+
restart: unless-stopped
|
|
22
|
+
environment:
|
|
23
|
+
POSTGRES_DB: ship-api
|
|
24
|
+
POSTGRES_USER: ship-api
|
|
25
|
+
POSTGRES_PASSWORD: ship-api
|
|
26
|
+
ports:
|
|
27
|
+
- "5432:5432"
|
|
28
|
+
volumes:
|
|
29
|
+
- postgres_data_ship-api:/var/lib/postgresql/data
|
|
30
|
+
healthcheck:
|
|
31
|
+
test: ["CMD-SHELL", "pg_isready -U ship-api -d ship-api"]
|
|
32
|
+
interval: 5s
|
|
33
|
+
timeout: 5s
|
|
34
|
+
retries: 10
|
|
35
|
+
|
|
36
|
+
redis:
|
|
37
|
+
container_name: ship-api-redis
|
|
38
|
+
image: redis:7-alpine
|
|
39
|
+
restart: unless-stopped
|
|
40
|
+
# `appendonly yes` keeps in-flight queue/job state across restarts; safe
|
|
41
|
+
# for dev. Production Redis tuning belongs in your prod compose / k8s.
|
|
42
|
+
command: ["redis-server", "--appendonly", "yes"]
|
|
43
|
+
ports:
|
|
44
|
+
- "6379:6379"
|
|
45
|
+
volumes:
|
|
46
|
+
- redis_data_ship-api:/data
|
|
47
|
+
healthcheck:
|
|
48
|
+
test: ["CMD", "redis-cli", "ping"]
|
|
49
|
+
interval: 5s
|
|
50
|
+
timeout: 5s
|
|
51
|
+
retries: 10
|
|
52
|
+
|
|
53
|
+
# Jaeger all-in-one — the dev observability viewer for the framework's
|
|
54
|
+
# OpenTelemetry SDK. Exposes:
|
|
55
|
+
# 4317 — OTLP/gRPC (the default the SDK auto-detects)
|
|
56
|
+
# 4318 — OTLP/HTTP (alternate; useful for browser SDKs sharing the env)
|
|
57
|
+
# 16686 — Jaeger UI (open in a browser to inspect traces)
|
|
58
|
+
#
|
|
59
|
+
# Why Jaeger here instead of an OTel Collector: in dev, the high-value
|
|
60
|
+
# surface is the trace UI — "I just ran my code, show me the spans." The
|
|
61
|
+
# framework also commits to OTel-only for job history (BullMQ jobs flow
|
|
62
|
+
# through OTel spans rather than a `job_runs` audit table), so a viewer
|
|
63
|
+
# is load-bearing for debugging. Jaeger has a native OTLP receiver, so
|
|
64
|
+
# the app's exporter config doesn't need a separate collector hop.
|
|
65
|
+
#
|
|
66
|
+
# Production path is different: point `OTEL_EXPORTER_OTLP_ENDPOINT` at
|
|
67
|
+
# your real APM (Honeycomb / Tempo / Datadog / Cloud Trace / etc.), or
|
|
68
|
+
# run a dedicated OTel Collector with `otel/opentelemetry-collector-contrib`
|
|
69
|
+
# if you need batching / sampling / multi-backend fan-out.
|
|
70
|
+
jaeger:
|
|
71
|
+
container_name: ship-api-jaeger
|
|
72
|
+
image: jaegertracing/all-in-one:latest
|
|
73
|
+
restart: unless-stopped
|
|
74
|
+
environment:
|
|
75
|
+
COLLECTOR_OTLP_ENABLED: "true"
|
|
76
|
+
ports:
|
|
77
|
+
- "4317:4317" # OTLP/gRPC
|
|
78
|
+
- "4318:4318" # OTLP/HTTP
|
|
79
|
+
- "16686:16686" # Jaeger UI
|
|
80
|
+
|
|
81
|
+
volumes:
|
|
82
|
+
postgres_data_ship-api:
|
|
83
|
+
redis_data_ship-api:
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { defineConfig } from "drizzle-kit";
|
|
2
|
+
import { env } from "./src/environment.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Drizzle Kit config — drives the migration tooling
|
|
6
|
+
* (`db:push`, `db:generate`, `db:migrate`, `db:studio`,
|
|
7
|
+
* `db:baseline`).
|
|
8
|
+
*
|
|
9
|
+
* The schema source aggregates the module-owned tables the consumer
|
|
10
|
+
* composes (identity/RBAC lives in the `accounts` module — add it with
|
|
11
|
+
* `ship-api add accounts`) — the same import graph the runtime sees via
|
|
12
|
+
* `createDb({ config, schema })` in `src/index.ts`. Single source of truth,
|
|
13
|
+
* never drift between "what the app uses at runtime" and "what
|
|
14
|
+
* migrations target".
|
|
15
|
+
*
|
|
16
|
+
* NEVER hand-edit the emitted SQL files in `src/db/migrations/`.
|
|
17
|
+
* The next `db:generate` will overwrite or break history. Edit
|
|
18
|
+
* the schema source and re-generate.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
export default defineConfig({
|
|
22
|
+
schema: "./src/db/schema.ts",
|
|
23
|
+
out: "./src/db/migrations",
|
|
24
|
+
dialect: "postgresql",
|
|
25
|
+
dbCredentials: {
|
|
26
|
+
url: env.DATABASE_URL,
|
|
27
|
+
},
|
|
28
|
+
// Verbose output makes `db:generate --name <description>` more
|
|
29
|
+
// informative when reviewing diffs in PR.
|
|
30
|
+
verbose: true,
|
|
31
|
+
// Prompt before applying destructive operations (column drops,
|
|
32
|
+
// type changes that need cast). Skip with --yes for CI.
|
|
33
|
+
strict: true,
|
|
34
|
+
});
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import js from "@eslint/js";
|
|
2
|
+
import tseslint from "typescript-eslint";
|
|
3
|
+
|
|
4
|
+
export default [
|
|
5
|
+
{
|
|
6
|
+
ignores: ["dist/**", "node_modules/**"],
|
|
7
|
+
},
|
|
8
|
+
js.configs.recommended,
|
|
9
|
+
...tseslint.configs.recommended,
|
|
10
|
+
{
|
|
11
|
+
languageOptions: {
|
|
12
|
+
parserOptions: { ecmaVersion: 2022, sourceType: "module" },
|
|
13
|
+
globals: {
|
|
14
|
+
console: "readonly",
|
|
15
|
+
process: "readonly",
|
|
16
|
+
Buffer: "readonly",
|
|
17
|
+
setInterval: "readonly",
|
|
18
|
+
clearInterval: "readonly",
|
|
19
|
+
setTimeout: "readonly",
|
|
20
|
+
clearTimeout: "readonly",
|
|
21
|
+
global: "readonly",
|
|
22
|
+
__dirname: "readonly",
|
|
23
|
+
__filename: "readonly",
|
|
24
|
+
fetch: "readonly",
|
|
25
|
+
URL: "readonly",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
rules: {
|
|
29
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
30
|
+
"@typescript-eslint/no-unused-vars": [
|
|
31
|
+
"error",
|
|
32
|
+
{ args: "none", varsIgnorePattern: "^_" },
|
|
33
|
+
],
|
|
34
|
+
"no-restricted-globals": [
|
|
35
|
+
"error",
|
|
36
|
+
{
|
|
37
|
+
name: "process",
|
|
38
|
+
message:
|
|
39
|
+
"Read env via the validated `env` object from src/environment.ts (defineEnv). Direct process.env access bypasses the schema.",
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
"no-restricted-syntax": [
|
|
43
|
+
"error",
|
|
44
|
+
{
|
|
45
|
+
selector:
|
|
46
|
+
"CallExpression[callee.type='MemberExpression'][callee.object.type='MemberExpression'][callee.object.property.name='req'][callee.property.name=/^(json|query|param)$/]",
|
|
47
|
+
message:
|
|
48
|
+
"Avoid raw `c.req.json()` / `c.req.query()` / `c.req.param()`. Register a Zod schema with validate() and read via c.req.valid(...).",
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
// Keep raw Drizzle query operators in the data-access layer. Express
|
|
52
|
+
// service queries via QueryOptions / DrizzleEntityService so a future
|
|
53
|
+
// ORM swap touches only the db layer. Schema (src/db, src/modules/**/
|
|
54
|
+
// schema.ts) is exempt below; type-only imports are allowed.
|
|
55
|
+
"@typescript-eslint/no-restricted-imports": [
|
|
56
|
+
"error",
|
|
57
|
+
{
|
|
58
|
+
paths: [
|
|
59
|
+
{
|
|
60
|
+
name: "drizzle-orm",
|
|
61
|
+
message:
|
|
62
|
+
"Raw Drizzle operators (eq/and/or/sql/…) bypass the QueryOptions abstraction. Express service queries via QueryOptions / DrizzleEntityService so an ORM swap touches only the db layer. For specialized access (row locking, raw SQL), add `// eslint-disable-next-line @typescript-eslint/no-restricted-imports -- <reason>`.",
|
|
63
|
+
allowTypeImports: true,
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
// Operators also re-export from drizzle-orm/sql* and **/expressions
|
|
67
|
+
// subpaths; block those too so `import { eq } from "drizzle-orm/sql"`
|
|
68
|
+
// can't dodge the rule. `drizzle-orm/pg-core` (columns) stays free.
|
|
69
|
+
patterns: [
|
|
70
|
+
{
|
|
71
|
+
group: [
|
|
72
|
+
"drizzle-orm/sql",
|
|
73
|
+
"drizzle-orm/sql/**",
|
|
74
|
+
"drizzle-orm/**/expressions",
|
|
75
|
+
"drizzle-orm/**/expressions/**",
|
|
76
|
+
],
|
|
77
|
+
message:
|
|
78
|
+
"Raw Drizzle operators re-export from these subpaths too — keep them in the data-access layer (src/db / schema) and express service queries via QueryOptions / DrizzleEntityService.",
|
|
79
|
+
allowTypeImports: true,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
// Schema + the db layer are where raw Drizzle belongs.
|
|
88
|
+
files: ["src/db/**", "src/modules/**/schema.ts"],
|
|
89
|
+
rules: { "@typescript-eslint/no-restricted-imports": "off" },
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
files: ["src/environment.ts"],
|
|
93
|
+
rules: {
|
|
94
|
+
// environment.ts is the boundary that reads process.env via
|
|
95
|
+
// defineEnv. The rest of the app routes through `env`.
|
|
96
|
+
"no-restricted-globals": "off",
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
files: ["**/*.test.ts"],
|
|
101
|
+
rules: {
|
|
102
|
+
"no-restricted-syntax": "off",
|
|
103
|
+
"@typescript-eslint/no-restricted-imports": "off",
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
];
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ship-api-app",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "ShipAPI v4 application",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"private": true,
|
|
7
|
+
"scripts": {
|
|
8
|
+
"dev": "ship-api dev",
|
|
9
|
+
"build": "tsc",
|
|
10
|
+
"start": "node dist/src/index.js",
|
|
11
|
+
"type-check": "tsc --noEmit",
|
|
12
|
+
"lint": "eslint .",
|
|
13
|
+
"lint:fix": "eslint . --fix",
|
|
14
|
+
"test": "vitest run",
|
|
15
|
+
"test:watch": "vitest",
|
|
16
|
+
"db:push": "drizzle-kit push",
|
|
17
|
+
"db:generate": "drizzle-kit generate",
|
|
18
|
+
"db:migrate": "drizzle-kit migrate",
|
|
19
|
+
"db:studio": "drizzle-kit studio",
|
|
20
|
+
"db:baseline": "drizzle-kit introspect && drizzle-kit migrate"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@hono/node-server": "^1.19.14",
|
|
24
|
+
"@hono/zod-validator": "^0.7.6",
|
|
25
|
+
"@sixthsummit/ship-observability-otel": "^1.0.0",
|
|
26
|
+
"drizzle-orm": "^0.45.2",
|
|
27
|
+
"drizzle-zod": "^0.8.3",
|
|
28
|
+
"firebase-admin": "^13.10.0",
|
|
29
|
+
"hono": "^4.12.15",
|
|
30
|
+
"ioredis": "^5.10.1",
|
|
31
|
+
"jose": "^6.2.3",
|
|
32
|
+
"pg": "^8.16.3",
|
|
33
|
+
"pino": "^9.14.0",
|
|
34
|
+
"pino-pretty": "^13.1.3",
|
|
35
|
+
"zod": "^4.0.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@eslint/js": "^10.0.0",
|
|
39
|
+
"@types/node": "^24.1.0",
|
|
40
|
+
"@types/pg": "^8.11.0",
|
|
41
|
+
"drizzle-kit": "^0.31.10",
|
|
42
|
+
"eslint": "^10.0.0",
|
|
43
|
+
"tsx": "^4.20.3",
|
|
44
|
+
"typescript": "^5.9.2",
|
|
45
|
+
"typescript-eslint": "^8.0.0",
|
|
46
|
+
"vitest": "^4.1.8"
|
|
47
|
+
},
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=22"
|
|
50
|
+
},
|
|
51
|
+
"overrides": {
|
|
52
|
+
"uuid": "^11.1.1",
|
|
53
|
+
"@esbuild-kit/core-utils": {
|
|
54
|
+
"esbuild": "^0.25.0"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ship-api.config.ts` — marker file the Claude Code plugin's
|
|
3
|
+
* activation glob keys off (`**\/ship-api.config.ts`). When this
|
|
4
|
+
* file is present at the workspace root, the plugin's agents,
|
|
5
|
+
* slash commands, skills, and hooks become available; when it's
|
|
6
|
+
* absent, the plugin stays dormant.
|
|
7
|
+
*
|
|
8
|
+
* Plugin-side configuration the framework does not own (custom
|
|
9
|
+
* skill-trigger lists, project-specific agent prompts, hook
|
|
10
|
+
* overrides) lives here. The framework's runtime config lives in
|
|
11
|
+
* `src/environment.ts` (validated) and `src/index.ts`
|
|
12
|
+
* (composition).
|
|
13
|
+
*/
|
|
14
|
+
export const config = {
|
|
15
|
+
/** Plugin-readable hint for agent-driven workflows. */
|
|
16
|
+
framework: "ship-api",
|
|
17
|
+
/** Plugin-readable version pin so agents pick the right SKILL.md. */
|
|
18
|
+
frameworkVersion: "4",
|
|
19
|
+
} as const;
|
|
20
|
+
|
|
21
|
+
export default config;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Materialized typed client — the "compile before using the client" lever.
|
|
3
|
+
*
|
|
4
|
+
* `hc<typeof app>()` re-instantiates your entire route chain every time a
|
|
5
|
+
* consumer (web / mobile / another service) touches the client — fine for a
|
|
6
|
+
* handful of routes, but as your app grows the per-keystroke type work in the
|
|
7
|
+
* consumer's editor adds up. Hono's recommended fix is to let `tsc` do that
|
|
8
|
+
* instantiation **once** at this package's build, emit it to `.d.ts`
|
|
9
|
+
* (`declaration: true` is set in `tsconfig.json`), and have consumers import
|
|
10
|
+
* the materialized type from your built package instead of re-deriving it from
|
|
11
|
+
* source.
|
|
12
|
+
*
|
|
13
|
+
* Consumers import `hcWithType` / `Client` from here rather than calling
|
|
14
|
+
* `hc<ShipApiClient>()` themselves:
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* // web / mobile / microservice
|
|
18
|
+
* import { hcWithType } from "@my-org/api/client";
|
|
19
|
+
* export const api = hcWithType(BASE_URL, { init: { credentials: "include" } });
|
|
20
|
+
* const me = await api.accounts[":id"].$get({ param: { id } });
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* `import type { ShipApiClient }` is erased at runtime, so importing this file
|
|
24
|
+
* does NOT boot the server in `index.ts` — only the tiny `hono/client` runtime
|
|
25
|
+
* is pulled in.
|
|
26
|
+
*/
|
|
27
|
+
import { hc } from "@sixthsummit/ship-api/client";
|
|
28
|
+
import type { ShipApiClient } from "./index.js";
|
|
29
|
+
|
|
30
|
+
/** The fully-resolved `hc()` client type for this app. */
|
|
31
|
+
export type Client = ReturnType<typeof hc<ShipApiClient>>;
|
|
32
|
+
|
|
33
|
+
/** `hc()` pre-bound to this app's type — use instead of `hc<ShipApiClient>()`. */
|
|
34
|
+
export const hcWithType = (...args: Parameters<typeof hc>): Client => hc<ShipApiClient>(...args);
|