@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,250 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
import fs from "fs/promises";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Project-name validator (F17). Mirrors npm's package-name rules
|
|
12
|
+
* (the loose subset that travels safely in directory paths). Reject
|
|
13
|
+
* names that:
|
|
14
|
+
* - contain path separators (`/`, `\`)
|
|
15
|
+
* - contain `..` (parent-dir traversal, even if `path.resolve` would
|
|
16
|
+
* later catch it)
|
|
17
|
+
* - contain null bytes (filesystem string-termination footgun)
|
|
18
|
+
* - start with `.` (hidden / dotfile collision)
|
|
19
|
+
* - start with a digit (npm forbids; npm-compatible names start with
|
|
20
|
+
* a letter)
|
|
21
|
+
* - contain anything outside `[a-zA-Z0-9_-]`
|
|
22
|
+
*
|
|
23
|
+
* Rejecting up front avoids filesystem clobbering of user-owned paths
|
|
24
|
+
* via `ship-api create ../../../etc/foo` (the `path.resolve` call
|
|
25
|
+
* downstream resolves out of `cwd` without these checks).
|
|
26
|
+
*/
|
|
27
|
+
const PROJECT_NAME_RE = /^[a-z][a-z0-9_-]*$/i;
|
|
28
|
+
const FORBIDDEN_CHARS = ["/", "\\", "\0", ".."];
|
|
29
|
+
|
|
30
|
+
export function validateProjectName(name) {
|
|
31
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
32
|
+
return "must be a non-empty string";
|
|
33
|
+
}
|
|
34
|
+
for (const forbidden of FORBIDDEN_CHARS) {
|
|
35
|
+
if (name.includes(forbidden)) {
|
|
36
|
+
return `must not contain ${JSON.stringify(forbidden)}`;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (!PROJECT_NAME_RE.test(name)) {
|
|
40
|
+
return "must match /^[a-z][a-z0-9_-]*$/i (npm-package-name rules: start with a letter, then letters / digits / `-` / `_`)";
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export async function createProject(projectName, _options) {
|
|
46
|
+
const isCurrentDirectory = _options.currentDir;
|
|
47
|
+
|
|
48
|
+
// F17: name validation. Skipped when `--current-dir` because that
|
|
49
|
+
// path uses cwd, not the name, and is purely a display string then.
|
|
50
|
+
if (!isCurrentDirectory) {
|
|
51
|
+
const reason = validateProjectName(projectName);
|
|
52
|
+
if (reason) {
|
|
53
|
+
console.error(chalk.red(`✗ Invalid project name "${projectName}": ${reason}`));
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const projectPath = isCurrentDirectory ? process.cwd() : path.resolve(process.cwd(), projectName);
|
|
59
|
+
const displayName = isCurrentDirectory ? "current directory" : projectName;
|
|
60
|
+
|
|
61
|
+
console.log(chalk.blue(`🚀 Creating ShipAPI project: ${projectName}`));
|
|
62
|
+
if (isCurrentDirectory) {
|
|
63
|
+
console.log(chalk.blue(`📁 Installing in current directory`));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Check if directory already exists (only for new directories)
|
|
67
|
+
if (!isCurrentDirectory) {
|
|
68
|
+
try {
|
|
69
|
+
await fs.access(projectPath);
|
|
70
|
+
throw new Error(`Directory ${projectName} already exists`);
|
|
71
|
+
} catch (_error) {
|
|
72
|
+
if (_error.code !== "ENOENT") {
|
|
73
|
+
throw _error;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Create project directory
|
|
78
|
+
await fs.mkdir(projectPath, { recursive: true });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Copy template files
|
|
82
|
+
await copyTemplate(projectPath, _options.template);
|
|
83
|
+
|
|
84
|
+
// Process template placeholders
|
|
85
|
+
await processTemplateFiles(projectPath, projectName);
|
|
86
|
+
|
|
87
|
+
// Install dependencies
|
|
88
|
+
if (!_options.skipInstall) {
|
|
89
|
+
console.log(chalk.yellow("📦 Installing dependencies..."));
|
|
90
|
+
process.chdir(projectPath);
|
|
91
|
+
execSync("npm install", { stdio: "inherit" });
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Initialize git
|
|
95
|
+
if (!_options.skipGit) {
|
|
96
|
+
console.log(chalk.yellow("🔧 Initializing git repository..."));
|
|
97
|
+
try {
|
|
98
|
+
execSync("git init", { stdio: "inherit" });
|
|
99
|
+
execSync("git add .", { stdio: "inherit" });
|
|
100
|
+
execSync('git commit -m "Initial commit: ShipAPI project setup"', { stdio: "inherit" });
|
|
101
|
+
} catch (_error) {
|
|
102
|
+
console.log(chalk.yellow("⚠️ Git initialization failed, continuing..."));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
console.log(chalk.green(`✅ Project "${projectName}" created successfully in ${displayName}!`));
|
|
107
|
+
console.log(chalk.cyan(`\nNext steps:`));
|
|
108
|
+
if (!isCurrentDirectory) {
|
|
109
|
+
console.log(chalk.cyan(` cd ${projectName}`));
|
|
110
|
+
}
|
|
111
|
+
console.log(chalk.cyan(` npx ship-api add accounts # Add authentication module`));
|
|
112
|
+
console.log(chalk.cyan(` npm run local`));
|
|
113
|
+
console.log(chalk.cyan(`\nDocumentation: https://github.com/SixthSummit/Ship`));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async function copyTemplate(projectPath, template) {
|
|
117
|
+
const templatePath = path.join(__dirname, "..", "..", "templates", template);
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
await fs.access(templatePath);
|
|
121
|
+
} catch (_error) {
|
|
122
|
+
throw new Error(`Template '${template}' not found`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
await copyDirectory(templatePath, projectPath);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async function copyDirectory(src, dest) {
|
|
129
|
+
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
130
|
+
|
|
131
|
+
for (const entry of entries) {
|
|
132
|
+
const srcPath = path.join(src, entry.name);
|
|
133
|
+
// npm strips .gitignore (and other dot-leading ignore files) during
|
|
134
|
+
// package publish — templates work around it by shipping
|
|
135
|
+
// `_gitignore` and renaming on scaffold. Same trick as
|
|
136
|
+
// `create-next-app` and friends. Generalized to `_<name>` → `.<name>`
|
|
137
|
+
// so future ignore-style files (`.npmignore`, `.dockerignore`, etc.)
|
|
138
|
+
// can use the same convention.
|
|
139
|
+
const destName = entry.name.startsWith("_") ? "." + entry.name.slice(1) : entry.name;
|
|
140
|
+
const destPath = path.join(dest, destName);
|
|
141
|
+
|
|
142
|
+
if (entry.isDirectory()) {
|
|
143
|
+
await fs.mkdir(destPath, { recursive: true });
|
|
144
|
+
await copyDirectory(srcPath, destPath);
|
|
145
|
+
} else {
|
|
146
|
+
await fs.copyFile(srcPath, destPath);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function processTemplateFiles(projectPath, projectName) {
|
|
152
|
+
// Determine ship-api version to use
|
|
153
|
+
const shipApiVersion = await getShipApiVersion();
|
|
154
|
+
const observabilityVersion = await getBundledDependencyVersion(
|
|
155
|
+
"@sixthsummit/ship-observability-otel",
|
|
156
|
+
"observability-otel",
|
|
157
|
+
);
|
|
158
|
+
console.log(chalk.blue(`📦 Using @sixthsummit/ship-api version: ${shipApiVersion}`));
|
|
159
|
+
|
|
160
|
+
// Process package.json - parse as JSON and update fields
|
|
161
|
+
const packageJsonPath = path.join(projectPath, "package.json");
|
|
162
|
+
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf8"));
|
|
163
|
+
|
|
164
|
+
packageJson.name = projectName;
|
|
165
|
+
|
|
166
|
+
// Insert @sixthsummit/ship-api at the beginning of dependencies, with
|
|
167
|
+
// the version resolved by getShipApiVersion(). Templates SHOULD NOT
|
|
168
|
+
// declare @sixthsummit/ship-api themselves — but defensively strip it
|
|
169
|
+
// from existingDeps before the spread so the explicit version wins
|
|
170
|
+
// (otherwise the template's stale literal overrides via property-key
|
|
171
|
+
// collision).
|
|
172
|
+
const {
|
|
173
|
+
"@sixthsummit/ship-api": _existingShipApi,
|
|
174
|
+
"@sixthsummit/ship-observability-otel": _existingObservability,
|
|
175
|
+
...existingDeps
|
|
176
|
+
} = packageJson.dependencies ?? {};
|
|
177
|
+
packageJson.dependencies = {
|
|
178
|
+
"@sixthsummit/ship-api": shipApiVersion,
|
|
179
|
+
"@sixthsummit/ship-observability-otel": observabilityVersion,
|
|
180
|
+
...existingDeps,
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n");
|
|
184
|
+
|
|
185
|
+
// Process .env.example - update PROJECT_ROOT
|
|
186
|
+
const envExamplePath = path.join(projectPath, ".env.example");
|
|
187
|
+
try {
|
|
188
|
+
let envExample = await fs.readFile(envExamplePath, "utf8");
|
|
189
|
+
envExample = envExample.replace(/PROJECT_ROOT=.*/, `PROJECT_ROOT=${projectPath}`);
|
|
190
|
+
envExample = envExample.replace(
|
|
191
|
+
/DATABASE_URL=postgresql:\/\/username:password@localhost:5432\/.*/,
|
|
192
|
+
`DATABASE_URL=postgresql://username:password@localhost:5432/${projectName}`,
|
|
193
|
+
);
|
|
194
|
+
await fs.writeFile(envExamplePath, envExample);
|
|
195
|
+
} catch (_error) {
|
|
196
|
+
// .env.example might not exist, that's okay
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
async function getShipApiVersion() {
|
|
201
|
+
// Read ship-api's package.json to get current version
|
|
202
|
+
const shipApiPackageJsonPath = path.join(__dirname, "..", "..", "package.json");
|
|
203
|
+
const shipApiPackageJson = JSON.parse(await fs.readFile(shipApiPackageJsonPath, "utf8"));
|
|
204
|
+
const currentVersion = shipApiPackageJson.version;
|
|
205
|
+
const isPrerelease = currentVersion.includes("-"); // e.g., 3.0.0-beta.1
|
|
206
|
+
|
|
207
|
+
if (isPrerelease) {
|
|
208
|
+
// For prereleases (beta, rc), use caret range to allow updates to newer betas and stable
|
|
209
|
+
// ^3.0.0-beta.1 will match 3.0.0-beta.2, 3.0.0, 3.0.1, etc.
|
|
210
|
+
return `^${currentVersion}`;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// For stable releases, try to get the latest stable version from npm
|
|
214
|
+
try {
|
|
215
|
+
const latestVersion = execSync("npm view @sixthsummit/ship-api version", {
|
|
216
|
+
encoding: "utf8",
|
|
217
|
+
}).trim();
|
|
218
|
+
return `^${latestVersion}`;
|
|
219
|
+
} catch (_error) {
|
|
220
|
+
// If npm view fails, use current version
|
|
221
|
+
return `^${currentVersion}`;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Resolve a package split out of the monolith to the version declared by the
|
|
227
|
+
* installed CLI. Published package manifests contain a normal semver range;
|
|
228
|
+
* the workspace fallback keeps local scaffold tests deterministic.
|
|
229
|
+
*/
|
|
230
|
+
export async function getBundledDependencyVersion(packageName, workspaceDirectory) {
|
|
231
|
+
const shipApiPackageJsonPath = path.join(__dirname, "..", "..", "package.json");
|
|
232
|
+
const shipApiPackageJson = JSON.parse(await fs.readFile(shipApiPackageJsonPath, "utf8"));
|
|
233
|
+
const declared = shipApiPackageJson.dependencies?.[packageName];
|
|
234
|
+
|
|
235
|
+
if (typeof declared !== "string") {
|
|
236
|
+
throw new Error(`${packageName} is not declared by @sixthsummit/ship-api`);
|
|
237
|
+
}
|
|
238
|
+
if (!declared.startsWith("workspace:")) return declared;
|
|
239
|
+
|
|
240
|
+
const workspacePackageJsonPath = path.join(
|
|
241
|
+
__dirname,
|
|
242
|
+
"..",
|
|
243
|
+
"..",
|
|
244
|
+
"..",
|
|
245
|
+
workspaceDirectory,
|
|
246
|
+
"package.json",
|
|
247
|
+
);
|
|
248
|
+
const workspacePackageJson = JSON.parse(await fs.readFile(workspacePackageJsonPath, "utf8"));
|
|
249
|
+
return `^${workspacePackageJson.version}`;
|
|
250
|
+
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { spawn } from "child_process";
|
|
3
|
+
import fs from "fs/promises";
|
|
4
|
+
import path from "path";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `ship-api dev` — local-stack orchestrator.
|
|
8
|
+
*
|
|
9
|
+
* Brings up the dependency containers (Postgres, Redis, optional OTel
|
|
10
|
+
* collector) via Docker Compose, then runs the project's dev script with
|
|
11
|
+
* hot reload, then polls a health endpoint until it goes green and prints
|
|
12
|
+
* the URL — the "new project just works" experience.
|
|
13
|
+
*
|
|
14
|
+
* --bare Skip Docker. Use this when Postgres/Redis are already running
|
|
15
|
+
* on the host (or you're shelling into a remote stack).
|
|
16
|
+
* --reset `docker compose down -v` before starting — drops volumes for
|
|
17
|
+
* a clean slate (and forces fresh migrations on next boot).
|
|
18
|
+
* --port Override the polled port (defaults to 3000 / $PORT).
|
|
19
|
+
*
|
|
20
|
+
* Implementation notes:
|
|
21
|
+
*
|
|
22
|
+
* • Compose file discovery: looks for `compose.yml`, `compose.yaml`,
|
|
23
|
+
* `docker-compose.yml`, `docker-compose.yaml` in cwd. If none, behaves
|
|
24
|
+
* as `--bare`.
|
|
25
|
+
* • Service selection: spins up *only* dependency services (`postgres`,
|
|
26
|
+
* `redis`, `jaeger`, `otel-collector`) — never the `api` service,
|
|
27
|
+
* since the point of `dev` is to run the app via `tsx watch` for
|
|
28
|
+
* hot reload. (`jaeger` is the v4 template's trace viewer; the
|
|
29
|
+
* legacy `otel-collector` name is kept for v3 / older v4 templates
|
|
30
|
+
* that haven't been updated.)
|
|
31
|
+
* • Health probe: tries `/livez`, then `/healthz`, then `/health-check`,
|
|
32
|
+
* then `/`. First non-5xx response wins. Polls every 500ms with a 60s
|
|
33
|
+
* timeout.
|
|
34
|
+
* • Signal handling: forwards SIGINT/SIGTERM to the npm child. Compose
|
|
35
|
+
* stays running so the next `dev` invocation reuses warm containers
|
|
36
|
+
* (use `--reset` to tear down explicitly).
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
const DEPENDENCY_SERVICES = ["postgres", "redis", "jaeger", "otel-collector"];
|
|
40
|
+
const HEALTH_PATHS = ["/livez", "/healthz", "/health-check", "/"];
|
|
41
|
+
const HEALTH_TIMEOUT_MS = 60_000;
|
|
42
|
+
const HEALTH_INTERVAL_MS = 500;
|
|
43
|
+
|
|
44
|
+
export async function devCommand(options = {}) {
|
|
45
|
+
const cwd = process.cwd();
|
|
46
|
+
const port = Number(options.port ?? process.env.PORT ?? 3000);
|
|
47
|
+
const useDocker = !options.bare;
|
|
48
|
+
const reset = Boolean(options.reset);
|
|
49
|
+
|
|
50
|
+
console.log(chalk.blue("🚀 ship-api dev"));
|
|
51
|
+
|
|
52
|
+
let composeFile = null;
|
|
53
|
+
if (useDocker) {
|
|
54
|
+
composeFile = await findComposeFile(cwd);
|
|
55
|
+
if (!composeFile) {
|
|
56
|
+
console.log(
|
|
57
|
+
chalk.yellow(
|
|
58
|
+
"⚠ no docker-compose.yml found — running in --bare mode (assumes Postgres/Redis are already up)",
|
|
59
|
+
),
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (composeFile && reset) {
|
|
65
|
+
console.log(chalk.gray(`↻ docker compose down -v (${composeFile})`));
|
|
66
|
+
await runToCompletion("docker", ["compose", "-f", composeFile, "down", "-v"], { cwd });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (composeFile) {
|
|
70
|
+
const services = await selectExistingServices(composeFile, cwd, DEPENDENCY_SERVICES);
|
|
71
|
+
if (services.length === 0) {
|
|
72
|
+
console.log(
|
|
73
|
+
chalk.yellow(
|
|
74
|
+
`⚠ ${composeFile} has no services matching ${DEPENDENCY_SERVICES.join(", ")} — skipping compose up`,
|
|
75
|
+
),
|
|
76
|
+
);
|
|
77
|
+
} else {
|
|
78
|
+
console.log(chalk.gray(`↑ docker compose up -d ${services.join(" ")}`));
|
|
79
|
+
const composeUp = await runToCompletion(
|
|
80
|
+
"docker",
|
|
81
|
+
["compose", "-f", composeFile, "up", "-d", ...services],
|
|
82
|
+
{ cwd },
|
|
83
|
+
);
|
|
84
|
+
if (composeUp.code !== 0) {
|
|
85
|
+
throw new Error(`docker compose up failed (exit ${composeUp.code})`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Pick the dev script. Templates expose `local` (v3) or `dev` (v4).
|
|
91
|
+
const devScript = await pickDevScript(cwd);
|
|
92
|
+
console.log(chalk.gray(`▶ npm run ${devScript}`));
|
|
93
|
+
|
|
94
|
+
const npmChild = spawn("npm", ["run", devScript], {
|
|
95
|
+
cwd,
|
|
96
|
+
stdio: "inherit",
|
|
97
|
+
env: process.env,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
let cleanedUp = false;
|
|
101
|
+
const cleanup = (signal) => {
|
|
102
|
+
if (cleanedUp) return;
|
|
103
|
+
cleanedUp = true;
|
|
104
|
+
if (!npmChild.killed) npmChild.kill(signal);
|
|
105
|
+
};
|
|
106
|
+
process.on("SIGINT", () => cleanup("SIGINT"));
|
|
107
|
+
process.on("SIGTERM", () => cleanup("SIGTERM"));
|
|
108
|
+
|
|
109
|
+
const childExit = new Promise((resolve) => {
|
|
110
|
+
npmChild.once("exit", (code, signal) => resolve({ code, signal }));
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Race the health probe vs. an early child exit.
|
|
114
|
+
const healthResult = await Promise.race([
|
|
115
|
+
pollHealth(`http://localhost:${port}`),
|
|
116
|
+
childExit.then((r) => ({ kind: "child-exited", ...r })),
|
|
117
|
+
]);
|
|
118
|
+
|
|
119
|
+
if (healthResult.kind === "child-exited") {
|
|
120
|
+
throw new Error(
|
|
121
|
+
`dev process exited before becoming healthy (code=${healthResult.code} signal=${healthResult.signal})`,
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
if (!healthResult.ok) {
|
|
125
|
+
console.log(
|
|
126
|
+
chalk.yellow(
|
|
127
|
+
`⚠ ${healthResult.reason}. The server may still be starting — try opening http://localhost:${port} in a moment.`,
|
|
128
|
+
),
|
|
129
|
+
);
|
|
130
|
+
} else {
|
|
131
|
+
console.log(
|
|
132
|
+
chalk.green(
|
|
133
|
+
`✓ healthy at http://localhost:${port}${healthResult.path} — opening in your browser`,
|
|
134
|
+
),
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Stay attached to the npm child so logs flow until Ctrl+C.
|
|
139
|
+
const { code } = await childExit;
|
|
140
|
+
if (code !== 0 && code !== null) {
|
|
141
|
+
process.exitCode = code;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Exported for tests. Internal helpers used by `devCommand`.
|
|
146
|
+
export const __test = {
|
|
147
|
+
findComposeFile: (...args) => findComposeFile(...args),
|
|
148
|
+
selectExistingServices: (...args) => selectExistingServices(...args),
|
|
149
|
+
pickDevScript: (...args) => pickDevScript(...args),
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
async function findComposeFile(cwd) {
|
|
153
|
+
const candidates = ["compose.yml", "compose.yaml", "docker-compose.yml", "docker-compose.yaml"];
|
|
154
|
+
for (const name of candidates) {
|
|
155
|
+
const full = path.join(cwd, name);
|
|
156
|
+
try {
|
|
157
|
+
await fs.access(full);
|
|
158
|
+
return name;
|
|
159
|
+
} catch {
|
|
160
|
+
// try next
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async function selectExistingServices(composeFile, cwd, candidates) {
|
|
167
|
+
// Cheap parse — read the file and look for top-level service keys via
|
|
168
|
+
// the indent-aware regex `\n <name>:`. Avoids a YAML dep for a CLI tool.
|
|
169
|
+
const text = await fs.readFile(path.join(cwd, composeFile), "utf8");
|
|
170
|
+
const out = [];
|
|
171
|
+
for (const name of candidates) {
|
|
172
|
+
const re = new RegExp(`(?:^|\\n) ${escapeRegex(name)}:`, "m");
|
|
173
|
+
if (re.test(text)) out.push(name);
|
|
174
|
+
}
|
|
175
|
+
return out;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async function pickDevScript(cwd) {
|
|
179
|
+
const pkgPath = path.join(cwd, "package.json");
|
|
180
|
+
try {
|
|
181
|
+
const pkg = JSON.parse(await fs.readFile(pkgPath, "utf8"));
|
|
182
|
+
const scripts = pkg.scripts ?? {};
|
|
183
|
+
if (scripts.dev) return "dev";
|
|
184
|
+
if (scripts.local) return "local";
|
|
185
|
+
if (scripts.start) return "start";
|
|
186
|
+
} catch {
|
|
187
|
+
// fall through
|
|
188
|
+
}
|
|
189
|
+
return "local";
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
async function pollHealth(baseUrl) {
|
|
193
|
+
const deadline = Date.now() + HEALTH_TIMEOUT_MS;
|
|
194
|
+
while (Date.now() < deadline) {
|
|
195
|
+
for (const p of HEALTH_PATHS) {
|
|
196
|
+
try {
|
|
197
|
+
const res = await fetch(`${baseUrl}${p}`, {
|
|
198
|
+
// Treat any 2xx/3xx/4xx as "the server is reachable enough".
|
|
199
|
+
// 5xx (or no response) keeps polling.
|
|
200
|
+
});
|
|
201
|
+
if (res.status < 500) {
|
|
202
|
+
return { kind: "healthy", ok: true, path: p, status: res.status };
|
|
203
|
+
}
|
|
204
|
+
} catch {
|
|
205
|
+
// connection refused / DNS / network — still booting
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
await new Promise((r) => setTimeout(r, HEALTH_INTERVAL_MS));
|
|
209
|
+
}
|
|
210
|
+
return {
|
|
211
|
+
kind: "healthy",
|
|
212
|
+
ok: false,
|
|
213
|
+
reason: `no health endpoint became reachable within ${HEALTH_TIMEOUT_MS / 1000}s`,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function runToCompletion(command, args, opts) {
|
|
218
|
+
return new Promise((resolve, reject) => {
|
|
219
|
+
const child = spawn(command, args, { ...opts, stdio: "inherit" });
|
|
220
|
+
child.once("error", reject);
|
|
221
|
+
child.once("exit", (code, signal) => resolve({ code, signal }));
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function escapeRegex(s) {
|
|
226
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
227
|
+
}
|