@digimuza/saas-core 0.0.2
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/CLAUDE.md +1165 -0
- package/LICENSE +21 -0
- package/README.md +234 -0
- package/dist/api-keys/index.d.ts +9 -0
- package/dist/api-keys/index.d.ts.map +1 -0
- package/dist/api-keys/index.js +37 -0
- package/dist/api-keys/index.js.map +1 -0
- package/dist/api-keys/keys.d.ts +55 -0
- package/dist/api-keys/keys.d.ts.map +1 -0
- package/dist/api-keys/keys.js +92 -0
- package/dist/api-keys/keys.js.map +1 -0
- package/dist/api-keys/service.d.ts +111 -0
- package/dist/api-keys/service.d.ts.map +1 -0
- package/dist/api-keys/service.js +210 -0
- package/dist/api-keys/service.js.map +1 -0
- package/dist/audit/index.d.ts +5 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +44 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/service.d.ts +88 -0
- package/dist/audit/service.d.ts.map +1 -0
- package/dist/audit/service.js +128 -0
- package/dist/audit/service.js.map +1 -0
- package/dist/auth/client.d.ts +5 -0
- package/dist/auth/client.d.ts.map +1 -0
- package/dist/auth/client.js +26 -0
- package/dist/auth/client.js.map +1 -0
- package/dist/auth/cookies.d.ts +51 -0
- package/dist/auth/cookies.d.ts.map +1 -0
- package/dist/auth/cookies.js +58 -0
- package/dist/auth/cookies.js.map +1 -0
- package/dist/auth/index.d.ts +14 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +46 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/service.d.ts +67 -0
- package/dist/auth/service.d.ts.map +1 -0
- package/dist/auth/service.js +275 -0
- package/dist/auth/service.js.map +1 -0
- package/dist/auth/types.d.ts +56 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +2 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/authorization/index.d.ts +4 -0
- package/dist/authorization/index.d.ts.map +1 -0
- package/dist/authorization/index.js +24 -0
- package/dist/authorization/index.js.map +1 -0
- package/dist/authorization/service.d.ts +92 -0
- package/dist/authorization/service.d.ts.map +1 -0
- package/dist/authorization/service.js +254 -0
- package/dist/authorization/service.js.map +1 -0
- package/dist/billing/index.d.ts +16 -0
- package/dist/billing/index.d.ts.map +1 -0
- package/dist/billing/index.js +47 -0
- package/dist/billing/index.js.map +1 -0
- package/dist/billing/provider.d.ts +114 -0
- package/dist/billing/provider.d.ts.map +1 -0
- package/dist/billing/provider.js +2 -0
- package/dist/billing/provider.js.map +1 -0
- package/dist/billing/revolut.d.ts +68 -0
- package/dist/billing/revolut.d.ts.map +1 -0
- package/dist/billing/revolut.js +181 -0
- package/dist/billing/revolut.js.map +1 -0
- package/dist/billing/service.d.ts +124 -0
- package/dist/billing/service.d.ts.map +1 -0
- package/dist/billing/service.js +470 -0
- package/dist/billing/service.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +43 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +212 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/project.d.ts +12 -0
- package/dist/cli/commands/project.d.ts.map +1 -0
- package/dist/cli/commands/project.js +49 -0
- package/dist/cli/commands/project.js.map +1 -0
- package/dist/cli/docker.d.ts +50 -0
- package/dist/cli/docker.d.ts.map +1 -0
- package/dist/cli/docker.js +84 -0
- package/dist/cli/docker.js.map +1 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +198 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/output.d.ts +30 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +66 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/templates.d.ts +52 -0
- package/dist/cli/templates.d.ts.map +1 -0
- package/dist/cli/templates.js +225 -0
- package/dist/cli/templates.js.map +1 -0
- package/dist/config/client.d.ts +60 -0
- package/dist/config/client.d.ts.map +1 -0
- package/dist/config/client.js +94 -0
- package/dist/config/client.js.map +1 -0
- package/dist/config/config-loader.d.ts +2 -0
- package/dist/config/config-loader.d.ts.map +1 -0
- package/dist/config/config-loader.js +2 -0
- package/dist/config/config-loader.js.map +1 -0
- package/dist/config/env.d.ts +24 -0
- package/dist/config/env.d.ts.map +1 -0
- package/dist/config/env.js +40 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/errors.d.ts +17 -0
- package/dist/config/errors.d.ts.map +1 -0
- package/dist/config/errors.js +26 -0
- package/dist/config/errors.js.map +1 -0
- package/dist/config/index.d.ts +72 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +106 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/runtime.d.ts +15 -0
- package/dist/config/runtime.d.ts.map +1 -0
- package/dist/config/runtime.js +22 -0
- package/dist/config/runtime.js.map +1 -0
- package/dist/config/sections.d.ts +226 -0
- package/dist/config/sections.d.ts.map +1 -0
- package/dist/config/sections.js +141 -0
- package/dist/config/sections.js.map +1 -0
- package/dist/db/client.d.ts +43 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +77 -0
- package/dist/db/client.js.map +1 -0
- package/dist/db/errors.d.ts +39 -0
- package/dist/db/errors.d.ts.map +1 -0
- package/dist/db/errors.js +67 -0
- package/dist/db/errors.js.map +1 -0
- package/dist/db/index.d.ts +10 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +10 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/migrate.d.ts +21 -0
- package/dist/db/migrate.d.ts.map +1 -0
- package/dist/db/migrate.js +28 -0
- package/dist/db/migrate.js.map +1 -0
- package/dist/db/schema/_shared.d.ts +30 -0
- package/dist/db/schema/_shared.d.ts.map +1 -0
- package/dist/db/schema/_shared.js +36 -0
- package/dist/db/schema/_shared.js.map +1 -0
- package/dist/db/schema/apikeys.d.ts +263 -0
- package/dist/db/schema/apikeys.d.ts.map +1 -0
- package/dist/db/schema/apikeys.js +70 -0
- package/dist/db/schema/apikeys.js.map +1 -0
- package/dist/db/schema/authorization.d.ts +465 -0
- package/dist/db/schema/authorization.d.ts.map +1 -0
- package/dist/db/schema/authorization.js +134 -0
- package/dist/db/schema/authorization.js.map +1 -0
- package/dist/db/schema/billing.d.ts +1100 -0
- package/dist/db/schema/billing.d.ts.map +1 -0
- package/dist/db/schema/billing.js +223 -0
- package/dist/db/schema/billing.js.map +1 -0
- package/dist/db/schema/events.d.ts +161 -0
- package/dist/db/schema/events.d.ts.map +1 -0
- package/dist/db/schema/events.js +66 -0
- package/dist/db/schema/events.js.map +1 -0
- package/dist/db/schema/features.d.ts +243 -0
- package/dist/db/schema/features.d.ts.map +1 -0
- package/dist/db/schema/features.js +87 -0
- package/dist/db/schema/features.js.map +1 -0
- package/dist/db/schema/files.d.ts +253 -0
- package/dist/db/schema/files.d.ts.map +1 -0
- package/dist/db/schema/files.js +74 -0
- package/dist/db/schema/files.js.map +1 -0
- package/dist/db/schema/index.d.ts +38 -0
- package/dist/db/schema/index.d.ts.map +1 -0
- package/dist/db/schema/index.js +38 -0
- package/dist/db/schema/index.js.map +1 -0
- package/dist/db/schema/invitations.d.ts +214 -0
- package/dist/db/schema/invitations.d.ts.map +1 -0
- package/dist/db/schema/invitations.js +80 -0
- package/dist/db/schema/invitations.js.map +1 -0
- package/dist/db/schema/messaging.d.ts +442 -0
- package/dist/db/schema/messaging.d.ts.map +1 -0
- package/dist/db/schema/messaging.js +120 -0
- package/dist/db/schema/messaging.js.map +1 -0
- package/dist/db/schema/users.d.ts +246 -0
- package/dist/db/schema/users.d.ts.map +1 -0
- package/dist/db/schema/users.js +60 -0
- package/dist/db/schema/users.js.map +1 -0
- package/dist/db/schema/webhooks.d.ts +693 -0
- package/dist/db/schema/webhooks.d.ts.map +1 -0
- package/dist/db/schema/webhooks.js +147 -0
- package/dist/db/schema/webhooks.js.map +1 -0
- package/dist/db/schema/workspaces.d.ts +196 -0
- package/dist/db/schema/workspaces.d.ts.map +1 -0
- package/dist/db/schema/workspaces.js +57 -0
- package/dist/db/schema/workspaces.js.map +1 -0
- package/dist/db/types.d.ts +18 -0
- package/dist/db/types.d.ts.map +1 -0
- package/dist/db/types.js +2 -0
- package/dist/db/types.js.map +1 -0
- package/dist/email/adapters.d.ts +29 -0
- package/dist/email/adapters.d.ts.map +1 -0
- package/dist/email/adapters.js +60 -0
- package/dist/email/adapters.js.map +1 -0
- package/dist/email/index.d.ts +20 -0
- package/dist/email/index.d.ts.map +1 -0
- package/dist/email/index.js +79 -0
- package/dist/email/index.js.map +1 -0
- package/dist/email/provider.d.ts +47 -0
- package/dist/email/provider.d.ts.map +1 -0
- package/dist/email/provider.js +7 -0
- package/dist/email/provider.js.map +1 -0
- package/dist/email/resend.d.ts +22 -0
- package/dist/email/resend.d.ts.map +1 -0
- package/dist/email/resend.js +51 -0
- package/dist/email/resend.js.map +1 -0
- package/dist/email/service.d.ts +55 -0
- package/dist/email/service.d.ts.map +1 -0
- package/dist/email/service.js +87 -0
- package/dist/email/service.js.map +1 -0
- package/dist/email/templates.d.ts +81 -0
- package/dist/email/templates.d.ts.map +1 -0
- package/dist/email/templates.js +84 -0
- package/dist/email/templates.js.map +1 -0
- package/dist/entitlements/index.d.ts +10 -0
- package/dist/entitlements/index.d.ts.map +1 -0
- package/dist/entitlements/index.js +28 -0
- package/dist/entitlements/index.js.map +1 -0
- package/dist/entitlements/service.d.ts +83 -0
- package/dist/entitlements/service.d.ts.map +1 -0
- package/dist/entitlements/service.js +158 -0
- package/dist/entitlements/service.js.map +1 -0
- package/dist/errors.d.ts +85 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +95 -0
- package/dist/errors.js.map +1 -0
- package/dist/events/core-events.d.ts +120 -0
- package/dist/events/core-events.d.ts.map +1 -0
- package/dist/events/core-events.js +109 -0
- package/dist/events/core-events.js.map +1 -0
- package/dist/events/index.d.ts +15 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +58 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/publisher.d.ts +46 -0
- package/dist/events/publisher.d.ts.map +1 -0
- package/dist/events/publisher.js +54 -0
- package/dist/events/publisher.js.map +1 -0
- package/dist/events/registry.d.ts +87 -0
- package/dist/events/registry.d.ts.map +1 -0
- package/dist/events/registry.js +34 -0
- package/dist/events/registry.js.map +1 -0
- package/dist/events/service.d.ts +78 -0
- package/dist/events/service.d.ts.map +1 -0
- package/dist/events/service.js +182 -0
- package/dist/events/service.js.map +1 -0
- package/dist/features/bucket.d.ts +22 -0
- package/dist/features/bucket.d.ts.map +1 -0
- package/dist/features/bucket.js +42 -0
- package/dist/features/bucket.js.map +1 -0
- package/dist/features/index.d.ts +15 -0
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/index.js +78 -0
- package/dist/features/index.js.map +1 -0
- package/dist/features/registry.d.ts +51 -0
- package/dist/features/registry.d.ts.map +1 -0
- package/dist/features/registry.js +52 -0
- package/dist/features/registry.js.map +1 -0
- package/dist/features/service.d.ts +78 -0
- package/dist/features/service.d.ts.map +1 -0
- package/dist/features/service.js +207 -0
- package/dist/features/service.js.map +1 -0
- package/dist/files/index.d.ts +6 -0
- package/dist/files/index.d.ts.map +1 -0
- package/dist/files/index.js +64 -0
- package/dist/files/index.js.map +1 -0
- package/dist/files/service.d.ts +92 -0
- package/dist/files/service.d.ts.map +1 -0
- package/dist/files/service.js +303 -0
- package/dist/files/service.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/jobs/backend.d.ts +23 -0
- package/dist/jobs/backend.d.ts.map +1 -0
- package/dist/jobs/backend.js +23 -0
- package/dist/jobs/backend.js.map +1 -0
- package/dist/jobs/index.d.ts +29 -0
- package/dist/jobs/index.d.ts.map +1 -0
- package/dist/jobs/index.js +114 -0
- package/dist/jobs/index.js.map +1 -0
- package/dist/jobs/service.d.ts +67 -0
- package/dist/jobs/service.d.ts.map +1 -0
- package/dist/jobs/service.js +139 -0
- package/dist/jobs/service.js.map +1 -0
- package/dist/jobs/types.d.ts +78 -0
- package/dist/jobs/types.d.ts.map +1 -0
- package/dist/jobs/types.js +4 -0
- package/dist/jobs/types.js.map +1 -0
- package/dist/logger/default.d.ts +7 -0
- package/dist/logger/default.d.ts.map +1 -0
- package/dist/logger/default.js +28 -0
- package/dist/logger/default.js.map +1 -0
- package/dist/logger/index.d.ts +24 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +90 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/logger/redact.d.ts +40 -0
- package/dist/logger/redact.d.ts.map +1 -0
- package/dist/logger/redact.js +178 -0
- package/dist/logger/redact.js.map +1 -0
- package/dist/logger/service.d.ts +14 -0
- package/dist/logger/service.d.ts.map +1 -0
- package/dist/logger/service.js +56 -0
- package/dist/logger/service.js.map +1 -0
- package/dist/logger/sinks.d.ts +37 -0
- package/dist/logger/sinks.d.ts.map +1 -0
- package/dist/logger/sinks.js +135 -0
- package/dist/logger/sinks.js.map +1 -0
- package/dist/logger/types.d.ts +47 -0
- package/dist/logger/types.d.ts.map +1 -0
- package/dist/logger/types.js +8 -0
- package/dist/logger/types.js.map +1 -0
- package/dist/notifications/index.d.ts +8 -0
- package/dist/notifications/index.d.ts.map +1 -0
- package/dist/notifications/index.js +72 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/notifications/service.d.ts +79 -0
- package/dist/notifications/service.d.ts.map +1 -0
- package/dist/notifications/service.js +164 -0
- package/dist/notifications/service.js.map +1 -0
- package/dist/realtime/channels.d.ts +37 -0
- package/dist/realtime/channels.d.ts.map +1 -0
- package/dist/realtime/channels.js +58 -0
- package/dist/realtime/channels.js.map +1 -0
- package/dist/realtime/index.d.ts +19 -0
- package/dist/realtime/index.d.ts.map +1 -0
- package/dist/realtime/index.js +118 -0
- package/dist/realtime/index.js.map +1 -0
- package/dist/realtime/postgres.d.ts +48 -0
- package/dist/realtime/postgres.d.ts.map +1 -0
- package/dist/realtime/postgres.js +151 -0
- package/dist/realtime/postgres.js.map +1 -0
- package/dist/realtime/service.d.ts +75 -0
- package/dist/realtime/service.d.ts.map +1 -0
- package/dist/realtime/service.js +103 -0
- package/dist/realtime/service.js.map +1 -0
- package/dist/realtime/sse.d.ts +55 -0
- package/dist/realtime/sse.d.ts.map +1 -0
- package/dist/realtime/sse.js +123 -0
- package/dist/realtime/sse.js.map +1 -0
- package/dist/realtime/transport.d.ts +52 -0
- package/dist/realtime/transport.d.ts.map +1 -0
- package/dist/realtime/transport.js +2 -0
- package/dist/realtime/transport.js.map +1 -0
- package/dist/storage/index.d.ts +18 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +89 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/keys.d.ts +50 -0
- package/dist/storage/keys.d.ts.map +1 -0
- package/dist/storage/keys.js +120 -0
- package/dist/storage/keys.js.map +1 -0
- package/dist/storage/memory.d.ts +32 -0
- package/dist/storage/memory.d.ts.map +1 -0
- package/dist/storage/memory.js +84 -0
- package/dist/storage/memory.js.map +1 -0
- package/dist/storage/provider.d.ts +93 -0
- package/dist/storage/provider.d.ts.map +1 -0
- package/dist/storage/provider.js +2 -0
- package/dist/storage/provider.js.map +1 -0
- package/dist/storage/s3.d.ts +34 -0
- package/dist/storage/s3.d.ts.map +1 -0
- package/dist/storage/s3.js +175 -0
- package/dist/storage/s3.js.map +1 -0
- package/dist/storage/service.d.ts +86 -0
- package/dist/storage/service.d.ts.map +1 -0
- package/dist/storage/service.js +107 -0
- package/dist/storage/service.js.map +1 -0
- package/dist/storage/sigv4.d.ts +58 -0
- package/dist/storage/sigv4.d.ts.map +1 -0
- package/dist/storage/sigv4.js +114 -0
- package/dist/storage/sigv4.js.map +1 -0
- package/dist/streams/client.d.ts +91 -0
- package/dist/streams/client.d.ts.map +1 -0
- package/dist/streams/client.js +128 -0
- package/dist/streams/client.js.map +1 -0
- package/dist/streams/events.d.ts +68 -0
- package/dist/streams/events.d.ts.map +1 -0
- package/dist/streams/events.js +81 -0
- package/dist/streams/events.js.map +1 -0
- package/dist/streams/index.d.ts +47 -0
- package/dist/streams/index.d.ts.map +1 -0
- package/dist/streams/index.js +47 -0
- package/dist/streams/index.js.map +1 -0
- package/dist/streams/realtime.d.ts +27 -0
- package/dist/streams/realtime.d.ts.map +1 -0
- package/dist/streams/realtime.js +50 -0
- package/dist/streams/realtime.js.map +1 -0
- package/dist/streams/state.d.ts +26 -0
- package/dist/streams/state.d.ts.map +1 -0
- package/dist/streams/state.js +34 -0
- package/dist/streams/state.js.map +1 -0
- package/dist/users/index.d.ts +9 -0
- package/dist/users/index.d.ts.map +1 -0
- package/dist/users/index.js +23 -0
- package/dist/users/index.js.map +1 -0
- package/dist/users/service.d.ts +43 -0
- package/dist/users/service.d.ts.map +1 -0
- package/dist/users/service.js +113 -0
- package/dist/users/service.js.map +1 -0
- package/dist/webhooks/inbound.d.ts +70 -0
- package/dist/webhooks/inbound.d.ts.map +1 -0
- package/dist/webhooks/inbound.js +146 -0
- package/dist/webhooks/inbound.js.map +1 -0
- package/dist/webhooks/index.d.ts +12 -0
- package/dist/webhooks/index.d.ts.map +1 -0
- package/dist/webhooks/index.js +65 -0
- package/dist/webhooks/index.js.map +1 -0
- package/dist/webhooks/outgoing.d.ts +89 -0
- package/dist/webhooks/outgoing.d.ts.map +1 -0
- package/dist/webhooks/outgoing.js +375 -0
- package/dist/webhooks/outgoing.js.map +1 -0
- package/dist/webhooks/signature.d.ts +40 -0
- package/dist/webhooks/signature.d.ts.map +1 -0
- package/dist/webhooks/signature.js +77 -0
- package/dist/webhooks/signature.js.map +1 -0
- package/dist/workspaces/context.d.ts +30 -0
- package/dist/workspaces/context.d.ts.map +1 -0
- package/dist/workspaces/context.js +12 -0
- package/dist/workspaces/context.js.map +1 -0
- package/dist/workspaces/index.d.ts +5 -0
- package/dist/workspaces/index.d.ts.map +1 -0
- package/dist/workspaces/index.js +21 -0
- package/dist/workspaces/index.js.map +1 -0
- package/dist/workspaces/service.d.ts +126 -0
- package/dist/workspaces/service.d.ts.map +1 -0
- package/dist/workspaces/service.js +495 -0
- package/dist/workspaces/service.js.map +1 -0
- package/docs/README.md +71 -0
- package/docs/api-keys.md +184 -0
- package/docs/audit.md +198 -0
- package/docs/auth.md +196 -0
- package/docs/authorization.md +225 -0
- package/docs/billing.md +293 -0
- package/docs/cli.md +238 -0
- package/docs/config.md +163 -0
- package/docs/db.md +219 -0
- package/docs/email.md +222 -0
- package/docs/entitlements.md +194 -0
- package/docs/errors.md +158 -0
- package/docs/events.md +279 -0
- package/docs/feature-flags.md +237 -0
- package/docs/files.md +229 -0
- package/docs/jobs.md +288 -0
- package/docs/logger.md +269 -0
- package/docs/notifications.md +179 -0
- package/docs/publishing.md +128 -0
- package/docs/realtime.md +360 -0
- package/docs/storage.md +279 -0
- package/docs/streams.md +296 -0
- package/docs/users.md +117 -0
- package/docs/webhooks.md +272 -0
- package/docs/workspaces.md +269 -0
- package/drizzle/0000_init_users.sql +21 -0
- package/drizzle/0001_workspaces_roles_permissions.sql +86 -0
- package/drizzle/0002_billing_entitlements.sql +97 -0
- package/drizzle/0003_events.sql +17 -0
- package/drizzle/0004_notifications_audit.sql +64 -0
- package/drizzle/0005_api_keys_webhooks.sql +77 -0
- package/drizzle/0006_feature_flags.sql +22 -0
- package/drizzle/0007_files.sql +23 -0
- package/drizzle/meta/0000_snapshot.json +160 -0
- package/drizzle/meta/0001_snapshot.json +837 -0
- package/drizzle/meta/0002_snapshot.json +1580 -0
- package/drizzle/meta/0003_snapshot.json +1751 -0
- package/drizzle/meta/0004_snapshot.json +2109 -0
- package/drizzle/meta/0005_snapshot.json +2719 -0
- package/drizzle/meta/0006_snapshot.json +2909 -0
- package/drizzle/meta/0007_snapshot.json +3113 -0
- package/drizzle/meta/_journal.json +62 -0
- package/package.json +180 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { basename, join, resolve } from "node:path";
|
|
3
|
+
import { assertDockerAvailable, compose, createCommandRunner, looksLikeDaemonDown, } from "../docker.js";
|
|
4
|
+
import { CliError, info, step, style, success, table, warn } from "../output.js";
|
|
5
|
+
import { DEFAULT_STACK, normaliseProjectName, renderCaddyfile, renderComposeFile, renderStackGitignore, stackEnvironment, } from "../templates.js";
|
|
6
|
+
/** Where the generated stack lives, relative to the project root. */
|
|
7
|
+
export const STACK_DIRECTORY = ".saas-core";
|
|
8
|
+
function buildConfig(cwd, options) {
|
|
9
|
+
return {
|
|
10
|
+
...DEFAULT_STACK,
|
|
11
|
+
// Derived from the directory name, so two projects on one machine get
|
|
12
|
+
// separate containers and volumes without anyone configuring it.
|
|
13
|
+
projectName: normaliseProjectName(options.projectName ?? basename(resolve(cwd))),
|
|
14
|
+
...(options.domain !== undefined ? { domain: options.domain } : {}),
|
|
15
|
+
...(options.appPort !== undefined ? { appPort: options.appPort } : {}),
|
|
16
|
+
...(options.postgresPort !== undefined ? { postgresPort: options.postgresPort } : {}),
|
|
17
|
+
...(options.minioPort !== undefined
|
|
18
|
+
? { minioPort: options.minioPort, minioConsolePort: options.minioPort + 1 }
|
|
19
|
+
: {}),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
async function exists(path) {
|
|
23
|
+
try {
|
|
24
|
+
await readFile(path);
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Write the stack files.
|
|
33
|
+
*
|
|
34
|
+
* Existing files are left alone unless `--force`. They are meant to be edited —
|
|
35
|
+
* a developer who changed the Caddyfile to add a second host should not lose it
|
|
36
|
+
* to the next `up`.
|
|
37
|
+
*/
|
|
38
|
+
export async function writeStackFiles(cwd, options = {}) {
|
|
39
|
+
const config = buildConfig(cwd, options);
|
|
40
|
+
const directory = join(cwd, STACK_DIRECTORY);
|
|
41
|
+
await mkdir(directory, { recursive: true });
|
|
42
|
+
const contents = [
|
|
43
|
+
["docker-compose.yml", renderComposeFile(config)],
|
|
44
|
+
["Caddyfile", renderCaddyfile(config)],
|
|
45
|
+
[".gitignore", renderStackGitignore()],
|
|
46
|
+
];
|
|
47
|
+
const files = [];
|
|
48
|
+
for (const [name, body] of contents) {
|
|
49
|
+
const path = join(directory, name);
|
|
50
|
+
const present = await exists(path);
|
|
51
|
+
if (present && options.force !== true) {
|
|
52
|
+
files.push({ path, action: "kept" });
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
await writeFile(path, body, "utf8");
|
|
56
|
+
files.push({ path, action: present ? "updated" : "created" });
|
|
57
|
+
}
|
|
58
|
+
return { config, directory, files };
|
|
59
|
+
}
|
|
60
|
+
function contextFor(directory, config, options) {
|
|
61
|
+
return {
|
|
62
|
+
runner: options.runner ?? createCommandRunner(),
|
|
63
|
+
directory,
|
|
64
|
+
projectName: config.projectName,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/** Turn a compose failure into something a user can act on. */
|
|
68
|
+
function explainFailure(stderr) {
|
|
69
|
+
/**
|
|
70
|
+
* Still checked here even though `assertDockerAvailable` probes the daemon
|
|
71
|
+
* first: Docker Desktop can stop mid-command, and a raw socket path is not a
|
|
72
|
+
* useful thing to show someone.
|
|
73
|
+
*/
|
|
74
|
+
if (looksLikeDaemonDown(stderr)) {
|
|
75
|
+
return new CliError("The Docker daemon stopped responding.", {
|
|
76
|
+
hint: "Start Docker Desktop, or run `sudo systemctl start docker`.",
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (/port is already allocated|address already in use|bind: permission denied/i.test(stderr)) {
|
|
80
|
+
return new CliError("A port the stack needs is already in use.", {
|
|
81
|
+
hint: "Pass --postgres-port or --minio-port to move it, " +
|
|
82
|
+
"or stop whatever is holding 80/443 for Caddy.",
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
if (/no space left on device/i.test(stderr)) {
|
|
86
|
+
return new CliError("Docker has run out of disk space.", {
|
|
87
|
+
hint: "`docker system prune` reclaims unused images and volumes.",
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return new CliError(`docker compose failed:\n${stderr.trim()}`);
|
|
91
|
+
}
|
|
92
|
+
export async function devUp(options = {}) {
|
|
93
|
+
const cwd = options.cwd ?? process.cwd();
|
|
94
|
+
const runner = options.runner ?? createCommandRunner();
|
|
95
|
+
const version = await assertDockerAvailable(runner);
|
|
96
|
+
step(`docker compose ${style.dim(`v${version}`)}`);
|
|
97
|
+
const { config, directory, files } = await writeStackFiles(cwd, { ...options, runner });
|
|
98
|
+
for (const file of files) {
|
|
99
|
+
if (file.action !== "kept") {
|
|
100
|
+
step(`${file.action} ${style.dim(file.path)}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (files.every((file) => file.action === "kept")) {
|
|
104
|
+
step(`using existing stack in ${style.dim(directory)}`);
|
|
105
|
+
}
|
|
106
|
+
step("starting postgres, minio and caddy");
|
|
107
|
+
/**
|
|
108
|
+
* `--wait` blocks until every healthcheck passes, so this command returning
|
|
109
|
+
* means the stack is usable. Without it "up" only means the containers were
|
|
110
|
+
* created, and the next command races the database.
|
|
111
|
+
*/
|
|
112
|
+
const result = await compose(contextFor(directory, config, options), ["up", "-d", "--wait", "--remove-orphans"], {});
|
|
113
|
+
if (result.code !== 0) {
|
|
114
|
+
throw explainFailure(`${result.stdout}${result.stderr}`);
|
|
115
|
+
}
|
|
116
|
+
success(`stack up (project ${style.bold(config.projectName)})`);
|
|
117
|
+
info("");
|
|
118
|
+
info(style.bold("Endpoints"));
|
|
119
|
+
table([
|
|
120
|
+
["app", `https://${config.domain} -> localhost:${config.appPort}`],
|
|
121
|
+
["postgres", `localhost:${config.postgresPort}`],
|
|
122
|
+
["minio", `http://localhost:${config.minioPort}`],
|
|
123
|
+
["minio console", `http://localhost:${config.minioConsolePort}`],
|
|
124
|
+
]);
|
|
125
|
+
info("");
|
|
126
|
+
info(style.bold("Configuration"));
|
|
127
|
+
info(style.dim(" Load these through Infisical rather than a .env file:"));
|
|
128
|
+
info("");
|
|
129
|
+
table(stackEnvironment(config));
|
|
130
|
+
info("");
|
|
131
|
+
info(style.dim(" ") +
|
|
132
|
+
stackEnvironment(config)
|
|
133
|
+
.map(([key, value]) => `infisical secrets set ${key}='${value}'`)
|
|
134
|
+
.join(`\n${style.dim(" ")}`));
|
|
135
|
+
info("");
|
|
136
|
+
info(style.bold("Next"));
|
|
137
|
+
info(` 1. Trust Caddy's local CA, or the browser will warn on every request:`);
|
|
138
|
+
info(style.dim(` docker compose -p ${config.projectName} cp caddy:/data/caddy/pki/authorities/local/root.crt ./caddy-root.crt`));
|
|
139
|
+
info(` 2. Apply the core migrations: ${style.cyan("infisical run -- npm run db:migrate")}`);
|
|
140
|
+
info(` 3. Start your dev server on port ${config.appPort}.`);
|
|
141
|
+
}
|
|
142
|
+
export async function devDown(options = {}) {
|
|
143
|
+
const cwd = options.cwd ?? process.cwd();
|
|
144
|
+
const runner = options.runner ?? createCommandRunner();
|
|
145
|
+
await assertDockerAvailable(runner);
|
|
146
|
+
const config = buildConfig(cwd, options);
|
|
147
|
+
const directory = join(cwd, STACK_DIRECTORY);
|
|
148
|
+
if (!(await exists(join(directory, "docker-compose.yml")))) {
|
|
149
|
+
throw new CliError(`No stack found in ${directory}.`, {
|
|
150
|
+
hint: "`saas-core dev up` generates it.",
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
step(options.volumes === true ? "stopping and deleting volumes" : "stopping");
|
|
154
|
+
const result = await compose(contextFor(directory, config, options), ["down", ...(options.volumes === true ? ["--volumes"] : [])]);
|
|
155
|
+
if (result.code !== 0) {
|
|
156
|
+
throw explainFailure(`${result.stdout}${result.stderr}`);
|
|
157
|
+
}
|
|
158
|
+
if (options.volumes === true) {
|
|
159
|
+
// Worth stating plainly: this is the one destructive command here.
|
|
160
|
+
success("stack down, volumes deleted");
|
|
161
|
+
warn("the database and object store are now empty");
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
success("stack down, data preserved");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
export async function devStatus(options = {}) {
|
|
168
|
+
const cwd = options.cwd ?? process.cwd();
|
|
169
|
+
const runner = options.runner ?? createCommandRunner();
|
|
170
|
+
await assertDockerAvailable(runner);
|
|
171
|
+
const config = buildConfig(cwd, options);
|
|
172
|
+
const directory = join(cwd, STACK_DIRECTORY);
|
|
173
|
+
if (!(await exists(join(directory, "docker-compose.yml")))) {
|
|
174
|
+
throw new CliError(`No stack found in ${directory}.`, {
|
|
175
|
+
hint: "`saas-core dev up` generates it.",
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
const result = await compose(contextFor(directory, config, options), ["ps"], { inherit: true });
|
|
179
|
+
if (result.code !== 0) {
|
|
180
|
+
throw explainFailure(`${result.stdout}${result.stderr}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
export async function devLogs(options = {}) {
|
|
184
|
+
const cwd = options.cwd ?? process.cwd();
|
|
185
|
+
const runner = options.runner ?? createCommandRunner();
|
|
186
|
+
await assertDockerAvailable(runner);
|
|
187
|
+
const config = buildConfig(cwd, options);
|
|
188
|
+
const directory = join(cwd, STACK_DIRECTORY);
|
|
189
|
+
await compose(contextFor(directory, config, options), [
|
|
190
|
+
"logs",
|
|
191
|
+
...(options.follow === true ? ["--follow"] : []),
|
|
192
|
+
"--tail",
|
|
193
|
+
"100",
|
|
194
|
+
...(options.service !== undefined ? [options.service] : []),
|
|
195
|
+
], { inherit: true });
|
|
196
|
+
}
|
|
197
|
+
/** Write the files without starting anything. For inspecting or editing first. */
|
|
198
|
+
export async function devInit(options = {}) {
|
|
199
|
+
const cwd = options.cwd ?? process.cwd();
|
|
200
|
+
const { directory, files } = await writeStackFiles(cwd, options);
|
|
201
|
+
for (const file of files) {
|
|
202
|
+
step(file.action === "kept"
|
|
203
|
+
? `${style.dim("kept")} ${file.path}`
|
|
204
|
+
: `${file.action} ${style.dim(file.path)}`);
|
|
205
|
+
}
|
|
206
|
+
success(`stack written to ${directory}`);
|
|
207
|
+
info(` Review it, then ${style.cyan("saas-core dev up")}.`);
|
|
208
|
+
if (files.some((file) => file.action === "kept")) {
|
|
209
|
+
info(style.dim(" Existing files were left alone. Pass --force to overwrite."));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=dev.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../../src/cli/commands/dev.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type CommandRunner } from "../docker.ts";
|
|
2
|
+
export declare const PROJECT_COMPOSE_FILE = "docker-compose.yml";
|
|
3
|
+
export interface ProjectOptions {
|
|
4
|
+
readonly cwd?: string;
|
|
5
|
+
readonly runner?: CommandRunner;
|
|
6
|
+
readonly projectName?: string;
|
|
7
|
+
readonly postgresPort?: number;
|
|
8
|
+
readonly force?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function projectInit(options: ProjectOptions): Promise<void>;
|
|
11
|
+
export declare function projectStart(options?: ProjectOptions): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=project.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/project.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,cAAc,CAAC;AAItB,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAEzD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAWD,wBAAsB,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBxE;AAED,wBAAsB,YAAY,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0B9E"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { assertDockerAvailable, createCommandRunner, } from "../docker.js";
|
|
4
|
+
import { CliError, step, style, success } from "../output.js";
|
|
5
|
+
import { normaliseProjectName, renderProjectComposeFile } from "../templates.js";
|
|
6
|
+
export const PROJECT_COMPOSE_FILE = "docker-compose.yml";
|
|
7
|
+
async function exists(path) {
|
|
8
|
+
try {
|
|
9
|
+
await readFile(path);
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export async function projectInit(options) {
|
|
17
|
+
const cwd = resolve(options.cwd ?? process.cwd());
|
|
18
|
+
const path = join(cwd, PROJECT_COMPOSE_FILE);
|
|
19
|
+
if ((await exists(path)) && options.force !== true) {
|
|
20
|
+
throw new CliError(`${PROJECT_COMPOSE_FILE} already exists.`, {
|
|
21
|
+
hint: "Use --force to replace it, or keep the existing Compose file.",
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
const projectName = normaliseProjectName(options.projectName ?? "");
|
|
25
|
+
const postgresPort = options.postgresPort ?? 5432;
|
|
26
|
+
await writeFile(path, renderProjectComposeFile({ projectName, postgresPort }), "utf8");
|
|
27
|
+
success(`created ${style.dim(path)}`);
|
|
28
|
+
success(`project ${style.bold(projectName)} initialized`);
|
|
29
|
+
step(`run ${style.cyan("sc start")} to start PostgreSQL`);
|
|
30
|
+
}
|
|
31
|
+
export async function projectStart(options = {}) {
|
|
32
|
+
const cwd = resolve(options.cwd ?? process.cwd());
|
|
33
|
+
const path = join(cwd, PROJECT_COMPOSE_FILE);
|
|
34
|
+
if (!(await exists(path))) {
|
|
35
|
+
throw new CliError(`${PROJECT_COMPOSE_FILE} was not found in ${cwd}.`, {
|
|
36
|
+
hint: "Run `sc init` first.",
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
const runner = options.runner ?? createCommandRunner();
|
|
40
|
+
const version = await assertDockerAvailable(runner);
|
|
41
|
+
step(`docker compose ${style.dim(`v${version}`)}`);
|
|
42
|
+
step("starting PostgreSQL");
|
|
43
|
+
const result = await runner.run("docker", ["compose", "-f", PROJECT_COMPOSE_FILE, "up", "-d", "--wait", "--remove-orphans"], { cwd });
|
|
44
|
+
if (result.code !== 0) {
|
|
45
|
+
throw new CliError(`docker compose failed:\n${`${result.stdout}${result.stderr}`.trim()}`);
|
|
46
|
+
}
|
|
47
|
+
success("PostgreSQL is ready");
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/cli/commands/project.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface RunResult {
|
|
2
|
+
readonly code: number;
|
|
3
|
+
readonly stdout: string;
|
|
4
|
+
readonly stderr: string;
|
|
5
|
+
}
|
|
6
|
+
export interface RunOptions {
|
|
7
|
+
readonly cwd?: string;
|
|
8
|
+
/** Stream to the terminal instead of capturing. For `logs` and `up`. */
|
|
9
|
+
readonly inherit?: boolean;
|
|
10
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* How the CLI reaches Docker.
|
|
14
|
+
*
|
|
15
|
+
* Injected so command construction is testable without Docker installed — which
|
|
16
|
+
* matters, because the argument list is the part that is easy to get wrong and the
|
|
17
|
+
* part no type can check.
|
|
18
|
+
*/
|
|
19
|
+
export interface CommandRunner {
|
|
20
|
+
run(command: string, args: readonly string[], options?: RunOptions): Promise<RunResult>;
|
|
21
|
+
}
|
|
22
|
+
export declare function createCommandRunner(): CommandRunner;
|
|
23
|
+
/** True when output complains about an unreachable daemon. */
|
|
24
|
+
export declare function looksLikeDaemonDown(output: string): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Confirm Docker is present, its daemon is reachable, and `compose` exists.
|
|
27
|
+
*
|
|
28
|
+
* Checked up front rather than letting the first real command fail. "Command not
|
|
29
|
+
* found", "daemon not running" and "no compose plugin" are three problems with
|
|
30
|
+
* three different fixes, and that distinction is lost if a `compose up` — halfway
|
|
31
|
+
* through pulling images — is what surfaces them.
|
|
32
|
+
*
|
|
33
|
+
* Note that the daemon needs its own probe. `docker compose version` reports the
|
|
34
|
+
* *client* plugin and succeeds perfectly well with the daemon stopped, so
|
|
35
|
+
* checking only that lets a stopped daemon through to fail later and less
|
|
36
|
+
* clearly.
|
|
37
|
+
*/
|
|
38
|
+
export declare function assertDockerAvailable(runner: CommandRunner): Promise<string>;
|
|
39
|
+
export interface ComposeContext {
|
|
40
|
+
readonly runner: CommandRunner;
|
|
41
|
+
/** Directory holding the generated compose file. */
|
|
42
|
+
readonly directory: string;
|
|
43
|
+
/** Passed as `-p`, so several projects can run side by side without colliding. */
|
|
44
|
+
readonly projectName: string;
|
|
45
|
+
}
|
|
46
|
+
/** Invoke `docker compose` against the generated project. */
|
|
47
|
+
export declare function compose(context: ComposeContext, args: readonly string[], options?: {
|
|
48
|
+
inherit?: boolean;
|
|
49
|
+
}): Promise<RunResult>;
|
|
50
|
+
//# sourceMappingURL=docker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../src/cli/docker.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACjD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;CACzF;AAED,wBAAgB,mBAAmB,IAAI,aAAa,CAwBnD;AAED,8DAA8D;AAC9D,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAI3D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CA4ClF;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,oDAAoD;IACpD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,kFAAkF;IAClF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,6DAA6D;AAC7D,wBAAgB,OAAO,CACrB,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAClC,OAAO,CAAC,SAAS,CAAC,CASpB"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { CliError } from "./output.js";
|
|
3
|
+
export function createCommandRunner() {
|
|
4
|
+
return {
|
|
5
|
+
run(command, args, options = {}) {
|
|
6
|
+
return new Promise((resolve, reject) => {
|
|
7
|
+
const child = spawn(command, [...args], {
|
|
8
|
+
...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
|
|
9
|
+
stdio: options.inherit === true ? "inherit" : "pipe",
|
|
10
|
+
env: { ...process.env, ...(options.env ?? {}) },
|
|
11
|
+
});
|
|
12
|
+
let stdout = "";
|
|
13
|
+
let stderr = "";
|
|
14
|
+
child.stdout?.on("data", (chunk) => {
|
|
15
|
+
stdout += chunk.toString();
|
|
16
|
+
});
|
|
17
|
+
child.stderr?.on("data", (chunk) => {
|
|
18
|
+
stderr += chunk.toString();
|
|
19
|
+
});
|
|
20
|
+
child.on("error", reject);
|
|
21
|
+
child.on("close", (code) => resolve({ code: code ?? 1, stdout, stderr }));
|
|
22
|
+
});
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/** True when output complains about an unreachable daemon. */
|
|
27
|
+
export function looksLikeDaemonDown(output) {
|
|
28
|
+
return /cannot connect to the docker daemon|is the docker daemon running|docker daemon is not running|open \/\/\.\/pipe\/docker_engine/i.test(output);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Confirm Docker is present, its daemon is reachable, and `compose` exists.
|
|
32
|
+
*
|
|
33
|
+
* Checked up front rather than letting the first real command fail. "Command not
|
|
34
|
+
* found", "daemon not running" and "no compose plugin" are three problems with
|
|
35
|
+
* three different fixes, and that distinction is lost if a `compose up` — halfway
|
|
36
|
+
* through pulling images — is what surfaces them.
|
|
37
|
+
*
|
|
38
|
+
* Note that the daemon needs its own probe. `docker compose version` reports the
|
|
39
|
+
* *client* plugin and succeeds perfectly well with the daemon stopped, so
|
|
40
|
+
* checking only that lets a stopped daemon through to fail later and less
|
|
41
|
+
* clearly.
|
|
42
|
+
*/
|
|
43
|
+
export async function assertDockerAvailable(runner) {
|
|
44
|
+
let version;
|
|
45
|
+
try {
|
|
46
|
+
version = await runner.run("docker", ["compose", "version", "--short"]);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
throw new CliError("Docker is not installed, or not on PATH.", {
|
|
50
|
+
hint: "Install Docker Desktop, or the docker engine plus the compose plugin.",
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
if (version.code !== 0) {
|
|
54
|
+
const combined = `${version.stdout}${version.stderr}`;
|
|
55
|
+
if (looksLikeDaemonDown(combined)) {
|
|
56
|
+
throw new CliError("Docker is installed but the daemon is not running.", {
|
|
57
|
+
hint: "Start Docker Desktop, or run `sudo systemctl start docker`.",
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (/is not a docker command|unknown command/i.test(combined)) {
|
|
61
|
+
throw new CliError("This Docker installation has no `compose` plugin.", {
|
|
62
|
+
hint: "Compose v2 is required; `docker compose version` should succeed.",
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
throw new CliError(`\`docker compose version\` failed: ${combined.trim()}`);
|
|
66
|
+
}
|
|
67
|
+
// Requires the daemon, unlike the version check above.
|
|
68
|
+
const daemon = await runner.run("docker", ["version", "--format", "{{.Server.Version}}"]);
|
|
69
|
+
if (daemon.code !== 0) {
|
|
70
|
+
const combined = `${daemon.stdout}${daemon.stderr}`;
|
|
71
|
+
throw new CliError(looksLikeDaemonDown(combined)
|
|
72
|
+
? "The Docker CLI is installed but its daemon is not reachable."
|
|
73
|
+
: `Could not reach the Docker daemon: ${combined.trim()}`, { hint: "Start Docker Desktop, or run `sudo systemctl start docker`." });
|
|
74
|
+
}
|
|
75
|
+
return version.stdout.trim();
|
|
76
|
+
}
|
|
77
|
+
/** Invoke `docker compose` against the generated project. */
|
|
78
|
+
export function compose(context, args, options = {}) {
|
|
79
|
+
return context.runner.run("docker", ["compose", "-p", context.projectName, "-f", "docker-compose.yml", ...args], {
|
|
80
|
+
cwd: context.directory,
|
|
81
|
+
...(options.inherit === true ? { inherit: true } : {}),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=docker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/cli/docker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AA+CA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CACnD;AA2BD,wBAAsB,IAAI,CACxB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,YAAY,GAAE,gBAAwC,GACrD,OAAO,CAAC,MAAM,CAAC,CAwHjB"}
|