@better-openclaw/core 1.0.21 → 1.0.22
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/dist/bare-metal-partition.cjs +2 -3
- package/dist/bare-metal-partition.cjs.map +1 -1
- package/dist/bare-metal-partition.d.mts.map +1 -1
- package/dist/bare-metal-partition.mjs +1 -1
- package/dist/bare-metal-partition.test.cjs +4 -5
- package/dist/bare-metal-partition.test.cjs.map +1 -1
- package/dist/bare-metal-partition.test.mjs +3 -4
- package/dist/bare-metal-partition.test.mjs.map +1 -1
- package/dist/compose-validation.test.cjs +5 -6
- package/dist/compose-validation.test.cjs.map +1 -1
- package/dist/compose-validation.test.mjs +2 -3
- package/dist/compose-validation.test.mjs.map +1 -1
- package/dist/composer.cjs +4 -5
- package/dist/composer.cjs.map +1 -1
- package/dist/composer.d.mts.map +1 -1
- package/dist/composer.mjs +1 -2
- package/dist/composer.mjs.map +1 -1
- package/dist/composer.snapshot.test.cjs +4 -5
- package/dist/composer.snapshot.test.cjs.map +1 -1
- package/dist/composer.snapshot.test.mjs +3 -4
- package/dist/composer.snapshot.test.mjs.map +1 -1
- package/dist/composer.test.cjs +5 -6
- package/dist/composer.test.cjs.map +1 -1
- package/dist/composer.test.mjs +3 -4
- package/dist/composer.test.mjs.map +1 -1
- package/dist/coolify-BVGGcMrT.d.mts +18 -0
- package/dist/coolify-BVGGcMrT.d.mts.map +1 -0
- package/dist/coolify-vlb1G9V2.d.cts +18 -0
- package/dist/coolify-vlb1G9V2.d.cts.map +1 -0
- package/dist/deployers/coolify.cjs +3 -4
- package/dist/deployers/coolify.cjs.map +1 -1
- package/dist/deployers/coolify.d.cts +2 -18
- package/dist/deployers/coolify.d.mts +2 -18
- package/dist/deployers/coolify.mjs +1 -2
- package/dist/deployers/coolify.mjs.map +1 -1
- package/dist/deployers/dokploy.cjs +3 -4
- package/dist/deployers/dokploy.cjs.map +1 -1
- package/dist/deployers/dokploy.d.cts +2 -25
- package/dist/deployers/dokploy.d.mts +2 -25
- package/dist/deployers/dokploy.mjs +1 -2
- package/dist/deployers/dokploy.mjs.map +1 -1
- package/dist/deployers/index.cjs +4 -5
- package/dist/deployers/index.cjs.map +1 -1
- package/dist/deployers/index.d.cts +3 -3
- package/dist/deployers/index.d.mts +3 -3
- package/dist/deployers/index.mjs +1 -2
- package/dist/deployers/index.mjs.map +1 -1
- package/dist/deployers/strip-host-ports.cjs +3 -4
- package/dist/deployers/strip-host-ports.cjs.map +1 -1
- package/dist/deployers/strip-host-ports.mjs +1 -2
- package/dist/deployers/strip-host-ports.mjs.map +1 -1
- package/dist/deployers/strip-host-ports.test.cjs +3 -4
- package/dist/deployers/strip-host-ports.test.cjs.map +1 -1
- package/dist/deployers/strip-host-ports.test.mjs +3 -4
- package/dist/deployers/strip-host-ports.test.mjs.map +1 -1
- package/dist/deployers/types.d.cts +2 -243
- package/dist/deployers/types.d.mts +2 -243
- package/dist/deployers/types.mjs +1 -1
- package/dist/dokploy-8cbrxUun.d.cts +25 -0
- package/dist/dokploy-8cbrxUun.d.cts.map +1 -0
- package/dist/dokploy-BTflLhTM.d.mts +25 -0
- package/dist/dokploy-BTflLhTM.d.mts.map +1 -0
- package/dist/errors.cjs +2 -3
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.mjs +1 -1
- package/dist/errors.mjs.map +1 -1
- package/dist/generate.cjs +27 -28
- package/dist/generate.cjs.map +1 -1
- package/dist/generate.d.mts.map +1 -1
- package/dist/generate.mjs +1 -2
- package/dist/generate.mjs.map +1 -1
- package/dist/generate.test.cjs +4 -5
- package/dist/generate.test.cjs.map +1 -1
- package/dist/generate.test.mjs +3 -4
- package/dist/generate.test.mjs.map +1 -1
- package/dist/generators/bare-metal-install.cjs +2 -3
- package/dist/generators/bare-metal-install.cjs.map +1 -1
- package/dist/generators/bare-metal-install.d.mts.map +1 -1
- package/dist/generators/bare-metal-install.mjs +1 -1
- package/dist/generators/bare-metal-install.test.cjs +3 -4
- package/dist/generators/bare-metal-install.test.cjs.map +1 -1
- package/dist/generators/bare-metal-install.test.mjs +3 -4
- package/dist/generators/bare-metal-install.test.mjs.map +1 -1
- package/dist/generators/caddy.cjs +2 -3
- package/dist/generators/caddy.cjs.map +1 -1
- package/dist/generators/caddy.d.mts.map +1 -1
- package/dist/generators/caddy.mjs +1 -1
- package/dist/generators/caddy.test.cjs +3 -4
- package/dist/generators/caddy.test.cjs.map +1 -1
- package/dist/generators/caddy.test.mjs +3 -4
- package/dist/generators/caddy.test.mjs.map +1 -1
- package/dist/generators/cloud-init.cjs +2 -3
- package/dist/generators/cloud-init.cjs.map +1 -1
- package/dist/generators/cloud-init.mjs +1 -1
- package/dist/generators/env.cjs +4 -5
- package/dist/generators/env.cjs.map +1 -1
- package/dist/generators/env.d.mts.map +1 -1
- package/dist/generators/env.mjs +1 -2
- package/dist/generators/env.mjs.map +1 -1
- package/dist/generators/env.test.cjs +3 -4
- package/dist/generators/env.test.cjs.map +1 -1
- package/dist/generators/env.test.mjs +3 -4
- package/dist/generators/env.test.mjs.map +1 -1
- package/dist/generators/get-shit-done.cjs +2 -3
- package/dist/generators/get-shit-done.cjs.map +1 -1
- package/dist/generators/get-shit-done.mjs +1 -1
- package/dist/generators/grafana.cjs +2 -3
- package/dist/generators/grafana.cjs.map +1 -1
- package/dist/generators/grafana.mjs +1 -1
- package/dist/generators/health-check.cjs +2 -3
- package/dist/generators/health-check.cjs.map +1 -1
- package/dist/generators/health-check.d.mts.map +1 -1
- package/dist/generators/health-check.mjs +1 -1
- package/dist/generators/health-check.test.cjs +3 -4
- package/dist/generators/health-check.test.cjs.map +1 -1
- package/dist/generators/health-check.test.mjs +3 -4
- package/dist/generators/health-check.test.mjs.map +1 -1
- package/dist/generators/n8n-workflows.cjs +2 -3
- package/dist/generators/n8n-workflows.cjs.map +1 -1
- package/dist/generators/n8n-workflows.d.mts.map +1 -1
- package/dist/generators/n8n-workflows.mjs +1 -1
- package/dist/generators/native-services.cjs +2 -3
- package/dist/generators/native-services.cjs.map +1 -1
- package/dist/generators/native-services.mjs +1 -1
- package/dist/generators/openclaw-install-script.cjs +2 -3
- package/dist/generators/openclaw-install-script.cjs.map +1 -1
- package/dist/generators/openclaw-install-script.mjs +1 -1
- package/dist/generators/openclaw-json.cjs +2 -3
- package/dist/generators/openclaw-json.cjs.map +1 -1
- package/dist/generators/openclaw-json.mjs +1 -1
- package/dist/generators/postgres-init.cjs +32 -3
- package/dist/generators/postgres-init.cjs.map +1 -1
- package/dist/generators/postgres-init.d.cts.map +1 -1
- package/dist/generators/postgres-init.d.mts.map +1 -1
- package/dist/generators/postgres-init.mjs +31 -1
- package/dist/generators/postgres-init.mjs.map +1 -1
- package/dist/generators/prometheus.cjs +2 -3
- package/dist/generators/prometheus.cjs.map +1 -1
- package/dist/generators/prometheus.d.mts.map +1 -1
- package/dist/generators/prometheus.mjs +1 -1
- package/dist/generators/readme.cjs +2 -3
- package/dist/generators/readme.cjs.map +1 -1
- package/dist/generators/readme.d.mts.map +1 -1
- package/dist/generators/readme.mjs +1 -1
- package/dist/generators/scripts.cjs +2 -3
- package/dist/generators/scripts.cjs.map +1 -1
- package/dist/generators/scripts.mjs +1 -1
- package/dist/generators/scripts.test.cjs +3 -4
- package/dist/generators/scripts.test.cjs.map +1 -1
- package/dist/generators/scripts.test.mjs +3 -4
- package/dist/generators/scripts.test.mjs.map +1 -1
- package/dist/generators/skills.cjs +3 -590
- package/dist/generators/skills.d.mts.map +1 -1
- package/dist/generators/skills.mjs +1 -2
- package/dist/generators/skills.mjs.map +1 -1
- package/dist/generators/stack-manifest.cjs +2 -3
- package/dist/generators/stack-manifest.cjs.map +1 -1
- package/dist/generators/stack-manifest.mjs +1 -1
- package/dist/generators/traefik.cjs +2 -3
- package/dist/generators/traefik.cjs.map +1 -1
- package/dist/generators/traefik.mjs +1 -1
- package/dist/generators/traefik.test.cjs +4 -5
- package/dist/generators/traefik.test.cjs.map +1 -1
- package/dist/generators/traefik.test.mjs +3 -4
- package/dist/generators/traefik.test.mjs.map +1 -1
- package/dist/index.cjs +35 -36
- package/dist/index.d.cts +4 -4
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +2 -3
- package/dist/{magic-string.es-D2agHT3I.cjs → magic-string.es-CJq41xdM.cjs} +2 -4
- package/dist/{magic-string.es-CfFonO_S.mjs.map → magic-string.es-CJq41xdM.cjs.map} +1 -1
- package/dist/{magic-string.es-CfFonO_S.mjs → magic-string.es-CoDyF8pj.mjs} +2 -3
- package/dist/{magic-string.es-D2agHT3I.cjs.map → magic-string.es-CoDyF8pj.mjs.map} +1 -1
- package/dist/migrations.cjs +5 -6
- package/dist/migrations.cjs.map +1 -1
- package/dist/migrations.mjs +4 -4
- package/dist/migrations.mjs.map +1 -1
- package/dist/migrations.test.cjs +6 -7
- package/dist/migrations.test.cjs.map +1 -1
- package/dist/migrations.test.mjs +7 -8
- package/dist/migrations.test.mjs.map +1 -1
- package/dist/port-scanner.cjs +2 -3
- package/dist/port-scanner.cjs.map +1 -1
- package/dist/port-scanner.d.mts.map +1 -1
- package/dist/port-scanner.mjs +1 -1
- package/dist/presets/presets.test.cjs +11 -8
- package/dist/presets/presets.test.cjs.map +1 -1
- package/dist/presets/presets.test.mjs +7 -4
- package/dist/presets/presets.test.mjs.map +1 -1
- package/dist/presets/registry.cjs +152 -3
- package/dist/presets/registry.cjs.map +1 -1
- package/dist/presets/registry.d.cts.map +1 -1
- package/dist/presets/registry.d.mts.map +1 -1
- package/dist/presets/registry.mjs +151 -1
- package/dist/presets/registry.mjs.map +1 -1
- package/dist/presets/registry.test.cjs +3 -4
- package/dist/presets/registry.test.cjs.map +1 -1
- package/dist/presets/registry.test.mjs +3 -4
- package/dist/presets/registry.test.mjs.map +1 -1
- package/dist/resolver.cjs +4 -5
- package/dist/resolver.cjs.map +1 -1
- package/dist/resolver.d.mts.map +1 -1
- package/dist/resolver.mjs +1 -2
- package/dist/resolver.mjs.map +1 -1
- package/dist/resolver.test.cjs +3 -4
- package/dist/resolver.test.cjs.map +1 -1
- package/dist/resolver.test.mjs +3 -4
- package/dist/resolver.test.mjs.map +1 -1
- package/dist/schema-C_hc7e4k.d.cts +898 -0
- package/dist/schema-C_hc7e4k.d.cts.map +1 -0
- package/dist/schema-CaesJaS2.d.mts +898 -0
- package/dist/schema-CaesJaS2.d.mts.map +1 -0
- package/dist/schema.cjs +15 -5
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +2 -854
- package/dist/schema.d.mts +2 -854
- package/dist/schema.mjs +13 -3
- package/dist/schema.mjs.map +1 -1
- package/dist/schema.test.cjs +3 -4
- package/dist/schema.test.cjs.map +1 -1
- package/dist/schema.test.mjs +3 -4
- package/dist/schema.test.mjs.map +1 -1
- package/dist/services/definitions/airbyte.cjs +76 -0
- package/dist/services/definitions/airbyte.cjs.map +1 -0
- package/dist/services/definitions/airbyte.d.cts +7 -0
- package/dist/services/definitions/airbyte.d.cts.map +1 -0
- package/dist/services/definitions/airbyte.d.mts +7 -0
- package/dist/services/definitions/airbyte.d.mts.map +1 -0
- package/dist/services/definitions/airbyte.mjs +75 -0
- package/dist/services/definitions/airbyte.mjs.map +1 -0
- package/dist/services/definitions/airflow.cjs +109 -0
- package/dist/services/definitions/airflow.cjs.map +1 -0
- package/dist/services/definitions/airflow.d.cts +7 -0
- package/dist/services/definitions/airflow.d.cts.map +1 -0
- package/dist/services/definitions/airflow.d.mts +7 -0
- package/dist/services/definitions/airflow.d.mts.map +1 -0
- package/dist/services/definitions/airflow.mjs +108 -0
- package/dist/services/definitions/airflow.mjs.map +1 -0
- package/dist/services/definitions/anything-llm.cjs +2 -3
- package/dist/services/definitions/anything-llm.cjs.map +1 -1
- package/dist/services/definitions/anything-llm.mjs +1 -1
- package/dist/services/definitions/appflowy.cjs +2 -3
- package/dist/services/definitions/appflowy.cjs.map +1 -1
- package/dist/services/definitions/appflowy.mjs +1 -1
- package/dist/services/definitions/appwrite.cjs +190 -0
- package/dist/services/definitions/appwrite.cjs.map +1 -0
- package/dist/services/definitions/appwrite.d.cts +7 -0
- package/dist/services/definitions/appwrite.d.cts.map +1 -0
- package/dist/services/definitions/appwrite.d.mts +7 -0
- package/dist/services/definitions/appwrite.d.mts.map +1 -0
- package/dist/services/definitions/appwrite.mjs +189 -0
- package/dist/services/definitions/appwrite.mjs.map +1 -0
- package/dist/services/definitions/authelia.cjs +145 -0
- package/dist/services/definitions/authelia.cjs.map +1 -0
- package/dist/services/definitions/authelia.d.cts +7 -0
- package/dist/services/definitions/authelia.d.cts.map +1 -0
- package/dist/services/definitions/authelia.d.mts +7 -0
- package/dist/services/definitions/authelia.d.mts.map +1 -0
- package/dist/services/definitions/authelia.mjs +144 -0
- package/dist/services/definitions/authelia.mjs.map +1 -0
- package/dist/services/definitions/authentik.cjs +2 -3
- package/dist/services/definitions/authentik.cjs.map +1 -1
- package/dist/services/definitions/authentik.mjs +1 -1
- package/dist/services/definitions/axolotl.cjs +67 -0
- package/dist/services/definitions/axolotl.cjs.map +1 -0
- package/dist/services/definitions/axolotl.d.cts +7 -0
- package/dist/services/definitions/axolotl.d.cts.map +1 -0
- package/dist/services/definitions/axolotl.d.mts +7 -0
- package/dist/services/definitions/axolotl.d.mts.map +1 -0
- package/dist/services/definitions/axolotl.mjs +66 -0
- package/dist/services/definitions/axolotl.mjs.map +1 -0
- package/dist/services/definitions/beszel.cjs +2 -3
- package/dist/services/definitions/beszel.cjs.map +1 -1
- package/dist/services/definitions/beszel.mjs +1 -1
- package/dist/services/definitions/browserless.cjs +2 -3
- package/dist/services/definitions/browserless.cjs.map +1 -1
- package/dist/services/definitions/browserless.mjs +1 -1
- package/dist/services/definitions/caddy.cjs +2 -3
- package/dist/services/definitions/caddy.cjs.map +1 -1
- package/dist/services/definitions/caddy.mjs +1 -1
- package/dist/services/definitions/cal-com.cjs +2 -3
- package/dist/services/definitions/cal-com.cjs.map +1 -1
- package/dist/services/definitions/cal-com.mjs +1 -1
- package/dist/services/definitions/chatwoot-worker.cjs +95 -0
- package/dist/services/definitions/chatwoot-worker.cjs.map +1 -0
- package/dist/services/definitions/chatwoot-worker.d.cts +7 -0
- package/dist/services/definitions/chatwoot-worker.d.cts.map +1 -0
- package/dist/services/definitions/chatwoot-worker.d.mts +7 -0
- package/dist/services/definitions/chatwoot-worker.d.mts.map +1 -0
- package/dist/services/definitions/chatwoot-worker.mjs +94 -0
- package/dist/services/definitions/chatwoot-worker.mjs.map +1 -0
- package/dist/services/definitions/chatwoot.cjs +112 -0
- package/dist/services/definitions/chatwoot.cjs.map +1 -0
- package/dist/services/definitions/chatwoot.d.cts +7 -0
- package/dist/services/definitions/chatwoot.d.cts.map +1 -0
- package/dist/services/definitions/chatwoot.d.mts +7 -0
- package/dist/services/definitions/chatwoot.d.mts.map +1 -0
- package/dist/services/definitions/chatwoot.mjs +111 -0
- package/dist/services/definitions/chatwoot.mjs.map +1 -0
- package/dist/services/definitions/chromadb.cjs +2 -3
- package/dist/services/definitions/chromadb.cjs.map +1 -1
- package/dist/services/definitions/chromadb.mjs +1 -1
- package/dist/services/definitions/claude-code.cjs +2 -3
- package/dist/services/definitions/claude-code.cjs.map +1 -1
- package/dist/services/definitions/claude-code.mjs +1 -1
- package/dist/services/definitions/code-server.cjs +2 -3
- package/dist/services/definitions/code-server.cjs.map +1 -1
- package/dist/services/definitions/code-server.mjs +1 -1
- package/dist/services/definitions/codex.cjs +2 -3
- package/dist/services/definitions/codex.cjs.map +1 -1
- package/dist/services/definitions/codex.mjs +1 -1
- package/dist/services/definitions/comfyui.cjs +2 -3
- package/dist/services/definitions/comfyui.cjs.map +1 -1
- package/dist/services/definitions/comfyui.mjs +1 -1
- package/dist/services/definitions/convex-dashboard.cjs +2 -3
- package/dist/services/definitions/convex-dashboard.cjs.map +1 -1
- package/dist/services/definitions/convex-dashboard.mjs +1 -1
- package/dist/services/definitions/convex.cjs +2 -3
- package/dist/services/definitions/convex.cjs.map +1 -1
- package/dist/services/definitions/convex.mjs +1 -1
- package/dist/services/definitions/coolify.cjs +2 -3
- package/dist/services/definitions/coolify.cjs.map +1 -1
- package/dist/services/definitions/coolify.mjs +1 -1
- package/dist/services/definitions/crowdsec.cjs +2 -3
- package/dist/services/definitions/crowdsec.cjs.map +1 -1
- package/dist/services/definitions/crowdsec.mjs +1 -1
- package/dist/services/definitions/dagster.cjs +83 -0
- package/dist/services/definitions/dagster.cjs.map +1 -0
- package/dist/services/definitions/dagster.d.cts +7 -0
- package/dist/services/definitions/dagster.d.cts.map +1 -0
- package/dist/services/definitions/dagster.d.mts +7 -0
- package/dist/services/definitions/dagster.d.mts.map +1 -0
- package/dist/services/definitions/dagster.mjs +82 -0
- package/dist/services/definitions/dagster.mjs.map +1 -0
- package/dist/services/definitions/desktop-environment.cjs +2 -3
- package/dist/services/definitions/desktop-environment.cjs.map +1 -1
- package/dist/services/definitions/desktop-environment.mjs +1 -1
- package/dist/services/definitions/dify.cjs +2 -3
- package/dist/services/definitions/dify.cjs.map +1 -1
- package/dist/services/definitions/dify.mjs +1 -1
- package/dist/services/definitions/directus.cjs +115 -0
- package/dist/services/definitions/directus.cjs.map +1 -0
- package/dist/services/definitions/directus.d.cts +7 -0
- package/dist/services/definitions/directus.d.cts.map +1 -0
- package/dist/services/definitions/directus.d.mts +7 -0
- package/dist/services/definitions/directus.d.mts.map +1 -0
- package/dist/services/definitions/directus.mjs +114 -0
- package/dist/services/definitions/directus.mjs.map +1 -0
- package/dist/services/definitions/docsgpt.cjs +2 -3
- package/dist/services/definitions/docsgpt.cjs.map +1 -1
- package/dist/services/definitions/docsgpt.mjs +1 -1
- package/dist/services/definitions/dokploy.cjs +2 -3
- package/dist/services/definitions/dokploy.cjs.map +1 -1
- package/dist/services/definitions/dokploy.mjs +1 -1
- package/dist/services/definitions/dozzle.cjs +2 -3
- package/dist/services/definitions/dozzle.cjs.map +1 -1
- package/dist/services/definitions/dozzle.mjs +1 -1
- package/dist/services/definitions/duplicati.cjs +76 -0
- package/dist/services/definitions/duplicati.cjs.map +1 -0
- package/dist/services/definitions/duplicati.d.cts +7 -0
- package/dist/services/definitions/duplicati.d.cts.map +1 -0
- package/dist/services/definitions/duplicati.d.mts +7 -0
- package/dist/services/definitions/duplicati.d.mts.map +1 -0
- package/dist/services/definitions/duplicati.mjs +75 -0
- package/dist/services/definitions/duplicati.mjs.map +1 -0
- package/dist/services/definitions/excalidraw.cjs +48 -0
- package/dist/services/definitions/excalidraw.cjs.map +1 -0
- package/dist/services/definitions/excalidraw.d.cts +7 -0
- package/dist/services/definitions/excalidraw.d.cts.map +1 -0
- package/dist/services/definitions/excalidraw.d.mts +7 -0
- package/dist/services/definitions/excalidraw.d.mts.map +1 -0
- package/dist/services/definitions/excalidraw.mjs +47 -0
- package/dist/services/definitions/excalidraw.mjs.map +1 -0
- package/dist/services/definitions/ffmpeg.cjs +2 -3
- package/dist/services/definitions/ffmpeg.cjs.map +1 -1
- package/dist/services/definitions/ffmpeg.mjs +1 -1
- package/dist/services/definitions/firecrawl-playwright.cjs +61 -0
- package/dist/services/definitions/firecrawl-playwright.cjs.map +1 -0
- package/dist/services/definitions/firecrawl-playwright.d.cts +7 -0
- package/dist/services/definitions/firecrawl-playwright.d.cts.map +1 -0
- package/dist/services/definitions/firecrawl-playwright.d.mts +7 -0
- package/dist/services/definitions/firecrawl-playwright.d.mts.map +1 -0
- package/dist/services/definitions/firecrawl-playwright.mjs +60 -0
- package/dist/services/definitions/firecrawl-playwright.mjs.map +1 -0
- package/dist/services/definitions/firecrawl.cjs +163 -0
- package/dist/services/definitions/firecrawl.cjs.map +1 -0
- package/dist/services/definitions/firecrawl.d.cts +7 -0
- package/dist/services/definitions/firecrawl.d.cts.map +1 -0
- package/dist/services/definitions/firecrawl.d.mts +7 -0
- package/dist/services/definitions/firecrawl.d.mts.map +1 -0
- package/dist/services/definitions/firecrawl.mjs +162 -0
- package/dist/services/definitions/firecrawl.mjs.map +1 -0
- package/dist/services/definitions/flagsmith.cjs +77 -0
- package/dist/services/definitions/flagsmith.cjs.map +1 -0
- package/dist/services/definitions/flagsmith.d.cts +7 -0
- package/dist/services/definitions/flagsmith.d.cts.map +1 -0
- package/dist/services/definitions/flagsmith.d.mts +7 -0
- package/dist/services/definitions/flagsmith.d.mts.map +1 -0
- package/dist/services/definitions/flagsmith.mjs +76 -0
- package/dist/services/definitions/flagsmith.mjs.map +1 -0
- package/dist/services/definitions/flowise.cjs +2 -3
- package/dist/services/definitions/flowise.cjs.map +1 -1
- package/dist/services/definitions/flowise.mjs +1 -1
- package/dist/services/definitions/fonoster.cjs +66 -0
- package/dist/services/definitions/fonoster.cjs.map +1 -0
- package/dist/services/definitions/fonoster.d.cts +7 -0
- package/dist/services/definitions/fonoster.d.cts.map +1 -0
- package/dist/services/definitions/fonoster.d.mts +7 -0
- package/dist/services/definitions/fonoster.d.mts.map +1 -0
- package/dist/services/definitions/fonoster.mjs +65 -0
- package/dist/services/definitions/fonoster.mjs.map +1 -0
- package/dist/services/definitions/formbricks.cjs +75 -0
- package/dist/services/definitions/formbricks.cjs.map +1 -0
- package/dist/services/definitions/formbricks.d.cts +7 -0
- package/dist/services/definitions/formbricks.d.cts.map +1 -0
- package/dist/services/definitions/formbricks.d.mts +7 -0
- package/dist/services/definitions/formbricks.d.mts.map +1 -0
- package/dist/services/definitions/formbricks.mjs +74 -0
- package/dist/services/definitions/formbricks.mjs.map +1 -0
- package/dist/services/definitions/gemini-cli.cjs +2 -3
- package/dist/services/definitions/gemini-cli.cjs.map +1 -1
- package/dist/services/definitions/gemini-cli.mjs +1 -1
- package/dist/services/definitions/ghost.cjs +2 -3
- package/dist/services/definitions/ghost.cjs.map +1 -1
- package/dist/services/definitions/ghost.mjs +1 -1
- package/dist/services/definitions/gitea.cjs +2 -3
- package/dist/services/definitions/gitea.cjs.map +1 -1
- package/dist/services/definitions/gitea.mjs +1 -1
- package/dist/services/definitions/gotify.cjs +2 -3
- package/dist/services/definitions/gotify.cjs.map +1 -1
- package/dist/services/definitions/gotify.mjs +1 -1
- package/dist/services/definitions/grafana.cjs +2 -3
- package/dist/services/definitions/grafana.cjs.map +1 -1
- package/dist/services/definitions/grafana.mjs +1 -1
- package/dist/services/definitions/headscale.cjs +2 -3
- package/dist/services/definitions/headscale.cjs.map +1 -1
- package/dist/services/definitions/headscale.mjs +1 -1
- package/dist/services/definitions/hedgedoc.cjs +82 -0
- package/dist/services/definitions/hedgedoc.cjs.map +1 -0
- package/dist/services/definitions/hedgedoc.d.cts +7 -0
- package/dist/services/definitions/hedgedoc.d.cts.map +1 -0
- package/dist/services/definitions/hedgedoc.d.mts +7 -0
- package/dist/services/definitions/hedgedoc.d.mts.map +1 -0
- package/dist/services/definitions/hedgedoc.mjs +81 -0
- package/dist/services/definitions/hedgedoc.mjs.map +1 -0
- package/dist/services/definitions/hexstrike.cjs +2 -3
- package/dist/services/definitions/hexstrike.cjs.map +1 -1
- package/dist/services/definitions/hexstrike.mjs +1 -1
- package/dist/services/definitions/heyform.cjs +64 -0
- package/dist/services/definitions/heyform.cjs.map +1 -0
- package/dist/services/definitions/heyform.d.cts +7 -0
- package/dist/services/definitions/heyform.d.cts.map +1 -0
- package/dist/services/definitions/heyform.d.mts +7 -0
- package/dist/services/definitions/heyform.d.mts.map +1 -0
- package/dist/services/definitions/heyform.mjs +63 -0
- package/dist/services/definitions/heyform.mjs.map +1 -0
- package/dist/services/definitions/homeassistant.cjs +2 -3
- package/dist/services/definitions/homeassistant.cjs.map +1 -1
- package/dist/services/definitions/homeassistant.mjs +1 -1
- package/dist/services/definitions/hoppscotch.cjs +76 -0
- package/dist/services/definitions/hoppscotch.cjs.map +1 -0
- package/dist/services/definitions/hoppscotch.d.cts +7 -0
- package/dist/services/definitions/hoppscotch.d.cts.map +1 -0
- package/dist/services/definitions/hoppscotch.d.mts +7 -0
- package/dist/services/definitions/hoppscotch.d.mts.map +1 -0
- package/dist/services/definitions/hoppscotch.mjs +75 -0
- package/dist/services/definitions/hoppscotch.mjs.map +1 -0
- package/dist/services/definitions/immich.cjs +2 -3
- package/dist/services/definitions/immich.cjs.map +1 -1
- package/dist/services/definitions/immich.mjs +1 -1
- package/dist/services/definitions/index.cjs +220 -98
- package/dist/services/definitions/index.cjs.map +1 -1
- package/dist/services/definitions/index.d.cts +42 -1
- package/dist/services/definitions/index.d.cts.map +1 -1
- package/dist/services/definitions/index.d.mts +42 -1
- package/dist/services/definitions/index.d.mts.map +1 -1
- package/dist/services/definitions/index.mjs +85 -4
- package/dist/services/definitions/index.mjs.map +1 -1
- package/dist/services/definitions/infisical.cjs +99 -0
- package/dist/services/definitions/infisical.cjs.map +1 -0
- package/dist/services/definitions/infisical.d.cts +7 -0
- package/dist/services/definitions/infisical.d.cts.map +1 -0
- package/dist/services/definitions/infisical.d.mts +7 -0
- package/dist/services/definitions/infisical.d.mts.map +1 -0
- package/dist/services/definitions/infisical.mjs +98 -0
- package/dist/services/definitions/infisical.mjs.map +1 -0
- package/dist/services/definitions/jellyfin.cjs +2 -3
- package/dist/services/definitions/jellyfin.cjs.map +1 -1
- package/dist/services/definitions/jellyfin.mjs +1 -1
- package/dist/services/definitions/jenkins.cjs +2 -3
- package/dist/services/definitions/jenkins.cjs.map +1 -1
- package/dist/services/definitions/jenkins.mjs +1 -1
- package/dist/services/definitions/keycloak.cjs +122 -0
- package/dist/services/definitions/keycloak.cjs.map +1 -0
- package/dist/services/definitions/keycloak.d.cts +7 -0
- package/dist/services/definitions/keycloak.d.cts.map +1 -0
- package/dist/services/definitions/keycloak.d.mts +7 -0
- package/dist/services/definitions/keycloak.d.mts.map +1 -0
- package/dist/services/definitions/keycloak.mjs +121 -0
- package/dist/services/definitions/keycloak.mjs.map +1 -0
- package/dist/services/definitions/kimi.cjs +2 -3
- package/dist/services/definitions/kimi.cjs.map +1 -1
- package/dist/services/definitions/kimi.mjs +1 -1
- package/dist/services/definitions/kong.cjs +121 -0
- package/dist/services/definitions/kong.cjs.map +1 -0
- package/dist/services/definitions/kong.d.cts +7 -0
- package/dist/services/definitions/kong.d.cts.map +1 -0
- package/dist/services/definitions/kong.d.mts +7 -0
- package/dist/services/definitions/kong.d.mts.map +1 -0
- package/dist/services/definitions/kong.mjs +120 -0
- package/dist/services/definitions/kong.mjs.map +1 -0
- package/dist/services/definitions/lago.cjs +95 -0
- package/dist/services/definitions/lago.cjs.map +1 -0
- package/dist/services/definitions/lago.d.cts +7 -0
- package/dist/services/definitions/lago.d.cts.map +1 -0
- package/dist/services/definitions/lago.d.mts +7 -0
- package/dist/services/definitions/lago.d.mts.map +1 -0
- package/dist/services/definitions/lago.mjs +94 -0
- package/dist/services/definitions/lago.mjs.map +1 -0
- package/dist/services/definitions/langflow.cjs +88 -0
- package/dist/services/definitions/langflow.cjs.map +1 -0
- package/dist/services/definitions/langflow.d.cts +7 -0
- package/dist/services/definitions/langflow.d.cts.map +1 -0
- package/dist/services/definitions/langflow.d.mts +7 -0
- package/dist/services/definitions/langflow.d.mts.map +1 -0
- package/dist/services/definitions/langflow.mjs +87 -0
- package/dist/services/definitions/langflow.mjs.map +1 -0
- package/dist/services/definitions/langfuse.cjs +79 -0
- package/dist/services/definitions/langfuse.cjs.map +1 -0
- package/dist/services/definitions/langfuse.d.cts +7 -0
- package/dist/services/definitions/langfuse.d.cts.map +1 -0
- package/dist/services/definitions/langfuse.d.mts +7 -0
- package/dist/services/definitions/langfuse.d.mts.map +1 -0
- package/dist/services/definitions/langfuse.mjs +78 -0
- package/dist/services/definitions/langfuse.mjs.map +1 -0
- package/dist/services/definitions/lasuite-meet-agents.cjs +2 -3
- package/dist/services/definitions/lasuite-meet-agents.cjs.map +1 -1
- package/dist/services/definitions/lasuite-meet-agents.mjs +1 -1
- package/dist/services/definitions/lasuite-meet-backend.cjs +2 -3
- package/dist/services/definitions/lasuite-meet-backend.cjs.map +1 -1
- package/dist/services/definitions/lasuite-meet-backend.mjs +1 -1
- package/dist/services/definitions/lasuite-meet-frontend.cjs +2 -3
- package/dist/services/definitions/lasuite-meet-frontend.cjs.map +1 -1
- package/dist/services/definitions/lasuite-meet-frontend.mjs +1 -1
- package/dist/services/definitions/librechat.cjs +2 -3
- package/dist/services/definitions/librechat.cjs.map +1 -1
- package/dist/services/definitions/librechat.mjs +1 -1
- package/dist/services/definitions/lightpanda.cjs +2 -3
- package/dist/services/definitions/lightpanda.cjs.map +1 -1
- package/dist/services/definitions/lightpanda.mjs +1 -1
- package/dist/services/definitions/listmonk.cjs +118 -0
- package/dist/services/definitions/listmonk.cjs.map +1 -0
- package/dist/services/definitions/listmonk.d.cts +7 -0
- package/dist/services/definitions/listmonk.d.cts.map +1 -0
- package/dist/services/definitions/listmonk.d.mts +7 -0
- package/dist/services/definitions/listmonk.d.mts.map +1 -0
- package/dist/services/definitions/listmonk.mjs +117 -0
- package/dist/services/definitions/listmonk.mjs.map +1 -0
- package/dist/services/definitions/litellm.cjs +2 -3
- package/dist/services/definitions/litellm.cjs.map +1 -1
- package/dist/services/definitions/litellm.mjs +1 -1
- package/dist/services/definitions/livekit.cjs +2 -3
- package/dist/services/definitions/livekit.cjs.map +1 -1
- package/dist/services/definitions/livekit.mjs +1 -1
- package/dist/services/definitions/loki.cjs +2 -3
- package/dist/services/definitions/loki.cjs.map +1 -1
- package/dist/services/definitions/loki.mjs +1 -1
- package/dist/services/definitions/mariadb.cjs +81 -0
- package/dist/services/definitions/mariadb.cjs.map +1 -0
- package/dist/services/definitions/mariadb.d.cts +7 -0
- package/dist/services/definitions/mariadb.d.cts.map +1 -0
- package/dist/services/definitions/mariadb.d.mts +7 -0
- package/dist/services/definitions/mariadb.d.mts.map +1 -0
- package/dist/services/definitions/mariadb.mjs +80 -0
- package/dist/services/definitions/mariadb.mjs.map +1 -0
- package/dist/services/definitions/matomo.cjs +2 -3
- package/dist/services/definitions/matomo.cjs.map +1 -1
- package/dist/services/definitions/matomo.mjs +1 -1
- package/dist/services/definitions/matrix-synapse.cjs +2 -3
- package/dist/services/definitions/matrix-synapse.cjs.map +1 -1
- package/dist/services/definitions/matrix-synapse.mjs +1 -1
- package/dist/services/definitions/mattermost.cjs +2 -3
- package/dist/services/definitions/mattermost.cjs.map +1 -1
- package/dist/services/definitions/mattermost.mjs +1 -1
- package/dist/services/definitions/mautic.cjs +83 -0
- package/dist/services/definitions/mautic.cjs.map +1 -0
- package/dist/services/definitions/mautic.d.cts +7 -0
- package/dist/services/definitions/mautic.d.cts.map +1 -0
- package/dist/services/definitions/mautic.d.mts +7 -0
- package/dist/services/definitions/mautic.d.mts.map +1 -0
- package/dist/services/definitions/mautic.mjs +82 -0
- package/dist/services/definitions/mautic.mjs.map +1 -0
- package/dist/services/definitions/medusa.cjs +83 -0
- package/dist/services/definitions/medusa.cjs.map +1 -0
- package/dist/services/definitions/medusa.d.cts +7 -0
- package/dist/services/definitions/medusa.d.cts.map +1 -0
- package/dist/services/definitions/medusa.d.mts +7 -0
- package/dist/services/definitions/medusa.d.mts.map +1 -0
- package/dist/services/definitions/medusa.mjs +82 -0
- package/dist/services/definitions/medusa.mjs.map +1 -0
- package/dist/services/definitions/meilisearch.cjs +2 -3
- package/dist/services/definitions/meilisearch.cjs.map +1 -1
- package/dist/services/definitions/meilisearch.mjs +1 -1
- package/dist/services/definitions/milvus.cjs +2 -3
- package/dist/services/definitions/milvus.cjs.map +1 -1
- package/dist/services/definitions/milvus.mjs +1 -1
- package/dist/services/definitions/minio.cjs +2 -3
- package/dist/services/definitions/minio.cjs.map +1 -1
- package/dist/services/definitions/minio.mjs +1 -1
- package/dist/services/definitions/mission-control.cjs +2 -3
- package/dist/services/definitions/mission-control.cjs.map +1 -1
- package/dist/services/definitions/mission-control.mjs +1 -1
- package/dist/services/definitions/mixpost.cjs +2 -3
- package/dist/services/definitions/mixpost.cjs.map +1 -1
- package/dist/services/definitions/mixpost.mjs +1 -1
- package/dist/services/definitions/motion-canvas.cjs +2 -3
- package/dist/services/definitions/motion-canvas.cjs.map +1 -1
- package/dist/services/definitions/motion-canvas.mjs +1 -1
- package/dist/services/definitions/mysql.cjs +81 -0
- package/dist/services/definitions/mysql.cjs.map +1 -0
- package/dist/services/definitions/mysql.d.cts +7 -0
- package/dist/services/definitions/mysql.d.cts.map +1 -0
- package/dist/services/definitions/mysql.d.mts +7 -0
- package/dist/services/definitions/mysql.d.mts.map +1 -0
- package/dist/services/definitions/mysql.mjs +80 -0
- package/dist/services/definitions/mysql.mjs.map +1 -0
- package/dist/services/definitions/n8n.cjs +2 -3
- package/dist/services/definitions/n8n.cjs.map +1 -1
- package/dist/services/definitions/n8n.mjs +1 -1
- package/dist/services/definitions/neo4j.cjs +2 -3
- package/dist/services/definitions/neo4j.cjs.map +1 -1
- package/dist/services/definitions/neo4j.mjs +1 -1
- package/dist/services/definitions/nextcloud.cjs +2 -3
- package/dist/services/definitions/nextcloud.cjs.map +1 -1
- package/dist/services/definitions/nextcloud.mjs +1 -1
- package/dist/services/definitions/nocodb.cjs +2 -3
- package/dist/services/definitions/nocodb.cjs.map +1 -1
- package/dist/services/definitions/nocodb.mjs +1 -1
- package/dist/services/definitions/ntfy.cjs +2 -3
- package/dist/services/definitions/ntfy.cjs.map +1 -1
- package/dist/services/definitions/ntfy.mjs +1 -1
- package/dist/services/definitions/ollama.cjs +2 -3
- package/dist/services/definitions/ollama.cjs.map +1 -1
- package/dist/services/definitions/ollama.mjs +1 -1
- package/dist/services/definitions/open-webui.cjs +2 -3
- package/dist/services/definitions/open-webui.cjs.map +1 -1
- package/dist/services/definitions/open-webui.mjs +1 -1
- package/dist/services/definitions/opencode.cjs +2 -3
- package/dist/services/definitions/opencode.cjs.map +1 -1
- package/dist/services/definitions/opencode.mjs +1 -1
- package/dist/services/definitions/openhands.cjs +58 -0
- package/dist/services/definitions/openhands.cjs.map +1 -0
- package/dist/services/definitions/openhands.d.cts +7 -0
- package/dist/services/definitions/openhands.d.cts.map +1 -0
- package/dist/services/definitions/openhands.d.mts +7 -0
- package/dist/services/definitions/openhands.d.mts.map +1 -0
- package/dist/services/definitions/openhands.mjs +57 -0
- package/dist/services/definitions/openhands.mjs.map +1 -0
- package/dist/services/definitions/openpanel.cjs +2 -3
- package/dist/services/definitions/openpanel.cjs.map +1 -1
- package/dist/services/definitions/openpanel.mjs +1 -1
- package/dist/services/definitions/opensearch.cjs +94 -0
- package/dist/services/definitions/opensearch.cjs.map +1 -0
- package/dist/services/definitions/opensearch.d.cts +7 -0
- package/dist/services/definitions/opensearch.d.cts.map +1 -0
- package/dist/services/definitions/opensearch.d.mts +7 -0
- package/dist/services/definitions/opensearch.d.mts.map +1 -0
- package/dist/services/definitions/opensearch.mjs +93 -0
- package/dist/services/definitions/opensearch.mjs.map +1 -0
- package/dist/services/definitions/outline.cjs +2 -3
- package/dist/services/definitions/outline.cjs.map +1 -1
- package/dist/services/definitions/outline.mjs +1 -1
- package/dist/services/definitions/paperless-ngx.cjs +2 -3
- package/dist/services/definitions/paperless-ngx.cjs.map +1 -1
- package/dist/services/definitions/paperless-ngx.mjs +1 -1
- package/dist/services/definitions/pentagi.cjs +2 -3
- package/dist/services/definitions/pentagi.cjs.map +1 -1
- package/dist/services/definitions/pentagi.mjs +1 -1
- package/dist/services/definitions/pentestagent.cjs +2 -3
- package/dist/services/definitions/pentestagent.cjs.map +1 -1
- package/dist/services/definitions/pentestagent.mjs +1 -1
- package/dist/services/definitions/playwright-server.cjs +2 -3
- package/dist/services/definitions/playwright-server.cjs.map +1 -1
- package/dist/services/definitions/playwright-server.mjs +1 -1
- package/dist/services/definitions/pocketbase.cjs +61 -0
- package/dist/services/definitions/pocketbase.cjs.map +1 -0
- package/dist/services/definitions/pocketbase.d.cts +7 -0
- package/dist/services/definitions/pocketbase.d.cts.map +1 -0
- package/dist/services/definitions/pocketbase.d.mts +7 -0
- package/dist/services/definitions/pocketbase.d.mts.map +1 -0
- package/dist/services/definitions/pocketbase.mjs +60 -0
- package/dist/services/definitions/pocketbase.mjs.map +1 -0
- package/dist/services/definitions/portainer.cjs +2 -3
- package/dist/services/definitions/portainer.cjs.map +1 -1
- package/dist/services/definitions/portainer.mjs +1 -1
- package/dist/services/definitions/postgresql.cjs +2 -3
- package/dist/services/definitions/postgresql.cjs.map +1 -1
- package/dist/services/definitions/postgresql.mjs +1 -1
- package/dist/services/definitions/postiz.cjs +2 -3
- package/dist/services/definitions/postiz.cjs.map +1 -1
- package/dist/services/definitions/postiz.mjs +1 -1
- package/dist/services/definitions/prometheus.cjs +2 -3
- package/dist/services/definitions/prometheus.cjs.map +1 -1
- package/dist/services/definitions/prometheus.mjs +1 -1
- package/dist/services/definitions/qdrant.cjs +2 -3
- package/dist/services/definitions/qdrant.cjs.map +1 -1
- package/dist/services/definitions/qdrant.mjs +1 -1
- package/dist/services/definitions/rabbitmq.cjs +80 -0
- package/dist/services/definitions/rabbitmq.cjs.map +1 -0
- package/dist/services/definitions/rabbitmq.d.cts +7 -0
- package/dist/services/definitions/rabbitmq.d.cts.map +1 -0
- package/dist/services/definitions/rabbitmq.d.mts +7 -0
- package/dist/services/definitions/rabbitmq.d.mts.map +1 -0
- package/dist/services/definitions/rabbitmq.mjs +79 -0
- package/dist/services/definitions/rabbitmq.mjs.map +1 -0
- package/dist/services/definitions/ragflow.cjs +192 -0
- package/dist/services/definitions/ragflow.cjs.map +1 -0
- package/dist/services/definitions/ragflow.d.cts +7 -0
- package/dist/services/definitions/ragflow.d.cts.map +1 -0
- package/dist/services/definitions/ragflow.d.mts +7 -0
- package/dist/services/definitions/ragflow.d.mts.map +1 -0
- package/dist/services/definitions/ragflow.mjs +191 -0
- package/dist/services/definitions/ragflow.mjs.map +1 -0
- package/dist/services/definitions/redis.cjs +2 -3
- package/dist/services/definitions/redis.cjs.map +1 -1
- package/dist/services/definitions/redis.mjs +1 -1
- package/dist/services/definitions/remotion.cjs +2 -3
- package/dist/services/definitions/remotion.cjs.map +1 -1
- package/dist/services/definitions/remotion.mjs +1 -1
- package/dist/services/definitions/restic.cjs +58 -0
- package/dist/services/definitions/restic.cjs.map +1 -0
- package/dist/services/definitions/restic.d.cts +7 -0
- package/dist/services/definitions/restic.d.cts.map +1 -0
- package/dist/services/definitions/restic.d.mts +7 -0
- package/dist/services/definitions/restic.d.mts.map +1 -0
- package/dist/services/definitions/restic.mjs +57 -0
- package/dist/services/definitions/restic.mjs.map +1 -0
- package/dist/services/definitions/rocketchat.cjs +2 -3
- package/dist/services/definitions/rocketchat.cjs.map +1 -1
- package/dist/services/definitions/rocketchat.mjs +1 -1
- package/dist/services/definitions/saleor.cjs +76 -0
- package/dist/services/definitions/saleor.cjs.map +1 -0
- package/dist/services/definitions/saleor.d.cts +7 -0
- package/dist/services/definitions/saleor.d.cts.map +1 -0
- package/dist/services/definitions/saleor.d.mts +7 -0
- package/dist/services/definitions/saleor.d.mts.map +1 -0
- package/dist/services/definitions/saleor.mjs +75 -0
- package/dist/services/definitions/saleor.mjs.map +1 -0
- package/dist/services/definitions/scrapling.cjs +2 -3
- package/dist/services/definitions/scrapling.cjs.map +1 -1
- package/dist/services/definitions/scrapling.mjs +1 -1
- package/dist/services/definitions/searxng.cjs +2 -3
- package/dist/services/definitions/searxng.cjs.map +1 -1
- package/dist/services/definitions/searxng.mjs +1 -1
- package/dist/services/definitions/signoz.cjs +2 -3
- package/dist/services/definitions/signoz.cjs.map +1 -1
- package/dist/services/definitions/signoz.mjs +1 -1
- package/dist/services/definitions/solidityguard.cjs +2 -3
- package/dist/services/definitions/solidityguard.cjs.map +1 -1
- package/dist/services/definitions/solidityguard.mjs +1 -1
- package/dist/services/definitions/stable-diffusion.cjs +2 -3
- package/dist/services/definitions/stable-diffusion.cjs.map +1 -1
- package/dist/services/definitions/stable-diffusion.mjs +1 -1
- package/dist/services/definitions/steel-browser.cjs +2 -3
- package/dist/services/definitions/steel-browser.cjs.map +1 -1
- package/dist/services/definitions/steel-browser.mjs +1 -1
- package/dist/services/definitions/stirling-pdf.cjs +74 -0
- package/dist/services/definitions/stirling-pdf.cjs.map +1 -0
- package/dist/services/definitions/stirling-pdf.d.cts +7 -0
- package/dist/services/definitions/stirling-pdf.d.cts.map +1 -0
- package/dist/services/definitions/stirling-pdf.d.mts +7 -0
- package/dist/services/definitions/stirling-pdf.d.mts.map +1 -0
- package/dist/services/definitions/stirling-pdf.mjs +73 -0
- package/dist/services/definitions/stirling-pdf.mjs.map +1 -0
- package/dist/services/definitions/strapi.cjs +124 -0
- package/dist/services/definitions/strapi.cjs.map +1 -0
- package/dist/services/definitions/strapi.d.cts +7 -0
- package/dist/services/definitions/strapi.d.cts.map +1 -0
- package/dist/services/definitions/strapi.d.mts +7 -0
- package/dist/services/definitions/strapi.d.mts.map +1 -0
- package/dist/services/definitions/strapi.mjs +123 -0
- package/dist/services/definitions/strapi.mjs.map +1 -0
- package/dist/services/definitions/stream-gateway.cjs +2 -3
- package/dist/services/definitions/stream-gateway.cjs.map +1 -1
- package/dist/services/definitions/stream-gateway.mjs +1 -1
- package/dist/services/definitions/supabase.cjs +2 -3
- package/dist/services/definitions/supabase.cjs.map +1 -1
- package/dist/services/definitions/supabase.mjs +1 -1
- package/dist/services/definitions/tailscale.cjs +2 -3
- package/dist/services/definitions/tailscale.cjs.map +1 -1
- package/dist/services/definitions/tailscale.mjs +1 -1
- package/dist/services/definitions/temporal.cjs +2 -3
- package/dist/services/definitions/temporal.cjs.map +1 -1
- package/dist/services/definitions/temporal.mjs +1 -1
- package/dist/services/definitions/traefik.cjs +2 -3
- package/dist/services/definitions/traefik.cjs.map +1 -1
- package/dist/services/definitions/traefik.mjs +1 -1
- package/dist/services/definitions/twenty.cjs +83 -0
- package/dist/services/definitions/twenty.cjs.map +1 -0
- package/dist/services/definitions/twenty.d.cts +7 -0
- package/dist/services/definitions/twenty.d.cts.map +1 -0
- package/dist/services/definitions/twenty.d.mts +7 -0
- package/dist/services/definitions/twenty.d.mts.map +1 -0
- package/dist/services/definitions/twenty.mjs +82 -0
- package/dist/services/definitions/twenty.mjs.map +1 -0
- package/dist/services/definitions/umami.cjs +2 -3
- package/dist/services/definitions/umami.cjs.map +1 -1
- package/dist/services/definitions/umami.mjs +1 -1
- package/dist/services/definitions/uptime-kuma.cjs +2 -3
- package/dist/services/definitions/uptime-kuma.cjs.map +1 -1
- package/dist/services/definitions/uptime-kuma.mjs +1 -1
- package/dist/services/definitions/usesend.cjs +2 -3
- package/dist/services/definitions/usesend.cjs.map +1 -1
- package/dist/services/definitions/usesend.mjs +1 -1
- package/dist/services/definitions/valkey.cjs +2 -3
- package/dist/services/definitions/valkey.cjs.map +1 -1
- package/dist/services/definitions/valkey.mjs +1 -1
- package/dist/services/definitions/vault.cjs +71 -0
- package/dist/services/definitions/vault.cjs.map +1 -0
- package/dist/services/definitions/vault.d.cts +7 -0
- package/dist/services/definitions/vault.d.cts.map +1 -0
- package/dist/services/definitions/vault.d.mts +7 -0
- package/dist/services/definitions/vault.d.mts.map +1 -0
- package/dist/services/definitions/vault.mjs +70 -0
- package/dist/services/definitions/vault.mjs.map +1 -0
- package/dist/services/definitions/vaultwarden.cjs +2 -3
- package/dist/services/definitions/vaultwarden.cjs.map +1 -1
- package/dist/services/definitions/vaultwarden.mjs +1 -1
- package/dist/services/definitions/watchtower.cjs +2 -3
- package/dist/services/definitions/watchtower.cjs.map +1 -1
- package/dist/services/definitions/watchtower.mjs +1 -1
- package/dist/services/definitions/weaviate.cjs +2 -3
- package/dist/services/definitions/weaviate.cjs.map +1 -1
- package/dist/services/definitions/weaviate.mjs +1 -1
- package/dist/services/definitions/whisper.cjs +2 -3
- package/dist/services/definitions/whisper.cjs.map +1 -1
- package/dist/services/definitions/whisper.mjs +1 -1
- package/dist/services/definitions/xyops.cjs +2 -3
- package/dist/services/definitions/xyops.cjs.map +1 -1
- package/dist/services/definitions/xyops.mjs +1 -1
- package/dist/services/registry.cjs +3 -4
- package/dist/services/registry.cjs.map +1 -1
- package/dist/services/registry.d.mts.map +1 -1
- package/dist/services/registry.mjs +1 -2
- package/dist/services/registry.mjs.map +1 -1
- package/dist/services/registry.test.cjs +3 -4
- package/dist/services/registry.test.cjs.map +1 -1
- package/dist/services/registry.test.mjs +3 -4
- package/dist/services/registry.test.mjs.map +1 -1
- package/dist/{manifest-4uLbISXV.cjs → skill-manifest--IgY9REK.cjs} +40 -10
- package/dist/skill-manifest--IgY9REK.cjs.map +1 -0
- package/dist/{manifest-B8UDsVlR.mjs → skill-manifest-BVUXU0__.mjs} +24 -5
- package/dist/skill-manifest-BVUXU0__.mjs.map +1 -0
- package/dist/skills/registry.cjs +262 -3
- package/dist/skills/registry.cjs.map +1 -1
- package/dist/skills/registry.d.cts.map +1 -1
- package/dist/skills/registry.d.mts.map +1 -1
- package/dist/skills/registry.mjs +261 -1
- package/dist/skills/registry.mjs.map +1 -1
- package/dist/skills/skill-manifest.cjs +5 -23
- package/dist/skills/skill-manifest.mjs +1 -19
- package/dist/skills-BlzpHmpH.cjs +620 -0
- package/dist/skills-BlzpHmpH.cjs.map +1 -0
- package/dist/types-CR83OJiq.d.cts +243 -0
- package/dist/types-CR83OJiq.d.cts.map +1 -0
- package/dist/types-zYjGTuyn.d.mts +243 -0
- package/dist/types-zYjGTuyn.d.mts.map +1 -0
- package/dist/types.cjs +79 -3
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +1 -1
- package/dist/types.d.mts +1 -1
- package/dist/types.mjs +78 -1
- package/dist/types.mjs.map +1 -1
- package/dist/validator.cjs +3 -4
- package/dist/validator.cjs.map +1 -1
- package/dist/validator.mjs +1 -2
- package/dist/validator.mjs.map +1 -1
- package/dist/validator.test.cjs +5 -6
- package/dist/validator.test.cjs.map +1 -1
- package/dist/validator.test.mjs +3 -4
- package/dist/validator.test.mjs.map +1 -1
- package/dist/version-manager.cjs +3 -4
- package/dist/version-manager.cjs.map +1 -1
- package/dist/version-manager.d.mts.map +1 -1
- package/dist/version-manager.mjs +1 -2
- package/dist/version-manager.mjs.map +1 -1
- package/dist/version-manager.test.cjs +5 -6
- package/dist/version-manager.test.cjs.map +1 -1
- package/dist/version-manager.test.mjs +3 -4
- package/dist/version-manager.test.mjs.map +1 -1
- package/dist/{vi.2VT5v0um-BmRMvymT.cjs → vi.2VT5v0um-CRqXre87.cjs} +82 -202
- package/dist/{vi.2VT5v0um-CFyDIn0m.mjs.map → vi.2VT5v0um-CRqXre87.cjs.map} +1 -1
- package/dist/{vi.2VT5v0um-CFyDIn0m.mjs → vi.2VT5v0um-DvC3SVNc.mjs} +67 -186
- package/dist/{vi.2VT5v0um-BmRMvymT.cjs.map → vi.2VT5v0um-DvC3SVNc.mjs.map} +1 -1
- package/package.json +3 -3
- package/src/generators/postgres-init.ts +6 -0
- package/src/presets/presets.test.ts +4 -0
- package/src/presets/registry.ts +88 -0
- package/src/schema.ts +11 -0
- package/src/services/definitions/airbyte.ts +75 -0
- package/src/services/definitions/airflow.ts +109 -0
- package/src/services/definitions/appwrite.ts +181 -0
- package/src/services/definitions/authelia.ts +145 -0
- package/src/services/definitions/axolotl.ts +65 -0
- package/src/services/definitions/chatwoot-worker.ts +93 -0
- package/src/services/definitions/chatwoot.ts +106 -0
- package/src/services/definitions/dagster.ts +82 -0
- package/src/services/definitions/directus.ts +115 -0
- package/src/services/definitions/duplicati.ts +77 -0
- package/src/services/definitions/excalidraw.ts +46 -0
- package/src/services/definitions/firecrawl-playwright.ts +62 -0
- package/src/services/definitions/firecrawl.ts +146 -0
- package/src/services/definitions/flagsmith.ts +76 -0
- package/src/services/definitions/fonoster.ts +67 -0
- package/src/services/definitions/formbricks.ts +75 -0
- package/src/services/definitions/hedgedoc.ts +81 -0
- package/src/services/definitions/heyform.ts +67 -0
- package/src/services/definitions/hoppscotch.ts +74 -0
- package/src/services/definitions/index.ts +124 -0
- package/src/services/definitions/infisical.ts +97 -0
- package/src/services/definitions/keycloak.ts +119 -0
- package/src/services/definitions/kong.ts +116 -0
- package/src/services/definitions/lago.ts +95 -0
- package/src/services/definitions/langflow.ts +82 -0
- package/src/services/definitions/langfuse.ts +76 -0
- package/src/services/definitions/listmonk.ts +118 -0
- package/src/services/definitions/mariadb.ts +82 -0
- package/src/services/definitions/mautic.ts +82 -0
- package/src/services/definitions/medusa.ts +82 -0
- package/src/services/definitions/mysql.ts +82 -0
- package/src/services/definitions/openhands.ts +60 -0
- package/src/services/definitions/opensearch.ts +95 -0
- package/src/services/definitions/pocketbase.ts +62 -0
- package/src/services/definitions/rabbitmq.ts +81 -0
- package/src/services/definitions/ragflow.ts +175 -0
- package/src/services/definitions/restic.ts +60 -0
- package/src/services/definitions/saleor.ts +75 -0
- package/src/services/definitions/stirling-pdf.ts +73 -0
- package/src/services/definitions/strapi.ts +124 -0
- package/src/services/definitions/twenty.ts +82 -0
- package/src/services/definitions/vault.ts +74 -0
- package/src/skills/manifest.json +8 -0
- package/src/skills/registry.ts +119 -0
- package/src/types.ts +91 -2
- package/dist/chunk-C0xms8kb.cjs +0 -34
- package/dist/deployers/coolify.d.cts.map +0 -1
- package/dist/deployers/coolify.d.mts.map +0 -1
- package/dist/deployers/dokploy.d.cts.map +0 -1
- package/dist/deployers/dokploy.d.mts.map +0 -1
- package/dist/deployers/types.d.cts.map +0 -1
- package/dist/deployers/types.d.mts.map +0 -1
- package/dist/generators/skills.cjs.map +0 -1
- package/dist/manifest-4uLbISXV.cjs.map +0 -1
- package/dist/manifest-B8UDsVlR.mjs.map +0 -1
- package/dist/schema.d.cts.map +0 -1
- package/dist/schema.d.mts.map +0 -1
- package/dist/skills/skill-manifest.cjs.map +0 -1
- package/dist/skills/skill-manifest.mjs.map +0 -1
|
@@ -1,18 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
//#region src/deployers/coolify.d.ts
|
|
4
|
-
declare class CoolifyDeployer implements PaasDeployer {
|
|
5
|
-
readonly name = "Coolify";
|
|
6
|
-
readonly id = "coolify";
|
|
7
|
-
testConnection(target: DeployTarget): Promise<{
|
|
8
|
-
ok: boolean;
|
|
9
|
-
error?: undefined;
|
|
10
|
-
} | {
|
|
11
|
-
ok: boolean;
|
|
12
|
-
error: string;
|
|
13
|
-
}>;
|
|
14
|
-
deploy(input: DeployInput): Promise<DeployResult>;
|
|
15
|
-
}
|
|
16
|
-
//#endregion
|
|
17
|
-
export { CoolifyDeployer };
|
|
18
|
-
//# sourceMappingURL=coolify.d.cts.map
|
|
1
|
+
import { t as CoolifyDeployer } from "../coolify-vlb1G9V2.cjs";
|
|
2
|
+
export { CoolifyDeployer };
|
|
@@ -1,18 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
//#region src/deployers/coolify.d.ts
|
|
4
|
-
declare class CoolifyDeployer implements PaasDeployer {
|
|
5
|
-
readonly name = "Coolify";
|
|
6
|
-
readonly id = "coolify";
|
|
7
|
-
testConnection(target: DeployTarget): Promise<{
|
|
8
|
-
ok: boolean;
|
|
9
|
-
error?: undefined;
|
|
10
|
-
} | {
|
|
11
|
-
ok: boolean;
|
|
12
|
-
error: string;
|
|
13
|
-
}>;
|
|
14
|
-
deploy(input: DeployInput): Promise<DeployResult>;
|
|
15
|
-
}
|
|
16
|
-
//#endregion
|
|
17
|
-
export { CoolifyDeployer };
|
|
18
|
-
//# sourceMappingURL=coolify.d.mts.map
|
|
1
|
+
import { t as CoolifyDeployer } from "../coolify-BVGGcMrT.mjs";
|
|
2
|
+
export { CoolifyDeployer };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { sanitizeComposeForPaas } from "./strip-host-ports.mjs";
|
|
2
|
-
|
|
3
2
|
//#region src/deployers/coolify.ts
|
|
4
3
|
/**
|
|
5
4
|
* Coolify PaaS deployer
|
|
@@ -183,7 +182,7 @@ var CoolifyDeployer = class {
|
|
|
183
182
|
}
|
|
184
183
|
}
|
|
185
184
|
};
|
|
186
|
-
|
|
187
185
|
//#endregion
|
|
188
186
|
export { CoolifyDeployer };
|
|
187
|
+
|
|
189
188
|
//# sourceMappingURL=coolify.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coolify.mjs","names":[],"sources":["../../src/deployers/coolify.ts"],"sourcesContent":["/**\n * Coolify PaaS deployer\n *\n * Deploys Docker Compose stacks via Coolify v4 API\n *\n * Docs:\n * https://coolify.io/docs/api-reference/api\n *\n * Auth:\n * Authorization: Bearer <token>\n *\n * Base path:\n * /api/v1\n */\n\nimport { sanitizeComposeForPaas } from \"./strip-host-ports.js\";\nimport type { DeployInput, DeployResult, DeployStep, DeployTarget, PaasDeployer } from \"./types.js\";\n\n/* ----------------------------- */\n/* Coolify API Types */\n/* ----------------------------- */\n\ninterface CoolifyProject {\n\tuuid: string;\n\tname: string;\n\tenvironments?: {\n\t\tuuid: string;\n\t\tname: string;\n\t}[];\n}\n\ninterface CoolifyServer {\n\tuuid: string;\n\tname: string;\n\tip: string;\n}\n\ninterface CoolifyService {\n\tuuid: string;\n\tname: string;\n\tdocker_compose_raw?: string;\n}\n\ninterface CoolifyDeployment {\n\tmessage: string;\n\tresource_uuid: string;\n\tdeployment_uuid: string;\n}\n\n/* ----------------------------- */\n/* Utilities */\n/* ----------------------------- */\n\nfunction apiUrl(target: DeployTarget, path: string) {\n\tconst base = target.instanceUrl.replace(/\\/+$/, \"\");\n\treturn `${base}/api/v1${path}`;\n}\n\nasync function coolifyFetch<T>(\n\ttarget: DeployTarget,\n\tpath: string,\n\toptions: { method?: string; body?: unknown } = {},\n): Promise<T> {\n\tconst res = await fetch(apiUrl(target, path), {\n\t\tmethod: options.method ?? \"GET\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAuthorization: `Bearer ${target.apiKey}`,\n\t\t},\n\t\tbody: options.body ? JSON.stringify(options.body) : undefined,\n\t});\n\n\tif (!res.ok) {\n\t\tconst text = await res.text().catch(() => \"\");\n\t\tlet detail = text;\n\n\t\ttry {\n\t\t\tconst json = JSON.parse(text);\n\t\t\tdetail = json.message || json.error || text;\n\t\t} catch {}\n\n\t\tthrow new Error(`Coolify API ${res.status}: ${detail}`);\n\t}\n\n\tconst text = await res.text();\n\n\tif (!text) return undefined as T;\n\n\treturn JSON.parse(text);\n}\n\nfunction hashString(str: string) {\n\tlet hash = 0;\n\n\tfor (let i = 0; i < str.length; i++) {\n\t\thash = (hash << 5) - hash + str.charCodeAt(i);\n\t\thash |= 0;\n\t}\n\n\treturn hash;\n}\n\nfunction parseEnvContent(envContent?: string) {\n\tif (!envContent) return [];\n\n\tconst result = [];\n\n\tfor (const line of envContent.split(\"\\n\")) {\n\t\tconst trimmed = line.trim();\n\n\t\tif (!trimmed || trimmed.startsWith(\"#\")) continue;\n\n\t\tconst idx = trimmed.indexOf(\"=\");\n\n\t\tif (idx <= 0) continue;\n\n\t\tconst key = trimmed.slice(0, idx);\n\t\tconst value = trimmed.slice(idx + 1);\n\n\t\tresult.push({\n\t\t\tkey,\n\t\t\tvalue,\n\t\t\tis_preview: false,\n\t\t\tis_build_time: false,\n\t\t\tis_literal: true,\n\t\t});\n\t}\n\n\treturn result;\n}\n\n/* ----------------------------- */\n/* Coolify Deployer */\n/* ----------------------------- */\n\nexport class CoolifyDeployer implements PaasDeployer {\n\treadonly name = \"Coolify\";\n\treadonly id = \"coolify\";\n\n\tasync testConnection(target: DeployTarget) {\n\t\ttry {\n\t\t\tawait coolifyFetch(target, \"/version\");\n\n\t\t\treturn { ok: true };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: err instanceof Error ? err.message : String(err),\n\t\t\t};\n\t\t}\n\t}\n\n\tasync deploy(input: DeployInput): Promise<DeployResult> {\n\t\tconst step1: DeployStep = { step: \"Discover server\", status: \"pending\" };\n\t\tconst step2: DeployStep = {\n\t\t\tstep: \"Find or create project\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step3: DeployStep = {\n\t\t\tstep: \"Find or create service\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step4: DeployStep = {\n\t\t\tstep: \"Update environment variables\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step5: DeployStep = { step: \"Trigger deployment\", status: \"pending\" };\n\t\tconst steps: DeployStep[] = [step1, step2, step3, step4, step5];\n\n\t\tconst result: DeployResult = { success: false, steps };\n\n\t\t// Strip host port bindings — Coolify routes via Traefik,\n\t\t// so host ports are unnecessary and cause \"port already allocated\" errors.\n\t\tconst composeYaml = sanitizeComposeForPaas(input.composeYaml);\n\n\t\ttry {\n\t\t\t/* ----------------------------- */\n\t\t\t/* STEP 1: Discover server */\n\t\t\t/* ----------------------------- */\n\n\t\t\tstep1.status = \"running\";\n\n\t\t\tconst servers = await coolifyFetch<CoolifyServer[]>(input.target, \"/servers\");\n\n\t\t\tif (!servers.length) {\n\t\t\t\tthrow new Error(\"No Coolify servers available\");\n\t\t\t}\n\n\t\t\tconst server = servers[0]!;\n\n\t\t\tstep1.status = \"done\";\n\t\t\tstep1.detail = `${server.name} (${server.ip})`;\n\n\t\t\t/* ----------------------------- */\n\t\t\t/* STEP 2: Find or create project */\n\t\t\t/* ----------------------------- */\n\n\t\t\tstep2.status = \"running\";\n\n\t\t\tconst projects = await coolifyFetch<CoolifyProject[]>(input.target, \"/projects\");\n\n\t\t\tlet project = projects.find((p) => p.name === input.projectName);\n\n\t\t\tif (!project) {\n\t\t\t\tproject = await coolifyFetch<CoolifyProject>(input.target, \"/projects\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tname: input.projectName,\n\t\t\t\t\t\tdescription: input.description ?? `Stack ${input.projectName}`,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tresult.projectId = project.uuid;\n\n\t\t\tstep2.status = \"done\";\n\t\t\tstep2.detail = project.uuid;\n\n\t\t\t/* ----------------------------- */\n\t\t\t/* Find environment */\n\t\t\t/* ----------------------------- */\n\n\t\t\tconst projectDetail = await coolifyFetch<CoolifyProject>(\n\t\t\t\tinput.target,\n\t\t\t\t`/projects/${project.uuid}`,\n\t\t\t);\n\n\t\t\tconst env =\n\t\t\t\tprojectDetail.environments?.find((e) => e.name === \"production\") ??\n\t\t\t\tprojectDetail.environments?.[0];\n\n\t\t\tif (!env) throw new Error(\"No environment found\");\n\n\t\t\t/* ----------------------------- */\n\t\t\t/* STEP 3: Find or create service */\n\t\t\t/* ----------------------------- */\n\n\t\t\tstep3.status = \"running\";\n\n\t\t\tconst services = await coolifyFetch<CoolifyService[]>(\n\t\t\t\tinput.target,\n\t\t\t\t`/projects/${project.uuid}/services`,\n\t\t\t);\n\n\t\t\tlet service = services.find((s) => s.name === input.projectName);\n\n\t\t\tif (!service) {\n\t\t\t\tservice = await coolifyFetch<CoolifyService>(input.target, \"/services\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tproject_uuid: project.uuid,\n\n\t\t\t\t\t\tserver_uuid: server.uuid,\n\n\t\t\t\t\t\tenvironment_uuid: env.uuid,\n\n\t\t\t\t\t\tenvironment_name: env.name,\n\n\t\t\t\t\t\tdocker_compose_raw: composeYaml,\n\n\t\t\t\t\t\tname: input.projectName,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst newHash = hashString(composeYaml);\n\t\t\t\tconst oldHash = hashString(service.docker_compose_raw ?? \"\");\n\n\t\t\t\tif (newHash !== oldHash) {\n\t\t\t\t\tawait coolifyFetch(input.target, `/services/${service.uuid}`, {\n\t\t\t\t\t\tmethod: \"PATCH\",\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\tdocker_compose_raw: composeYaml,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tresult.composeId = service.uuid;\n\n\t\t\tstep3.status = \"done\";\n\t\t\tstep3.detail = service.uuid;\n\n\t\t\t/* ----------------------------- */\n\t\t\t/* STEP 4: Environment variables */\n\t\t\t/* ----------------------------- */\n\n\t\t\tstep4.status = \"running\";\n\n\t\t\tconst envVars = parseEnvContent(input.envContent);\n\n\t\t\tif (envVars.length) {\n\t\t\t\tawait coolifyFetch(input.target, `/services/${service.uuid}/envs`, {\n\t\t\t\t\tmethod: \"PATCH\",\n\t\t\t\t\tbody: envVars,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tstep4.status = \"done\";\n\t\t\tstep4.detail = `${envVars.length} vars`;\n\n\t\t\t/* ----------------------------- */\n\t\t\t/* STEP 5: Deploy */\n\t\t\t/* ----------------------------- */\n\n\t\t\tstep5.status = \"running\";\n\n\t\t\tconst deploy = await coolifyFetch<{ deployments: CoolifyDeployment[] }>(\n\t\t\t\tinput.target,\n\t\t\t\t`/deploy?uuid=${service.uuid}&force=true`,\n\t\t\t);\n\n\t\t\tstep5.status = \"done\";\n\t\t\tstep5.detail = deploy.deployments?.[0]?.deployment_uuid ?? \"Deployment started\";\n\n\t\t\tresult.success = true;\n\n\t\t\tconst base = input.target.instanceUrl.replace(/\\/+$/, \"\");\n\n\t\t\tresult.dashboardUrl = `${base}/project/${project.uuid}`;\n\n\t\t\treturn result;\n\t\t} catch (err) {\n\t\t\tconst running = steps.find((s) => s.status === \"running\");\n\n\t\t\tif (running) {\n\t\t\t\trunning.status = \"error\";\n\t\t\t\trunning.detail = err instanceof Error ? err.message : String(err);\n\t\t\t}\n\n\t\t\tresult.error = err instanceof Error ? err.message : String(err);\n\n\t\t\treturn result;\n\t\t}\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAqDA,SAAS,OAAO,QAAsB,MAAc;AAEnD,QAAO,GADM,OAAO,YAAY,QAAQ,QAAQ,GAAG,CACpC,SAAS;;AAGzB,eAAe,aACd,QACA,MACA,UAA+C,EAAE,EACpC;CACb,MAAM,MAAM,MAAM,MAAM,OAAO,QAAQ,KAAK,EAAE;EAC7C,QAAQ,QAAQ,UAAU;EAC1B,SAAS;GACR,gBAAgB;GAChB,eAAe,UAAU,OAAO;GAChC;EACD,MAAM,QAAQ,OAAO,KAAK,UAAU,QAAQ,KAAK,GAAG;EACpD,CAAC;AAEF,KAAI,CAAC,IAAI,IAAI;EACZ,MAAM,OAAO,MAAM,IAAI,MAAM,CAAC,YAAY,GAAG;EAC7C,IAAI,SAAS;AAEb,MAAI;GACH,MAAM,OAAO,KAAK,MAAM,KAAK;AAC7B,YAAS,KAAK,WAAW,KAAK,SAAS;UAChC;AAER,QAAM,IAAI,MAAM,eAAe,IAAI,OAAO,IAAI,SAAS;;CAGxD,MAAM,OAAO,MAAM,IAAI,MAAM;AAE7B,KAAI,CAAC,KAAM,QAAO;AAElB,QAAO,KAAK,MAAM,KAAK;;AAGxB,SAAS,WAAW,KAAa;CAChC,IAAI,OAAO;AAEX,MAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACpC,UAAQ,QAAQ,KAAK,OAAO,IAAI,WAAW,EAAE;AAC7C,UAAQ;;AAGT,QAAO;;AAGR,SAAS,gBAAgB,YAAqB;AAC7C,KAAI,CAAC,WAAY,QAAO,EAAE;CAE1B,MAAM,SAAS,EAAE;AAEjB,MAAK,MAAM,QAAQ,WAAW,MAAM,KAAK,EAAE;EAC1C,MAAM,UAAU,KAAK,MAAM;AAE3B,MAAI,CAAC,WAAW,QAAQ,WAAW,IAAI,CAAE;EAEzC,MAAM,MAAM,QAAQ,QAAQ,IAAI;AAEhC,MAAI,OAAO,EAAG;EAEd,MAAM,MAAM,QAAQ,MAAM,GAAG,IAAI;EACjC,MAAM,QAAQ,QAAQ,MAAM,MAAM,EAAE;AAEpC,SAAO,KAAK;GACX;GACA;GACA,YAAY;GACZ,eAAe;GACf,YAAY;GACZ,CAAC;;AAGH,QAAO;;AAOR,IAAa,kBAAb,MAAqD;CACpD,AAAS,OAAO;CAChB,AAAS,KAAK;CAEd,MAAM,eAAe,QAAsB;AAC1C,MAAI;AACH,SAAM,aAAa,QAAQ,WAAW;AAEtC,UAAO,EAAE,IAAI,MAAM;WACX,KAAK;AACb,UAAO;IACN,IAAI;IACJ,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;IACvD;;;CAIH,MAAM,OAAO,OAA2C;EACvD,MAAM,QAAoB;GAAE,MAAM;GAAmB,QAAQ;GAAW;EACxE,MAAM,QAAoB;GACzB,MAAM;GACN,QAAQ;GACR;EACD,MAAM,QAAoB;GACzB,MAAM;GACN,QAAQ;GACR;EACD,MAAM,QAAoB;GACzB,MAAM;GACN,QAAQ;GACR;EACD,MAAM,QAAoB;GAAE,MAAM;GAAsB,QAAQ;GAAW;EAC3E,MAAM,QAAsB;GAAC;GAAO;GAAO;GAAO;GAAO;GAAM;EAE/D,MAAM,SAAuB;GAAE,SAAS;GAAO;GAAO;EAItD,MAAM,cAAc,uBAAuB,MAAM,YAAY;AAE7D,MAAI;AAKH,SAAM,SAAS;GAEf,MAAM,UAAU,MAAM,aAA8B,MAAM,QAAQ,WAAW;AAE7E,OAAI,CAAC,QAAQ,OACZ,OAAM,IAAI,MAAM,+BAA+B;GAGhD,MAAM,SAAS,QAAQ;AAEvB,SAAM,SAAS;AACf,SAAM,SAAS,GAAG,OAAO,KAAK,IAAI,OAAO,GAAG;AAM5C,SAAM,SAAS;GAIf,IAAI,WAFa,MAAM,aAA+B,MAAM,QAAQ,YAAY,EAEzD,MAAM,MAAM,EAAE,SAAS,MAAM,YAAY;AAEhE,OAAI,CAAC,QACJ,WAAU,MAAM,aAA6B,MAAM,QAAQ,aAAa;IACvE,QAAQ;IACR,MAAM;KACL,MAAM,MAAM;KACZ,aAAa,MAAM,eAAe,SAAS,MAAM;KACjD;IACD,CAAC;AAGH,UAAO,YAAY,QAAQ;AAE3B,SAAM,SAAS;AACf,SAAM,SAAS,QAAQ;GAMvB,MAAM,gBAAgB,MAAM,aAC3B,MAAM,QACN,aAAa,QAAQ,OACrB;GAED,MAAM,MACL,cAAc,cAAc,MAAM,MAAM,EAAE,SAAS,aAAa,IAChE,cAAc,eAAe;AAE9B,OAAI,CAAC,IAAK,OAAM,IAAI,MAAM,uBAAuB;AAMjD,SAAM,SAAS;GAOf,IAAI,WALa,MAAM,aACtB,MAAM,QACN,aAAa,QAAQ,KAAK,WAC1B,EAEsB,MAAM,MAAM,EAAE,SAAS,MAAM,YAAY;AAEhE,OAAI,CAAC,QACJ,WAAU,MAAM,aAA6B,MAAM,QAAQ,aAAa;IACvE,QAAQ;IACR,MAAM;KACL,cAAc,QAAQ;KAEtB,aAAa,OAAO;KAEpB,kBAAkB,IAAI;KAEtB,kBAAkB,IAAI;KAEtB,oBAAoB;KAEpB,MAAM,MAAM;KACZ;IACD,CAAC;YAEc,WAAW,YAAY,KACvB,WAAW,QAAQ,sBAAsB,GAAG,CAG3D,OAAM,aAAa,MAAM,QAAQ,aAAa,QAAQ,QAAQ;IAC7D,QAAQ;IACR,MAAM,EACL,oBAAoB,aACpB;IACD,CAAC;AAIJ,UAAO,YAAY,QAAQ;AAE3B,SAAM,SAAS;AACf,SAAM,SAAS,QAAQ;AAMvB,SAAM,SAAS;GAEf,MAAM,UAAU,gBAAgB,MAAM,WAAW;AAEjD,OAAI,QAAQ,OACX,OAAM,aAAa,MAAM,QAAQ,aAAa,QAAQ,KAAK,QAAQ;IAClE,QAAQ;IACR,MAAM;IACN,CAAC;AAGH,SAAM,SAAS;AACf,SAAM,SAAS,GAAG,QAAQ,OAAO;AAMjC,SAAM,SAAS;GAEf,MAAM,SAAS,MAAM,aACpB,MAAM,QACN,gBAAgB,QAAQ,KAAK,aAC7B;AAED,SAAM,SAAS;AACf,SAAM,SAAS,OAAO,cAAc,IAAI,mBAAmB;AAE3D,UAAO,UAAU;AAIjB,UAAO,eAAe,GAFT,MAAM,OAAO,YAAY,QAAQ,QAAQ,GAAG,CAE3B,WAAW,QAAQ;AAEjD,UAAO;WACC,KAAK;GACb,MAAM,UAAU,MAAM,MAAM,MAAM,EAAE,WAAW,UAAU;AAEzD,OAAI,SAAS;AACZ,YAAQ,SAAS;AACjB,YAAQ,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;;AAGlE,UAAO,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAE/D,UAAO"}
|
|
1
|
+
{"version":3,"file":"coolify.mjs","names":[],"sources":["../../src/deployers/coolify.ts"],"sourcesContent":["/**\n * Coolify PaaS deployer\n *\n * Deploys Docker Compose stacks via Coolify v4 API\n *\n * Docs:\n * https://coolify.io/docs/api-reference/api\n *\n * Auth:\n * Authorization: Bearer <token>\n *\n * Base path:\n * /api/v1\n */\n\nimport { sanitizeComposeForPaas } from \"./strip-host-ports.js\";\nimport type { DeployInput, DeployResult, DeployStep, DeployTarget, PaasDeployer } from \"./types.js\";\n\n/* ----------------------------- */\n/* Coolify API Types */\n/* ----------------------------- */\n\ninterface CoolifyProject {\n\tuuid: string;\n\tname: string;\n\tenvironments?: {\n\t\tuuid: string;\n\t\tname: string;\n\t}[];\n}\n\ninterface CoolifyServer {\n\tuuid: string;\n\tname: string;\n\tip: string;\n}\n\ninterface CoolifyService {\n\tuuid: string;\n\tname: string;\n\tdocker_compose_raw?: string;\n}\n\ninterface CoolifyDeployment {\n\tmessage: string;\n\tresource_uuid: string;\n\tdeployment_uuid: string;\n}\n\n/* ----------------------------- */\n/* Utilities */\n/* ----------------------------- */\n\nfunction apiUrl(target: DeployTarget, path: string) {\n\tconst base = target.instanceUrl.replace(/\\/+$/, \"\");\n\treturn `${base}/api/v1${path}`;\n}\n\nasync function coolifyFetch<T>(\n\ttarget: DeployTarget,\n\tpath: string,\n\toptions: { method?: string; body?: unknown } = {},\n): Promise<T> {\n\tconst res = await fetch(apiUrl(target, path), {\n\t\tmethod: options.method ?? \"GET\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAuthorization: `Bearer ${target.apiKey}`,\n\t\t},\n\t\tbody: options.body ? JSON.stringify(options.body) : undefined,\n\t});\n\n\tif (!res.ok) {\n\t\tconst text = await res.text().catch(() => \"\");\n\t\tlet detail = text;\n\n\t\ttry {\n\t\t\tconst json = JSON.parse(text);\n\t\t\tdetail = json.message || json.error || text;\n\t\t} catch {}\n\n\t\tthrow new Error(`Coolify API ${res.status}: ${detail}`);\n\t}\n\n\tconst text = await res.text();\n\n\tif (!text) return undefined as T;\n\n\treturn JSON.parse(text);\n}\n\nfunction hashString(str: string) {\n\tlet hash = 0;\n\n\tfor (let i = 0; i < str.length; i++) {\n\t\thash = (hash << 5) - hash + str.charCodeAt(i);\n\t\thash |= 0;\n\t}\n\n\treturn hash;\n}\n\nfunction parseEnvContent(envContent?: string) {\n\tif (!envContent) return [];\n\n\tconst result = [];\n\n\tfor (const line of envContent.split(\"\\n\")) {\n\t\tconst trimmed = line.trim();\n\n\t\tif (!trimmed || trimmed.startsWith(\"#\")) continue;\n\n\t\tconst idx = trimmed.indexOf(\"=\");\n\n\t\tif (idx <= 0) continue;\n\n\t\tconst key = trimmed.slice(0, idx);\n\t\tconst value = trimmed.slice(idx + 1);\n\n\t\tresult.push({\n\t\t\tkey,\n\t\t\tvalue,\n\t\t\tis_preview: false,\n\t\t\tis_build_time: false,\n\t\t\tis_literal: true,\n\t\t});\n\t}\n\n\treturn result;\n}\n\n/* ----------------------------- */\n/* Coolify Deployer */\n/* ----------------------------- */\n\nexport class CoolifyDeployer implements PaasDeployer {\n\treadonly name = \"Coolify\";\n\treadonly id = \"coolify\";\n\n\tasync testConnection(target: DeployTarget) {\n\t\ttry {\n\t\t\tawait coolifyFetch(target, \"/version\");\n\n\t\t\treturn { ok: true };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: err instanceof Error ? err.message : String(err),\n\t\t\t};\n\t\t}\n\t}\n\n\tasync deploy(input: DeployInput): Promise<DeployResult> {\n\t\tconst step1: DeployStep = { step: \"Discover server\", status: \"pending\" };\n\t\tconst step2: DeployStep = {\n\t\t\tstep: \"Find or create project\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step3: DeployStep = {\n\t\t\tstep: \"Find or create service\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step4: DeployStep = {\n\t\t\tstep: \"Update environment variables\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step5: DeployStep = { step: \"Trigger deployment\", status: \"pending\" };\n\t\tconst steps: DeployStep[] = [step1, step2, step3, step4, step5];\n\n\t\tconst result: DeployResult = { success: false, steps };\n\n\t\t// Strip host port bindings — Coolify routes via Traefik,\n\t\t// so host ports are unnecessary and cause \"port already allocated\" errors.\n\t\tconst composeYaml = sanitizeComposeForPaas(input.composeYaml);\n\n\t\ttry {\n\t\t\t/* ----------------------------- */\n\t\t\t/* STEP 1: Discover server */\n\t\t\t/* ----------------------------- */\n\n\t\t\tstep1.status = \"running\";\n\n\t\t\tconst servers = await coolifyFetch<CoolifyServer[]>(input.target, \"/servers\");\n\n\t\t\tif (!servers.length) {\n\t\t\t\tthrow new Error(\"No Coolify servers available\");\n\t\t\t}\n\n\t\t\tconst server = servers[0]!;\n\n\t\t\tstep1.status = \"done\";\n\t\t\tstep1.detail = `${server.name} (${server.ip})`;\n\n\t\t\t/* ----------------------------- */\n\t\t\t/* STEP 2: Find or create project */\n\t\t\t/* ----------------------------- */\n\n\t\t\tstep2.status = \"running\";\n\n\t\t\tconst projects = await coolifyFetch<CoolifyProject[]>(input.target, \"/projects\");\n\n\t\t\tlet project = projects.find((p) => p.name === input.projectName);\n\n\t\t\tif (!project) {\n\t\t\t\tproject = await coolifyFetch<CoolifyProject>(input.target, \"/projects\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tname: input.projectName,\n\t\t\t\t\t\tdescription: input.description ?? `Stack ${input.projectName}`,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tresult.projectId = project.uuid;\n\n\t\t\tstep2.status = \"done\";\n\t\t\tstep2.detail = project.uuid;\n\n\t\t\t/* ----------------------------- */\n\t\t\t/* Find environment */\n\t\t\t/* ----------------------------- */\n\n\t\t\tconst projectDetail = await coolifyFetch<CoolifyProject>(\n\t\t\t\tinput.target,\n\t\t\t\t`/projects/${project.uuid}`,\n\t\t\t);\n\n\t\t\tconst env =\n\t\t\t\tprojectDetail.environments?.find((e) => e.name === \"production\") ??\n\t\t\t\tprojectDetail.environments?.[0];\n\n\t\t\tif (!env) throw new Error(\"No environment found\");\n\n\t\t\t/* ----------------------------- */\n\t\t\t/* STEP 3: Find or create service */\n\t\t\t/* ----------------------------- */\n\n\t\t\tstep3.status = \"running\";\n\n\t\t\tconst services = await coolifyFetch<CoolifyService[]>(\n\t\t\t\tinput.target,\n\t\t\t\t`/projects/${project.uuid}/services`,\n\t\t\t);\n\n\t\t\tlet service = services.find((s) => s.name === input.projectName);\n\n\t\t\tif (!service) {\n\t\t\t\tservice = await coolifyFetch<CoolifyService>(input.target, \"/services\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tproject_uuid: project.uuid,\n\n\t\t\t\t\t\tserver_uuid: server.uuid,\n\n\t\t\t\t\t\tenvironment_uuid: env.uuid,\n\n\t\t\t\t\t\tenvironment_name: env.name,\n\n\t\t\t\t\t\tdocker_compose_raw: composeYaml,\n\n\t\t\t\t\t\tname: input.projectName,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst newHash = hashString(composeYaml);\n\t\t\t\tconst oldHash = hashString(service.docker_compose_raw ?? \"\");\n\n\t\t\t\tif (newHash !== oldHash) {\n\t\t\t\t\tawait coolifyFetch(input.target, `/services/${service.uuid}`, {\n\t\t\t\t\t\tmethod: \"PATCH\",\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\tdocker_compose_raw: composeYaml,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tresult.composeId = service.uuid;\n\n\t\t\tstep3.status = \"done\";\n\t\t\tstep3.detail = service.uuid;\n\n\t\t\t/* ----------------------------- */\n\t\t\t/* STEP 4: Environment variables */\n\t\t\t/* ----------------------------- */\n\n\t\t\tstep4.status = \"running\";\n\n\t\t\tconst envVars = parseEnvContent(input.envContent);\n\n\t\t\tif (envVars.length) {\n\t\t\t\tawait coolifyFetch(input.target, `/services/${service.uuid}/envs`, {\n\t\t\t\t\tmethod: \"PATCH\",\n\t\t\t\t\tbody: envVars,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tstep4.status = \"done\";\n\t\t\tstep4.detail = `${envVars.length} vars`;\n\n\t\t\t/* ----------------------------- */\n\t\t\t/* STEP 5: Deploy */\n\t\t\t/* ----------------------------- */\n\n\t\t\tstep5.status = \"running\";\n\n\t\t\tconst deploy = await coolifyFetch<{ deployments: CoolifyDeployment[] }>(\n\t\t\t\tinput.target,\n\t\t\t\t`/deploy?uuid=${service.uuid}&force=true`,\n\t\t\t);\n\n\t\t\tstep5.status = \"done\";\n\t\t\tstep5.detail = deploy.deployments?.[0]?.deployment_uuid ?? \"Deployment started\";\n\n\t\t\tresult.success = true;\n\n\t\t\tconst base = input.target.instanceUrl.replace(/\\/+$/, \"\");\n\n\t\t\tresult.dashboardUrl = `${base}/project/${project.uuid}`;\n\n\t\t\treturn result;\n\t\t} catch (err) {\n\t\t\tconst running = steps.find((s) => s.status === \"running\");\n\n\t\t\tif (running) {\n\t\t\t\trunning.status = \"error\";\n\t\t\t\trunning.detail = err instanceof Error ? err.message : String(err);\n\t\t\t}\n\n\t\t\tresult.error = err instanceof Error ? err.message : String(err);\n\n\t\t\treturn result;\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value:
|
|
2
|
-
const require_deployers_strip_host_ports = require(
|
|
3
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_deployers_strip_host_ports = require("./strip-host-ports.cjs");
|
|
4
3
|
//#region src/deployers/dokploy.ts
|
|
5
4
|
/**
|
|
6
5
|
* Dokploy PaaS deployer — deploys Docker Compose stacks via the Dokploy REST API.
|
|
@@ -216,7 +215,7 @@ var DokployDeployer = class {
|
|
|
216
215
|
}
|
|
217
216
|
}
|
|
218
217
|
};
|
|
219
|
-
|
|
220
218
|
//#endregion
|
|
221
219
|
exports.DokployDeployer = DokployDeployer;
|
|
220
|
+
|
|
222
221
|
//# sourceMappingURL=dokploy.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dokploy.cjs","names":["sanitizeComposeForPaas"],"sources":["../../src/deployers/dokploy.ts"],"sourcesContent":["/**\n * Dokploy PaaS deployer — deploys Docker Compose stacks via the Dokploy REST API.\n *\n * API docs: https://docs.dokploy.com/docs/api\n * Auth: x-api-key header\n * Endpoints use dot-notation (e.g. /api/project.create, /api/compose.deploy)\n */\n\nimport { sanitizeComposeForPaas } from \"./strip-host-ports.js\";\nimport type {\n\tDeployInput,\n\tDeployResult,\n\tDeployStep,\n\tDeployTarget,\n\tDokployEnvironment,\n\tPaasDeployer,\n\tPaasServer,\n} from \"./types.js\";\n\ninterface DokployProject {\n\tprojectId: string;\n\tname: string;\n\tdescription: string;\n\tenvironments?: DokployEnvironment[];\n}\n\ninterface DokployCompose {\n\tcomposeId: string;\n\tname: string;\n\tstatus?: string;\n\tcompose?: string;\n}\n\ninterface ProjectCreateResult {\n\tproject: DokployProject;\n\tprojectId: string;\n\tname: string;\n\tdescription: string;\n\tenvironments?: { environmentId: string; name: string }[];\n}\n\n/** Build a full Dokploy API URL from a dot-notation endpoint (e.g. \"project.create\"). */\nfunction apiUrl(target: DeployTarget, endpoint: string): string {\n\tconst base = target.instanceUrl.replace(/\\/+$/, \"\");\n\treturn `${base}/api/${endpoint}`;\n}\n/**\n * Typed fetch wrapper for the Dokploy API.\n * Handles JSON serialisation, x-api-key auth, and error extraction.\n */\nasync function dokployFetch<T>(\n\ttarget: DeployTarget,\n\tendpoint: string,\n\toptions: { method?: string; body?: unknown } = {},\n): Promise<T> {\n\tconst res = await fetch(apiUrl(target, endpoint), {\n\t\tmethod: options.method ?? \"GET\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\"x-api-key\": target.apiKey,\n\t\t},\n\t\tbody: options.body ? JSON.stringify(options.body) : undefined,\n\t});\n\n\tif (!res.ok) {\n\t\tconst text = await res.text().catch(() => \"\");\n\t\tlet detail = text;\n\n\t\ttry {\n\t\t\tconst json = JSON.parse(text);\n\t\t\tdetail = json.message || json.error || text;\n\t\t} catch {}\n\n\t\tthrow new Error(`Dokploy API ${res.status}: ${detail}`);\n\t}\n\n\tconst text = await res.text();\n\tif (!text) return undefined as T;\n\n\treturn JSON.parse(text) as T;\n}\n\n/**\n * Simple hash for compose diff detection\n */\nfunction hashString(str: string) {\n\tlet hash = 0;\n\n\tfor (let i = 0; i < str.length; i++) {\n\t\thash = (hash << 5) - hash + str.charCodeAt(i);\n\t\thash |= 0;\n\t}\n\n\treturn hash;\n}\n\n/**\n * Deploys Docker Compose stacks to a Dokploy instance.\n *\n * Deploy flow (4 steps):\n * 1. Create a Dokploy project\n * 2. Create a compose stack inside the project's default environment\n * 3. Push .env variables to the compose stack\n * 4. Trigger the deployment\n */\n\nexport class DokployDeployer implements PaasDeployer {\n\treadonly name = \"Dokploy\";\n\treadonly id = \"dokploy\";\n\n\tasync testConnection(target: DeployTarget): Promise<{ ok: boolean; error?: string }> {\n\t\ttry {\n\t\t\tawait dokployFetch<DokployProject[]>(target, \"project.all\");\n\n\t\t\treturn { ok: true };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: err instanceof Error ? err.message : String(err),\n\t\t\t};\n\t\t}\n\t}\n\n\tasync listServers(target: DeployTarget): Promise<PaasServer[]> {\n\t\ttry {\n\t\t\tconst servers = await dokployFetch<{ serverId: string; name: string; ipAddress: string }[]>(\n\t\t\t\ttarget,\n\t\t\t\t\"server.all\",\n\t\t\t);\n\t\t\treturn servers.map((s) => ({\n\t\t\t\tid: s.serverId,\n\t\t\t\tname: s.name,\n\t\t\t\tip: s.ipAddress,\n\t\t\t}));\n\t\t} catch {\n\t\t\t// Return empty list if server API is not available\n\t\t\treturn [];\n\t\t}\n\t}\n\n\tasync deploy(input: DeployInput): Promise<DeployResult> {\n\t\tconst step1: DeployStep = {\n\t\t\tstep: \"Find or create project\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step2: DeployStep = {\n\t\t\tstep: \"Find default environment\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step3: DeployStep = {\n\t\t\tstep: \"Find or create compose stack\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step4: DeployStep = {\n\t\t\tstep: \"Update stack configuration\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step5: DeployStep = { step: \"Deploy stack\", status: \"pending\" };\n\t\tconst steps: DeployStep[] = [step1, step2, step3, step4, step5];\n\n\t\tconst result: DeployResult = { success: false, steps };\n\n\t\t// Strip host port bindings — Dokploy routes via Traefik,\n\t\t// so host ports are unnecessary and cause \"port already allocated\" errors.\n\t\tconst composeYaml = sanitizeComposeForPaas(input.composeYaml);\n\n\t\ttry {\n\t\t\t/**\n\t\t\t * STEP 1\n\t\t\t * Find or create project\n\t\t\t */\n\n\t\t\tstep1.status = \"running\";\n\n\t\t\tconst projects = await dokployFetch<DokployProject[]>(input.target, \"project.all\");\n\n\t\t\tlet project = projects.find((p) => p.name === input.projectName);\n\n\t\t\tif (!project) {\n\t\t\t\tconst created = await dokployFetch<ProjectCreateResult>(input.target, \"project.create\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tname: input.projectName,\n\t\t\t\t\t\tdescription: input.description ?? `OpenClaw stack: ${input.projectName}`,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tproject = created.project;\n\t\t\t}\n\n\t\t\tresult.projectId = project.projectId;\n\n\t\t\tstep1.status = \"done\";\n\t\t\tstep1.detail = `Project ID: ${project.projectId}`;\n\n\t\t\t/**\n\t\t\t * STEP 2\n\t\t\t * Find default environment\n\t\t\t */\n\n\t\t\tstep2.status = \"running\";\n\n\t\t\tconst projectDetail = await dokployFetch<DokployProject>(\n\t\t\t\tinput.target,\n\t\t\t\t`project.one?projectId=${project.projectId}`,\n\t\t\t);\n\n\t\t\tconst env = projectDetail.environments?.find((e) => e.isDefault);\n\n\t\t\tif (!env) throw new Error(\"No default environment\");\n\n\t\t\tstep2.status = \"done\";\n\t\t\tstep2.detail = env.environmentId;\n\n\t\t\t/**\n\t\t\t * STEP 3\n\t\t\t * Find or create compose stack\n\t\t\t */\n\n\t\t\tstep3.status = \"running\";\n\n\t\t\tlet stack: DokployCompose | null = null;\n\n\t\t\tstack = await dokployFetch<DokployCompose>(input.target, \"compose.create\", {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tbody: {\n\t\t\t\t\tname: input.projectName,\n\t\t\t\t\tdescription: input.description ?? `Stack ${input.projectName}`,\n\t\t\t\t\tenvironmentId: env.environmentId,\n\t\t\t\t\tcomposeType: \"docker-compose\",\n\t\t\t\t\tcomposeFile: composeYaml,\n\t\t\t\t\t...(input.serverId ? { serverId: input.serverId } : {}),\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// Dokploy's compose.create schema does NOT accept sourceType;\n\t\t\t// it defaults to \"github\". We must update it to \"raw\" so the\n\t\t\t// deploy step writes the compose file from the stored YAML\n\t\t\t// instead of attempting to clone from a Git provider.\n\t\t\tif (stack?.composeId) {\n\t\t\t\tawait dokployFetch(input.target, \"compose.update\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tcomposeId: stack.composeId,\n\t\t\t\t\t\tsourceType: \"raw\",\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tresult.composeId = stack?.composeId;\n\t\t\tstep3.status = \"done\";\n\t\t\tstep3.detail = stack?.composeId;\n\n\t\t\t/**\n\t\t\t * STEP 4\n\t\t\t * Update stack if compose changed\n\t\t\t */\n\n\t\t\tstep4.status = \"running\";\n\n\t\t\tconst existingStack = await dokployFetch<DokployCompose>(\n\t\t\t\tinput.target,\n\t\t\t\t`compose.one?composeId=${stack?.composeId}`,\n\t\t\t);\n\n\t\t\tconst newHash = hashString(composeYaml);\n\t\t\tconst oldHash = hashString(existingStack.compose ?? \"\");\n\n\t\t\tif (newHash !== oldHash) {\n\t\t\t\tawait dokployFetch(input.target, \"compose.update\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tcomposeId: stack?.composeId,\n\t\t\t\t\t\tcomposeFile: composeYaml,\n\t\t\t\t\t\tenv: input.envContent ?? \"\",\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tstep4.detail = \"Stack updated\";\n\t\t\t} else {\n\t\t\t\tstep4.detail = \"No compose changes\";\n\t\t\t}\n\n\t\t\tstep4.status = \"done\";\n\n\t\t\t/**\n\t\t\t * STEP 5\n\t\t\t * Deploy\n\t\t\t */\n\n\t\t\tstep5.status = \"running\";\n\n\t\t\tawait dokployFetch(input.target, \"compose.deploy\", {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tbody: {\n\t\t\t\t\tcomposeId: stack?.composeId,\n\n\t\t\t\t\ttitle: `Deploy ${input.projectName}`,\n\n\t\t\t\t\tdescription: \"CI deployment\",\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tstep5.status = \"done\";\n\n\t\t\tresult.success = true;\n\n\t\t\tconst base = input.target.instanceUrl.replace(/\\/+$/, \"\");\n\n\t\t\tresult.dashboardUrl = `${base}/dashboard/project/${project.projectId}/environment/${env.environmentId}/services/compose/${stack?.composeId}?tab=deployments`;\n\n\t\t\treturn result;\n\t\t} catch (err) {\n\t\t\tconst running = steps.find((s) => s.status === \"running\");\n\n\t\t\tif (running) {\n\t\t\t\trunning.status = \"error\";\n\n\t\t\t\trunning.detail = err instanceof Error ? err.message : String(err);\n\t\t\t}\n\n\t\t\tresult.error = err instanceof Error ? err.message : String(err);\n\n\t\t\treturn result;\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dokploy.cjs","names":["sanitizeComposeForPaas"],"sources":["../../src/deployers/dokploy.ts"],"sourcesContent":["/**\n * Dokploy PaaS deployer — deploys Docker Compose stacks via the Dokploy REST API.\n *\n * API docs: https://docs.dokploy.com/docs/api\n * Auth: x-api-key header\n * Endpoints use dot-notation (e.g. /api/project.create, /api/compose.deploy)\n */\n\nimport { sanitizeComposeForPaas } from \"./strip-host-ports.js\";\nimport type {\n\tDeployInput,\n\tDeployResult,\n\tDeployStep,\n\tDeployTarget,\n\tDokployEnvironment,\n\tPaasDeployer,\n\tPaasServer,\n} from \"./types.js\";\n\ninterface DokployProject {\n\tprojectId: string;\n\tname: string;\n\tdescription: string;\n\tenvironments?: DokployEnvironment[];\n}\n\ninterface DokployCompose {\n\tcomposeId: string;\n\tname: string;\n\tstatus?: string;\n\tcompose?: string;\n}\n\ninterface ProjectCreateResult {\n\tproject: DokployProject;\n\tprojectId: string;\n\tname: string;\n\tdescription: string;\n\tenvironments?: { environmentId: string; name: string }[];\n}\n\n/** Build a full Dokploy API URL from a dot-notation endpoint (e.g. \"project.create\"). */\nfunction apiUrl(target: DeployTarget, endpoint: string): string {\n\tconst base = target.instanceUrl.replace(/\\/+$/, \"\");\n\treturn `${base}/api/${endpoint}`;\n}\n/**\n * Typed fetch wrapper for the Dokploy API.\n * Handles JSON serialisation, x-api-key auth, and error extraction.\n */\nasync function dokployFetch<T>(\n\ttarget: DeployTarget,\n\tendpoint: string,\n\toptions: { method?: string; body?: unknown } = {},\n): Promise<T> {\n\tconst res = await fetch(apiUrl(target, endpoint), {\n\t\tmethod: options.method ?? \"GET\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\"x-api-key\": target.apiKey,\n\t\t},\n\t\tbody: options.body ? JSON.stringify(options.body) : undefined,\n\t});\n\n\tif (!res.ok) {\n\t\tconst text = await res.text().catch(() => \"\");\n\t\tlet detail = text;\n\n\t\ttry {\n\t\t\tconst json = JSON.parse(text);\n\t\t\tdetail = json.message || json.error || text;\n\t\t} catch {}\n\n\t\tthrow new Error(`Dokploy API ${res.status}: ${detail}`);\n\t}\n\n\tconst text = await res.text();\n\tif (!text) return undefined as T;\n\n\treturn JSON.parse(text) as T;\n}\n\n/**\n * Simple hash for compose diff detection\n */\nfunction hashString(str: string) {\n\tlet hash = 0;\n\n\tfor (let i = 0; i < str.length; i++) {\n\t\thash = (hash << 5) - hash + str.charCodeAt(i);\n\t\thash |= 0;\n\t}\n\n\treturn hash;\n}\n\n/**\n * Deploys Docker Compose stacks to a Dokploy instance.\n *\n * Deploy flow (4 steps):\n * 1. Create a Dokploy project\n * 2. Create a compose stack inside the project's default environment\n * 3. Push .env variables to the compose stack\n * 4. Trigger the deployment\n */\n\nexport class DokployDeployer implements PaasDeployer {\n\treadonly name = \"Dokploy\";\n\treadonly id = \"dokploy\";\n\n\tasync testConnection(target: DeployTarget): Promise<{ ok: boolean; error?: string }> {\n\t\ttry {\n\t\t\tawait dokployFetch<DokployProject[]>(target, \"project.all\");\n\n\t\t\treturn { ok: true };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: err instanceof Error ? err.message : String(err),\n\t\t\t};\n\t\t}\n\t}\n\n\tasync listServers(target: DeployTarget): Promise<PaasServer[]> {\n\t\ttry {\n\t\t\tconst servers = await dokployFetch<{ serverId: string; name: string; ipAddress: string }[]>(\n\t\t\t\ttarget,\n\t\t\t\t\"server.all\",\n\t\t\t);\n\t\t\treturn servers.map((s) => ({\n\t\t\t\tid: s.serverId,\n\t\t\t\tname: s.name,\n\t\t\t\tip: s.ipAddress,\n\t\t\t}));\n\t\t} catch {\n\t\t\t// Return empty list if server API is not available\n\t\t\treturn [];\n\t\t}\n\t}\n\n\tasync deploy(input: DeployInput): Promise<DeployResult> {\n\t\tconst step1: DeployStep = {\n\t\t\tstep: \"Find or create project\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step2: DeployStep = {\n\t\t\tstep: \"Find default environment\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step3: DeployStep = {\n\t\t\tstep: \"Find or create compose stack\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step4: DeployStep = {\n\t\t\tstep: \"Update stack configuration\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step5: DeployStep = { step: \"Deploy stack\", status: \"pending\" };\n\t\tconst steps: DeployStep[] = [step1, step2, step3, step4, step5];\n\n\t\tconst result: DeployResult = { success: false, steps };\n\n\t\t// Strip host port bindings — Dokploy routes via Traefik,\n\t\t// so host ports are unnecessary and cause \"port already allocated\" errors.\n\t\tconst composeYaml = sanitizeComposeForPaas(input.composeYaml);\n\n\t\ttry {\n\t\t\t/**\n\t\t\t * STEP 1\n\t\t\t * Find or create project\n\t\t\t */\n\n\t\t\tstep1.status = \"running\";\n\n\t\t\tconst projects = await dokployFetch<DokployProject[]>(input.target, \"project.all\");\n\n\t\t\tlet project = projects.find((p) => p.name === input.projectName);\n\n\t\t\tif (!project) {\n\t\t\t\tconst created = await dokployFetch<ProjectCreateResult>(input.target, \"project.create\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tname: input.projectName,\n\t\t\t\t\t\tdescription: input.description ?? `OpenClaw stack: ${input.projectName}`,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tproject = created.project;\n\t\t\t}\n\n\t\t\tresult.projectId = project.projectId;\n\n\t\t\tstep1.status = \"done\";\n\t\t\tstep1.detail = `Project ID: ${project.projectId}`;\n\n\t\t\t/**\n\t\t\t * STEP 2\n\t\t\t * Find default environment\n\t\t\t */\n\n\t\t\tstep2.status = \"running\";\n\n\t\t\tconst projectDetail = await dokployFetch<DokployProject>(\n\t\t\t\tinput.target,\n\t\t\t\t`project.one?projectId=${project.projectId}`,\n\t\t\t);\n\n\t\t\tconst env = projectDetail.environments?.find((e) => e.isDefault);\n\n\t\t\tif (!env) throw new Error(\"No default environment\");\n\n\t\t\tstep2.status = \"done\";\n\t\t\tstep2.detail = env.environmentId;\n\n\t\t\t/**\n\t\t\t * STEP 3\n\t\t\t * Find or create compose stack\n\t\t\t */\n\n\t\t\tstep3.status = \"running\";\n\n\t\t\tlet stack: DokployCompose | null = null;\n\n\t\t\tstack = await dokployFetch<DokployCompose>(input.target, \"compose.create\", {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tbody: {\n\t\t\t\t\tname: input.projectName,\n\t\t\t\t\tdescription: input.description ?? `Stack ${input.projectName}`,\n\t\t\t\t\tenvironmentId: env.environmentId,\n\t\t\t\t\tcomposeType: \"docker-compose\",\n\t\t\t\t\tcomposeFile: composeYaml,\n\t\t\t\t\t...(input.serverId ? { serverId: input.serverId } : {}),\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// Dokploy's compose.create schema does NOT accept sourceType;\n\t\t\t// it defaults to \"github\". We must update it to \"raw\" so the\n\t\t\t// deploy step writes the compose file from the stored YAML\n\t\t\t// instead of attempting to clone from a Git provider.\n\t\t\tif (stack?.composeId) {\n\t\t\t\tawait dokployFetch(input.target, \"compose.update\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tcomposeId: stack.composeId,\n\t\t\t\t\t\tsourceType: \"raw\",\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tresult.composeId = stack?.composeId;\n\t\t\tstep3.status = \"done\";\n\t\t\tstep3.detail = stack?.composeId;\n\n\t\t\t/**\n\t\t\t * STEP 4\n\t\t\t * Update stack if compose changed\n\t\t\t */\n\n\t\t\tstep4.status = \"running\";\n\n\t\t\tconst existingStack = await dokployFetch<DokployCompose>(\n\t\t\t\tinput.target,\n\t\t\t\t`compose.one?composeId=${stack?.composeId}`,\n\t\t\t);\n\n\t\t\tconst newHash = hashString(composeYaml);\n\t\t\tconst oldHash = hashString(existingStack.compose ?? \"\");\n\n\t\t\tif (newHash !== oldHash) {\n\t\t\t\tawait dokployFetch(input.target, \"compose.update\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tcomposeId: stack?.composeId,\n\t\t\t\t\t\tcomposeFile: composeYaml,\n\t\t\t\t\t\tenv: input.envContent ?? \"\",\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tstep4.detail = \"Stack updated\";\n\t\t\t} else {\n\t\t\t\tstep4.detail = \"No compose changes\";\n\t\t\t}\n\n\t\t\tstep4.status = \"done\";\n\n\t\t\t/**\n\t\t\t * STEP 5\n\t\t\t * Deploy\n\t\t\t */\n\n\t\t\tstep5.status = \"running\";\n\n\t\t\tawait dokployFetch(input.target, \"compose.deploy\", {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tbody: {\n\t\t\t\t\tcomposeId: stack?.composeId,\n\n\t\t\t\t\ttitle: `Deploy ${input.projectName}`,\n\n\t\t\t\t\tdescription: \"CI deployment\",\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tstep5.status = \"done\";\n\n\t\t\tresult.success = true;\n\n\t\t\tconst base = input.target.instanceUrl.replace(/\\/+$/, \"\");\n\n\t\t\tresult.dashboardUrl = `${base}/dashboard/project/${project.projectId}/environment/${env.environmentId}/services/compose/${stack?.composeId}?tab=deployments`;\n\n\t\t\treturn result;\n\t\t} catch (err) {\n\t\t\tconst running = steps.find((s) => s.status === \"running\");\n\n\t\t\tif (running) {\n\t\t\t\trunning.status = \"error\";\n\n\t\t\t\trunning.detail = err instanceof Error ? err.message : String(err);\n\t\t\t}\n\n\t\t\tresult.error = err instanceof Error ? err.message : String(err);\n\n\t\t\treturn result;\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1,25 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
//#region src/deployers/dokploy.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Deploys Docker Compose stacks to a Dokploy instance.
|
|
6
|
-
*
|
|
7
|
-
* Deploy flow (4 steps):
|
|
8
|
-
* 1. Create a Dokploy project
|
|
9
|
-
* 2. Create a compose stack inside the project's default environment
|
|
10
|
-
* 3. Push .env variables to the compose stack
|
|
11
|
-
* 4. Trigger the deployment
|
|
12
|
-
*/
|
|
13
|
-
declare class DokployDeployer implements PaasDeployer {
|
|
14
|
-
readonly name = "Dokploy";
|
|
15
|
-
readonly id = "dokploy";
|
|
16
|
-
testConnection(target: DeployTarget): Promise<{
|
|
17
|
-
ok: boolean;
|
|
18
|
-
error?: string;
|
|
19
|
-
}>;
|
|
20
|
-
listServers(target: DeployTarget): Promise<PaasServer[]>;
|
|
21
|
-
deploy(input: DeployInput): Promise<DeployResult>;
|
|
22
|
-
}
|
|
23
|
-
//#endregion
|
|
24
|
-
export { DokployDeployer };
|
|
25
|
-
//# sourceMappingURL=dokploy.d.cts.map
|
|
1
|
+
import { t as DokployDeployer } from "../dokploy-8cbrxUun.cjs";
|
|
2
|
+
export { DokployDeployer };
|
|
@@ -1,25 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
//#region src/deployers/dokploy.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Deploys Docker Compose stacks to a Dokploy instance.
|
|
6
|
-
*
|
|
7
|
-
* Deploy flow (4 steps):
|
|
8
|
-
* 1. Create a Dokploy project
|
|
9
|
-
* 2. Create a compose stack inside the project's default environment
|
|
10
|
-
* 3. Push .env variables to the compose stack
|
|
11
|
-
* 4. Trigger the deployment
|
|
12
|
-
*/
|
|
13
|
-
declare class DokployDeployer implements PaasDeployer {
|
|
14
|
-
readonly name = "Dokploy";
|
|
15
|
-
readonly id = "dokploy";
|
|
16
|
-
testConnection(target: DeployTarget): Promise<{
|
|
17
|
-
ok: boolean;
|
|
18
|
-
error?: string;
|
|
19
|
-
}>;
|
|
20
|
-
listServers(target: DeployTarget): Promise<PaasServer[]>;
|
|
21
|
-
deploy(input: DeployInput): Promise<DeployResult>;
|
|
22
|
-
}
|
|
23
|
-
//#endregion
|
|
24
|
-
export { DokployDeployer };
|
|
25
|
-
//# sourceMappingURL=dokploy.d.mts.map
|
|
1
|
+
import { t as DokployDeployer } from "../dokploy-BTflLhTM.mjs";
|
|
2
|
+
export { DokployDeployer };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { sanitizeComposeForPaas } from "./strip-host-ports.mjs";
|
|
2
|
-
|
|
3
2
|
//#region src/deployers/dokploy.ts
|
|
4
3
|
/**
|
|
5
4
|
* Dokploy PaaS deployer — deploys Docker Compose stacks via the Dokploy REST API.
|
|
@@ -215,7 +214,7 @@ var DokployDeployer = class {
|
|
|
215
214
|
}
|
|
216
215
|
}
|
|
217
216
|
};
|
|
218
|
-
|
|
219
217
|
//#endregion
|
|
220
218
|
export { DokployDeployer };
|
|
219
|
+
|
|
221
220
|
//# sourceMappingURL=dokploy.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dokploy.mjs","names":[],"sources":["../../src/deployers/dokploy.ts"],"sourcesContent":["/**\n * Dokploy PaaS deployer — deploys Docker Compose stacks via the Dokploy REST API.\n *\n * API docs: https://docs.dokploy.com/docs/api\n * Auth: x-api-key header\n * Endpoints use dot-notation (e.g. /api/project.create, /api/compose.deploy)\n */\n\nimport { sanitizeComposeForPaas } from \"./strip-host-ports.js\";\nimport type {\n\tDeployInput,\n\tDeployResult,\n\tDeployStep,\n\tDeployTarget,\n\tDokployEnvironment,\n\tPaasDeployer,\n\tPaasServer,\n} from \"./types.js\";\n\ninterface DokployProject {\n\tprojectId: string;\n\tname: string;\n\tdescription: string;\n\tenvironments?: DokployEnvironment[];\n}\n\ninterface DokployCompose {\n\tcomposeId: string;\n\tname: string;\n\tstatus?: string;\n\tcompose?: string;\n}\n\ninterface ProjectCreateResult {\n\tproject: DokployProject;\n\tprojectId: string;\n\tname: string;\n\tdescription: string;\n\tenvironments?: { environmentId: string; name: string }[];\n}\n\n/** Build a full Dokploy API URL from a dot-notation endpoint (e.g. \"project.create\"). */\nfunction apiUrl(target: DeployTarget, endpoint: string): string {\n\tconst base = target.instanceUrl.replace(/\\/+$/, \"\");\n\treturn `${base}/api/${endpoint}`;\n}\n/**\n * Typed fetch wrapper for the Dokploy API.\n * Handles JSON serialisation, x-api-key auth, and error extraction.\n */\nasync function dokployFetch<T>(\n\ttarget: DeployTarget,\n\tendpoint: string,\n\toptions: { method?: string; body?: unknown } = {},\n): Promise<T> {\n\tconst res = await fetch(apiUrl(target, endpoint), {\n\t\tmethod: options.method ?? \"GET\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\"x-api-key\": target.apiKey,\n\t\t},\n\t\tbody: options.body ? JSON.stringify(options.body) : undefined,\n\t});\n\n\tif (!res.ok) {\n\t\tconst text = await res.text().catch(() => \"\");\n\t\tlet detail = text;\n\n\t\ttry {\n\t\t\tconst json = JSON.parse(text);\n\t\t\tdetail = json.message || json.error || text;\n\t\t} catch {}\n\n\t\tthrow new Error(`Dokploy API ${res.status}: ${detail}`);\n\t}\n\n\tconst text = await res.text();\n\tif (!text) return undefined as T;\n\n\treturn JSON.parse(text) as T;\n}\n\n/**\n * Simple hash for compose diff detection\n */\nfunction hashString(str: string) {\n\tlet hash = 0;\n\n\tfor (let i = 0; i < str.length; i++) {\n\t\thash = (hash << 5) - hash + str.charCodeAt(i);\n\t\thash |= 0;\n\t}\n\n\treturn hash;\n}\n\n/**\n * Deploys Docker Compose stacks to a Dokploy instance.\n *\n * Deploy flow (4 steps):\n * 1. Create a Dokploy project\n * 2. Create a compose stack inside the project's default environment\n * 3. Push .env variables to the compose stack\n * 4. Trigger the deployment\n */\n\nexport class DokployDeployer implements PaasDeployer {\n\treadonly name = \"Dokploy\";\n\treadonly id = \"dokploy\";\n\n\tasync testConnection(target: DeployTarget): Promise<{ ok: boolean; error?: string }> {\n\t\ttry {\n\t\t\tawait dokployFetch<DokployProject[]>(target, \"project.all\");\n\n\t\t\treturn { ok: true };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: err instanceof Error ? err.message : String(err),\n\t\t\t};\n\t\t}\n\t}\n\n\tasync listServers(target: DeployTarget): Promise<PaasServer[]> {\n\t\ttry {\n\t\t\tconst servers = await dokployFetch<{ serverId: string; name: string; ipAddress: string }[]>(\n\t\t\t\ttarget,\n\t\t\t\t\"server.all\",\n\t\t\t);\n\t\t\treturn servers.map((s) => ({\n\t\t\t\tid: s.serverId,\n\t\t\t\tname: s.name,\n\t\t\t\tip: s.ipAddress,\n\t\t\t}));\n\t\t} catch {\n\t\t\t// Return empty list if server API is not available\n\t\t\treturn [];\n\t\t}\n\t}\n\n\tasync deploy(input: DeployInput): Promise<DeployResult> {\n\t\tconst step1: DeployStep = {\n\t\t\tstep: \"Find or create project\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step2: DeployStep = {\n\t\t\tstep: \"Find default environment\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step3: DeployStep = {\n\t\t\tstep: \"Find or create compose stack\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step4: DeployStep = {\n\t\t\tstep: \"Update stack configuration\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step5: DeployStep = { step: \"Deploy stack\", status: \"pending\" };\n\t\tconst steps: DeployStep[] = [step1, step2, step3, step4, step5];\n\n\t\tconst result: DeployResult = { success: false, steps };\n\n\t\t// Strip host port bindings — Dokploy routes via Traefik,\n\t\t// so host ports are unnecessary and cause \"port already allocated\" errors.\n\t\tconst composeYaml = sanitizeComposeForPaas(input.composeYaml);\n\n\t\ttry {\n\t\t\t/**\n\t\t\t * STEP 1\n\t\t\t * Find or create project\n\t\t\t */\n\n\t\t\tstep1.status = \"running\";\n\n\t\t\tconst projects = await dokployFetch<DokployProject[]>(input.target, \"project.all\");\n\n\t\t\tlet project = projects.find((p) => p.name === input.projectName);\n\n\t\t\tif (!project) {\n\t\t\t\tconst created = await dokployFetch<ProjectCreateResult>(input.target, \"project.create\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tname: input.projectName,\n\t\t\t\t\t\tdescription: input.description ?? `OpenClaw stack: ${input.projectName}`,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tproject = created.project;\n\t\t\t}\n\n\t\t\tresult.projectId = project.projectId;\n\n\t\t\tstep1.status = \"done\";\n\t\t\tstep1.detail = `Project ID: ${project.projectId}`;\n\n\t\t\t/**\n\t\t\t * STEP 2\n\t\t\t * Find default environment\n\t\t\t */\n\n\t\t\tstep2.status = \"running\";\n\n\t\t\tconst projectDetail = await dokployFetch<DokployProject>(\n\t\t\t\tinput.target,\n\t\t\t\t`project.one?projectId=${project.projectId}`,\n\t\t\t);\n\n\t\t\tconst env = projectDetail.environments?.find((e) => e.isDefault);\n\n\t\t\tif (!env) throw new Error(\"No default environment\");\n\n\t\t\tstep2.status = \"done\";\n\t\t\tstep2.detail = env.environmentId;\n\n\t\t\t/**\n\t\t\t * STEP 3\n\t\t\t * Find or create compose stack\n\t\t\t */\n\n\t\t\tstep3.status = \"running\";\n\n\t\t\tlet stack: DokployCompose | null = null;\n\n\t\t\tstack = await dokployFetch<DokployCompose>(input.target, \"compose.create\", {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tbody: {\n\t\t\t\t\tname: input.projectName,\n\t\t\t\t\tdescription: input.description ?? `Stack ${input.projectName}`,\n\t\t\t\t\tenvironmentId: env.environmentId,\n\t\t\t\t\tcomposeType: \"docker-compose\",\n\t\t\t\t\tcomposeFile: composeYaml,\n\t\t\t\t\t...(input.serverId ? { serverId: input.serverId } : {}),\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// Dokploy's compose.create schema does NOT accept sourceType;\n\t\t\t// it defaults to \"github\". We must update it to \"raw\" so the\n\t\t\t// deploy step writes the compose file from the stored YAML\n\t\t\t// instead of attempting to clone from a Git provider.\n\t\t\tif (stack?.composeId) {\n\t\t\t\tawait dokployFetch(input.target, \"compose.update\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tcomposeId: stack.composeId,\n\t\t\t\t\t\tsourceType: \"raw\",\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tresult.composeId = stack?.composeId;\n\t\t\tstep3.status = \"done\";\n\t\t\tstep3.detail = stack?.composeId;\n\n\t\t\t/**\n\t\t\t * STEP 4\n\t\t\t * Update stack if compose changed\n\t\t\t */\n\n\t\t\tstep4.status = \"running\";\n\n\t\t\tconst existingStack = await dokployFetch<DokployCompose>(\n\t\t\t\tinput.target,\n\t\t\t\t`compose.one?composeId=${stack?.composeId}`,\n\t\t\t);\n\n\t\t\tconst newHash = hashString(composeYaml);\n\t\t\tconst oldHash = hashString(existingStack.compose ?? \"\");\n\n\t\t\tif (newHash !== oldHash) {\n\t\t\t\tawait dokployFetch(input.target, \"compose.update\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tcomposeId: stack?.composeId,\n\t\t\t\t\t\tcomposeFile: composeYaml,\n\t\t\t\t\t\tenv: input.envContent ?? \"\",\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tstep4.detail = \"Stack updated\";\n\t\t\t} else {\n\t\t\t\tstep4.detail = \"No compose changes\";\n\t\t\t}\n\n\t\t\tstep4.status = \"done\";\n\n\t\t\t/**\n\t\t\t * STEP 5\n\t\t\t * Deploy\n\t\t\t */\n\n\t\t\tstep5.status = \"running\";\n\n\t\t\tawait dokployFetch(input.target, \"compose.deploy\", {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tbody: {\n\t\t\t\t\tcomposeId: stack?.composeId,\n\n\t\t\t\t\ttitle: `Deploy ${input.projectName}`,\n\n\t\t\t\t\tdescription: \"CI deployment\",\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tstep5.status = \"done\";\n\n\t\t\tresult.success = true;\n\n\t\t\tconst base = input.target.instanceUrl.replace(/\\/+$/, \"\");\n\n\t\t\tresult.dashboardUrl = `${base}/dashboard/project/${project.projectId}/environment/${env.environmentId}/services/compose/${stack?.composeId}?tab=deployments`;\n\n\t\t\treturn result;\n\t\t} catch (err) {\n\t\t\tconst running = steps.find((s) => s.status === \"running\");\n\n\t\t\tif (running) {\n\t\t\t\trunning.status = \"error\";\n\n\t\t\t\trunning.detail = err instanceof Error ? err.message : String(err);\n\t\t\t}\n\n\t\t\tresult.error = err instanceof Error ? err.message : String(err);\n\n\t\t\treturn result;\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dokploy.mjs","names":[],"sources":["../../src/deployers/dokploy.ts"],"sourcesContent":["/**\n * Dokploy PaaS deployer — deploys Docker Compose stacks via the Dokploy REST API.\n *\n * API docs: https://docs.dokploy.com/docs/api\n * Auth: x-api-key header\n * Endpoints use dot-notation (e.g. /api/project.create, /api/compose.deploy)\n */\n\nimport { sanitizeComposeForPaas } from \"./strip-host-ports.js\";\nimport type {\n\tDeployInput,\n\tDeployResult,\n\tDeployStep,\n\tDeployTarget,\n\tDokployEnvironment,\n\tPaasDeployer,\n\tPaasServer,\n} from \"./types.js\";\n\ninterface DokployProject {\n\tprojectId: string;\n\tname: string;\n\tdescription: string;\n\tenvironments?: DokployEnvironment[];\n}\n\ninterface DokployCompose {\n\tcomposeId: string;\n\tname: string;\n\tstatus?: string;\n\tcompose?: string;\n}\n\ninterface ProjectCreateResult {\n\tproject: DokployProject;\n\tprojectId: string;\n\tname: string;\n\tdescription: string;\n\tenvironments?: { environmentId: string; name: string }[];\n}\n\n/** Build a full Dokploy API URL from a dot-notation endpoint (e.g. \"project.create\"). */\nfunction apiUrl(target: DeployTarget, endpoint: string): string {\n\tconst base = target.instanceUrl.replace(/\\/+$/, \"\");\n\treturn `${base}/api/${endpoint}`;\n}\n/**\n * Typed fetch wrapper for the Dokploy API.\n * Handles JSON serialisation, x-api-key auth, and error extraction.\n */\nasync function dokployFetch<T>(\n\ttarget: DeployTarget,\n\tendpoint: string,\n\toptions: { method?: string; body?: unknown } = {},\n): Promise<T> {\n\tconst res = await fetch(apiUrl(target, endpoint), {\n\t\tmethod: options.method ?? \"GET\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\"x-api-key\": target.apiKey,\n\t\t},\n\t\tbody: options.body ? JSON.stringify(options.body) : undefined,\n\t});\n\n\tif (!res.ok) {\n\t\tconst text = await res.text().catch(() => \"\");\n\t\tlet detail = text;\n\n\t\ttry {\n\t\t\tconst json = JSON.parse(text);\n\t\t\tdetail = json.message || json.error || text;\n\t\t} catch {}\n\n\t\tthrow new Error(`Dokploy API ${res.status}: ${detail}`);\n\t}\n\n\tconst text = await res.text();\n\tif (!text) return undefined as T;\n\n\treturn JSON.parse(text) as T;\n}\n\n/**\n * Simple hash for compose diff detection\n */\nfunction hashString(str: string) {\n\tlet hash = 0;\n\n\tfor (let i = 0; i < str.length; i++) {\n\t\thash = (hash << 5) - hash + str.charCodeAt(i);\n\t\thash |= 0;\n\t}\n\n\treturn hash;\n}\n\n/**\n * Deploys Docker Compose stacks to a Dokploy instance.\n *\n * Deploy flow (4 steps):\n * 1. Create a Dokploy project\n * 2. Create a compose stack inside the project's default environment\n * 3. Push .env variables to the compose stack\n * 4. Trigger the deployment\n */\n\nexport class DokployDeployer implements PaasDeployer {\n\treadonly name = \"Dokploy\";\n\treadonly id = \"dokploy\";\n\n\tasync testConnection(target: DeployTarget): Promise<{ ok: boolean; error?: string }> {\n\t\ttry {\n\t\t\tawait dokployFetch<DokployProject[]>(target, \"project.all\");\n\n\t\t\treturn { ok: true };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: err instanceof Error ? err.message : String(err),\n\t\t\t};\n\t\t}\n\t}\n\n\tasync listServers(target: DeployTarget): Promise<PaasServer[]> {\n\t\ttry {\n\t\t\tconst servers = await dokployFetch<{ serverId: string; name: string; ipAddress: string }[]>(\n\t\t\t\ttarget,\n\t\t\t\t\"server.all\",\n\t\t\t);\n\t\t\treturn servers.map((s) => ({\n\t\t\t\tid: s.serverId,\n\t\t\t\tname: s.name,\n\t\t\t\tip: s.ipAddress,\n\t\t\t}));\n\t\t} catch {\n\t\t\t// Return empty list if server API is not available\n\t\t\treturn [];\n\t\t}\n\t}\n\n\tasync deploy(input: DeployInput): Promise<DeployResult> {\n\t\tconst step1: DeployStep = {\n\t\t\tstep: \"Find or create project\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step2: DeployStep = {\n\t\t\tstep: \"Find default environment\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step3: DeployStep = {\n\t\t\tstep: \"Find or create compose stack\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step4: DeployStep = {\n\t\t\tstep: \"Update stack configuration\",\n\t\t\tstatus: \"pending\",\n\t\t};\n\t\tconst step5: DeployStep = { step: \"Deploy stack\", status: \"pending\" };\n\t\tconst steps: DeployStep[] = [step1, step2, step3, step4, step5];\n\n\t\tconst result: DeployResult = { success: false, steps };\n\n\t\t// Strip host port bindings — Dokploy routes via Traefik,\n\t\t// so host ports are unnecessary and cause \"port already allocated\" errors.\n\t\tconst composeYaml = sanitizeComposeForPaas(input.composeYaml);\n\n\t\ttry {\n\t\t\t/**\n\t\t\t * STEP 1\n\t\t\t * Find or create project\n\t\t\t */\n\n\t\t\tstep1.status = \"running\";\n\n\t\t\tconst projects = await dokployFetch<DokployProject[]>(input.target, \"project.all\");\n\n\t\t\tlet project = projects.find((p) => p.name === input.projectName);\n\n\t\t\tif (!project) {\n\t\t\t\tconst created = await dokployFetch<ProjectCreateResult>(input.target, \"project.create\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tname: input.projectName,\n\t\t\t\t\t\tdescription: input.description ?? `OpenClaw stack: ${input.projectName}`,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tproject = created.project;\n\t\t\t}\n\n\t\t\tresult.projectId = project.projectId;\n\n\t\t\tstep1.status = \"done\";\n\t\t\tstep1.detail = `Project ID: ${project.projectId}`;\n\n\t\t\t/**\n\t\t\t * STEP 2\n\t\t\t * Find default environment\n\t\t\t */\n\n\t\t\tstep2.status = \"running\";\n\n\t\t\tconst projectDetail = await dokployFetch<DokployProject>(\n\t\t\t\tinput.target,\n\t\t\t\t`project.one?projectId=${project.projectId}`,\n\t\t\t);\n\n\t\t\tconst env = projectDetail.environments?.find((e) => e.isDefault);\n\n\t\t\tif (!env) throw new Error(\"No default environment\");\n\n\t\t\tstep2.status = \"done\";\n\t\t\tstep2.detail = env.environmentId;\n\n\t\t\t/**\n\t\t\t * STEP 3\n\t\t\t * Find or create compose stack\n\t\t\t */\n\n\t\t\tstep3.status = \"running\";\n\n\t\t\tlet stack: DokployCompose | null = null;\n\n\t\t\tstack = await dokployFetch<DokployCompose>(input.target, \"compose.create\", {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tbody: {\n\t\t\t\t\tname: input.projectName,\n\t\t\t\t\tdescription: input.description ?? `Stack ${input.projectName}`,\n\t\t\t\t\tenvironmentId: env.environmentId,\n\t\t\t\t\tcomposeType: \"docker-compose\",\n\t\t\t\t\tcomposeFile: composeYaml,\n\t\t\t\t\t...(input.serverId ? { serverId: input.serverId } : {}),\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// Dokploy's compose.create schema does NOT accept sourceType;\n\t\t\t// it defaults to \"github\". We must update it to \"raw\" so the\n\t\t\t// deploy step writes the compose file from the stored YAML\n\t\t\t// instead of attempting to clone from a Git provider.\n\t\t\tif (stack?.composeId) {\n\t\t\t\tawait dokployFetch(input.target, \"compose.update\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tcomposeId: stack.composeId,\n\t\t\t\t\t\tsourceType: \"raw\",\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tresult.composeId = stack?.composeId;\n\t\t\tstep3.status = \"done\";\n\t\t\tstep3.detail = stack?.composeId;\n\n\t\t\t/**\n\t\t\t * STEP 4\n\t\t\t * Update stack if compose changed\n\t\t\t */\n\n\t\t\tstep4.status = \"running\";\n\n\t\t\tconst existingStack = await dokployFetch<DokployCompose>(\n\t\t\t\tinput.target,\n\t\t\t\t`compose.one?composeId=${stack?.composeId}`,\n\t\t\t);\n\n\t\t\tconst newHash = hashString(composeYaml);\n\t\t\tconst oldHash = hashString(existingStack.compose ?? \"\");\n\n\t\t\tif (newHash !== oldHash) {\n\t\t\t\tawait dokployFetch(input.target, \"compose.update\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: {\n\t\t\t\t\t\tcomposeId: stack?.composeId,\n\t\t\t\t\t\tcomposeFile: composeYaml,\n\t\t\t\t\t\tenv: input.envContent ?? \"\",\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tstep4.detail = \"Stack updated\";\n\t\t\t} else {\n\t\t\t\tstep4.detail = \"No compose changes\";\n\t\t\t}\n\n\t\t\tstep4.status = \"done\";\n\n\t\t\t/**\n\t\t\t * STEP 5\n\t\t\t * Deploy\n\t\t\t */\n\n\t\t\tstep5.status = \"running\";\n\n\t\t\tawait dokployFetch(input.target, \"compose.deploy\", {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tbody: {\n\t\t\t\t\tcomposeId: stack?.composeId,\n\n\t\t\t\t\ttitle: `Deploy ${input.projectName}`,\n\n\t\t\t\t\tdescription: \"CI deployment\",\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tstep5.status = \"done\";\n\n\t\t\tresult.success = true;\n\n\t\t\tconst base = input.target.instanceUrl.replace(/\\/+$/, \"\");\n\n\t\t\tresult.dashboardUrl = `${base}/dashboard/project/${project.projectId}/environment/${env.environmentId}/services/compose/${stack?.composeId}?tab=deployments`;\n\n\t\t\treturn result;\n\t\t} catch (err) {\n\t\t\tconst running = steps.find((s) => s.status === \"running\");\n\n\t\t\tif (running) {\n\t\t\t\trunning.status = \"error\";\n\n\t\t\t\trunning.detail = err instanceof Error ? err.message : String(err);\n\t\t\t}\n\n\t\t\tresult.error = err instanceof Error ? err.message : String(err);\n\n\t\t\treturn result;\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
package/dist/deployers/index.cjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value:
|
|
2
|
-
const require_deployers_coolify = require(
|
|
3
|
-
const require_deployers_dokploy = require(
|
|
4
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_deployers_coolify = require("./coolify.cjs");
|
|
3
|
+
const require_deployers_dokploy = require("./dokploy.cjs");
|
|
5
4
|
//#region src/deployers/index.ts
|
|
6
5
|
/** Registry of all available PaaS deployers. */
|
|
7
6
|
const deployerRegistry = {
|
|
@@ -16,11 +15,11 @@ function getDeployer(id) {
|
|
|
16
15
|
function getAvailableDeployers() {
|
|
17
16
|
return Object.keys(deployerRegistry);
|
|
18
17
|
}
|
|
19
|
-
|
|
20
18
|
//#endregion
|
|
21
19
|
exports.CoolifyDeployer = require_deployers_coolify.CoolifyDeployer;
|
|
22
20
|
exports.DokployDeployer = require_deployers_dokploy.DokployDeployer;
|
|
23
21
|
exports.deployerRegistry = deployerRegistry;
|
|
24
22
|
exports.getAvailableDeployers = getAvailableDeployers;
|
|
25
23
|
exports.getDeployer = getDeployer;
|
|
24
|
+
|
|
26
25
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["DokployDeployer","CoolifyDeployer"],"sources":["../../src/deployers/index.ts"],"sourcesContent":["/**\n * PaaS deployer registry — barrel export + lookup helpers.\n *\n * To add a new provider, implement `PaasDeployer` and register it in\n * `deployerRegistry` below.\n */\n\nexport { CoolifyDeployer } from \"./coolify.js\";\nexport { DokployDeployer } from \"./dokploy.js\";\nexport type {\n\tDeployInput,\n\tDeployResult,\n\tDeployStep,\n\tDeployTarget,\n\tPaasDeployer,\n\tPaasServer,\n} from \"./types.js\";\n\nimport { CoolifyDeployer } from \"./coolify.js\";\nimport { DokployDeployer } from \"./dokploy.js\";\nimport type { PaasDeployer } from \"./types.js\";\n\n/** Registry of all available PaaS deployers. */\nexport const deployerRegistry: Record<string, PaasDeployer> = {\n\tdokploy: new DokployDeployer(),\n\tcoolify: new CoolifyDeployer(),\n};\n\n/** Get a deployer by ID, or undefined if not found. */\nexport function getDeployer(id: string): PaasDeployer | undefined {\n\treturn deployerRegistry[id];\n}\n\n/** List all available deployer IDs. */\nexport function getAvailableDeployers(): string[] {\n\treturn Object.keys(deployerRegistry);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["DokployDeployer","CoolifyDeployer"],"sources":["../../src/deployers/index.ts"],"sourcesContent":["/**\n * PaaS deployer registry — barrel export + lookup helpers.\n *\n * To add a new provider, implement `PaasDeployer` and register it in\n * `deployerRegistry` below.\n */\n\nexport { CoolifyDeployer } from \"./coolify.js\";\nexport { DokployDeployer } from \"./dokploy.js\";\nexport type {\n\tDeployInput,\n\tDeployResult,\n\tDeployStep,\n\tDeployTarget,\n\tPaasDeployer,\n\tPaasServer,\n} from \"./types.js\";\n\nimport { CoolifyDeployer } from \"./coolify.js\";\nimport { DokployDeployer } from \"./dokploy.js\";\nimport type { PaasDeployer } from \"./types.js\";\n\n/** Registry of all available PaaS deployers. */\nexport const deployerRegistry: Record<string, PaasDeployer> = {\n\tdokploy: new DokployDeployer(),\n\tcoolify: new CoolifyDeployer(),\n};\n\n/** Get a deployer by ID, or undefined if not found. */\nexport function getDeployer(id: string): PaasDeployer | undefined {\n\treturn deployerRegistry[id];\n}\n\n/** List all available deployer IDs. */\nexport function getAvailableDeployers(): string[] {\n\treturn Object.keys(deployerRegistry);\n}\n"],"mappings":";;;;;AAuBA,MAAa,mBAAiD;CAC7D,SAAS,IAAIA,0BAAAA,iBAAiB;CAC9B,SAAS,IAAIC,0BAAAA,iBAAiB;CAC9B;;AAGD,SAAgB,YAAY,IAAsC;AACjE,QAAO,iBAAiB;;;AAIzB,SAAgB,wBAAkC;AACjD,QAAO,OAAO,KAAK,iBAAiB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { CoolifyDeployer } from "
|
|
3
|
-
import { DokployDeployer } from "
|
|
1
|
+
import { d as PaasDeployer, f as PaasServer, i as DeployTarget, n as DeployResult, r as DeployStep, t as DeployInput } from "../types-CR83OJiq.cjs";
|
|
2
|
+
import { t as CoolifyDeployer } from "../coolify-vlb1G9V2.cjs";
|
|
3
|
+
import { t as DokployDeployer } from "../dokploy-8cbrxUun.cjs";
|
|
4
4
|
|
|
5
5
|
//#region src/deployers/index.d.ts
|
|
6
6
|
/** Registry of all available PaaS deployers. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { CoolifyDeployer } from "
|
|
3
|
-
import { DokployDeployer } from "
|
|
1
|
+
import { d as PaasDeployer, f as PaasServer, i as DeployTarget, n as DeployResult, r as DeployStep, t as DeployInput } from "../types-zYjGTuyn.mjs";
|
|
2
|
+
import { t as CoolifyDeployer } from "../coolify-BVGGcMrT.mjs";
|
|
3
|
+
import { t as DokployDeployer } from "../dokploy-BTflLhTM.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/deployers/index.d.ts
|
|
6
6
|
/** Registry of all available PaaS deployers. */
|
package/dist/deployers/index.mjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { CoolifyDeployer } from "./coolify.mjs";
|
|
2
2
|
import { DokployDeployer } from "./dokploy.mjs";
|
|
3
|
-
|
|
4
3
|
//#region src/deployers/index.ts
|
|
5
4
|
/** Registry of all available PaaS deployers. */
|
|
6
5
|
const deployerRegistry = {
|
|
@@ -15,7 +14,7 @@ function getDeployer(id) {
|
|
|
15
14
|
function getAvailableDeployers() {
|
|
16
15
|
return Object.keys(deployerRegistry);
|
|
17
16
|
}
|
|
18
|
-
|
|
19
17
|
//#endregion
|
|
20
18
|
export { CoolifyDeployer, DokployDeployer, deployerRegistry, getAvailableDeployers, getDeployer };
|
|
19
|
+
|
|
21
20
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/deployers/index.ts"],"sourcesContent":["/**\n * PaaS deployer registry — barrel export + lookup helpers.\n *\n * To add a new provider, implement `PaasDeployer` and register it in\n * `deployerRegistry` below.\n */\n\nexport { CoolifyDeployer } from \"./coolify.js\";\nexport { DokployDeployer } from \"./dokploy.js\";\nexport type {\n\tDeployInput,\n\tDeployResult,\n\tDeployStep,\n\tDeployTarget,\n\tPaasDeployer,\n\tPaasServer,\n} from \"./types.js\";\n\nimport { CoolifyDeployer } from \"./coolify.js\";\nimport { DokployDeployer } from \"./dokploy.js\";\nimport type { PaasDeployer } from \"./types.js\";\n\n/** Registry of all available PaaS deployers. */\nexport const deployerRegistry: Record<string, PaasDeployer> = {\n\tdokploy: new DokployDeployer(),\n\tcoolify: new CoolifyDeployer(),\n};\n\n/** Get a deployer by ID, or undefined if not found. */\nexport function getDeployer(id: string): PaasDeployer | undefined {\n\treturn deployerRegistry[id];\n}\n\n/** List all available deployer IDs. */\nexport function getAvailableDeployers(): string[] {\n\treturn Object.keys(deployerRegistry);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/deployers/index.ts"],"sourcesContent":["/**\n * PaaS deployer registry — barrel export + lookup helpers.\n *\n * To add a new provider, implement `PaasDeployer` and register it in\n * `deployerRegistry` below.\n */\n\nexport { CoolifyDeployer } from \"./coolify.js\";\nexport { DokployDeployer } from \"./dokploy.js\";\nexport type {\n\tDeployInput,\n\tDeployResult,\n\tDeployStep,\n\tDeployTarget,\n\tPaasDeployer,\n\tPaasServer,\n} from \"./types.js\";\n\nimport { CoolifyDeployer } from \"./coolify.js\";\nimport { DokployDeployer } from \"./dokploy.js\";\nimport type { PaasDeployer } from \"./types.js\";\n\n/** Registry of all available PaaS deployers. */\nexport const deployerRegistry: Record<string, PaasDeployer> = {\n\tdokploy: new DokployDeployer(),\n\tcoolify: new CoolifyDeployer(),\n};\n\n/** Get a deployer by ID, or undefined if not found. */\nexport function getDeployer(id: string): PaasDeployer | undefined {\n\treturn deployerRegistry[id];\n}\n\n/** List all available deployer IDs. */\nexport function getAvailableDeployers(): string[] {\n\treturn Object.keys(deployerRegistry);\n}\n"],"mappings":";;;;AAuBA,MAAa,mBAAiD;CAC7D,SAAS,IAAI,iBAAiB;CAC9B,SAAS,IAAI,iBAAiB;CAC9B;;AAGD,SAAgB,YAAY,IAAsC;AACjE,QAAO,iBAAiB;;;AAIzB,SAAgB,wBAAkC;AACjD,QAAO,OAAO,KAAK,iBAAiB"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value:
|
|
2
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../skills-BlzpHmpH.cjs");
|
|
3
3
|
let yaml = require("yaml");
|
|
4
|
-
|
|
5
4
|
//#region src/deployers/strip-host-ports.ts
|
|
6
5
|
/**
|
|
7
6
|
* Strips host port bindings from a Docker Compose YAML string.
|
|
@@ -129,10 +128,10 @@ function stripSecurityHardening(composeYaml) {
|
|
|
129
128
|
function sanitizeComposeForPaas(composeYaml) {
|
|
130
129
|
return stripSecurityHardening(stripLocalBindMounts(stripHostPorts(composeYaml)));
|
|
131
130
|
}
|
|
132
|
-
|
|
133
131
|
//#endregion
|
|
134
132
|
exports.sanitizeComposeForPaas = sanitizeComposeForPaas;
|
|
135
133
|
exports.stripHostPorts = stripHostPorts;
|
|
136
134
|
exports.stripLocalBindMounts = stripLocalBindMounts;
|
|
137
135
|
exports.stripSecurityHardening = stripSecurityHardening;
|
|
136
|
+
|
|
138
137
|
//# sourceMappingURL=strip-host-ports.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strip-host-ports.cjs","names":[],"sources":["../../src/deployers/strip-host-ports.ts"],"sourcesContent":["/**\n * Strips host port bindings from a Docker Compose YAML string.\n *\n * When deploying to a PaaS like Dokploy or Coolify, services don't need\n * host port mappings because routing is handled by the platform's built-in\n * reverse proxy (Traefik). Binding to host ports causes \"port already\n * allocated\" errors when ports are in use by other services on the server.\n *\n * Transforms port mappings:\n * \"8080:8080\" → \"8080\" (container port only)\n * \"0.0.0.0:8080:80\" → \"80\" (container port only)\n * \"8080:80/tcp\" → \"80/tcp\" (preserves protocol)\n * { published: 8080, target: 80 } → { target: 80 }\n *\n * The `expose` field is left untouched since it only defines internal ports.\n */\n\nimport { parse, stringify } from \"yaml\";\n\ninterface ComposeService {\n\tports?: (string | PortObject)[];\n\tvolumes?: (string | Record<string, unknown>)[];\n\t[key: string]: unknown;\n}\n\ninterface PortObject {\n\ttarget: number;\n\tpublished?: number | string;\n\thost_ip?: string;\n\tprotocol?: string;\n\t[key: string]: unknown;\n}\n\ninterface ComposeFile {\n\tservices?: Record<string, ComposeService>;\n\t[key: string]: unknown;\n}\n\n/**\n * Strips host port bindings from a Docker Compose YAML string,\n * keeping only the container (target) ports.\n *\n * Returns the modified YAML string.\n */\nexport function stripHostPorts(composeYaml: string): string {\n\tconst doc = parse(composeYaml) as ComposeFile;\n\n\tif (!doc?.services) return composeYaml;\n\n\tfor (const [, service] of Object.entries(doc.services)) {\n\t\tif (!service.ports || !Array.isArray(service.ports)) continue;\n\n\t\tservice.ports = service.ports.map((port) => {\n\t\t\tif (typeof port === \"string\") {\n\t\t\t\treturn stripStringPort(port);\n\t\t\t}\n\t\t\tif (typeof port === \"object\" && port !== null) {\n\t\t\t\treturn stripObjectPort(port);\n\t\t\t}\n\t\t\treturn port;\n\t\t});\n\t}\n\n\treturn stringify(doc, { lineWidth: 200 });\n}\n\n/**\n * Strips host portion from a string port mapping.\n *\n * \"8080:80\" → \"80\"\n * \"0.0.0.0:8080:80\" → \"80\"\n * \"80\" → \"80\" (no change)\n * \"80/tcp\" → \"80/tcp\"\n * \"8080:80/tcp\" → \"80/tcp\"\n */\nfunction stripStringPort(port: string): string {\n\t// Split off protocol if present (e.g. \"/tcp\", \"/udp\")\n\tconst protocolIdx = port.lastIndexOf(\"/\");\n\tlet protocol = \"\";\n\tlet portSpec = port;\n\n\tif (protocolIdx > 0) {\n\t\tprotocol = port.substring(protocolIdx); // includes the \"/\"\n\t\tportSpec = port.substring(0, protocolIdx);\n\t}\n\n\t// Split by \":\" — formats are:\n\t// \"80\" → container only\n\t// \"8080:80\" → host:container\n\t// \"0.0.0.0:8080:80\" → ip:host:container\n\tconst parts = portSpec.split(\":\");\n\n\t// Take the last part as the container port\n\tconst containerPort = parts[parts.length - 1];\n\n\treturn `${containerPort}${protocol}`;\n}\n\n/**\n * Strips host/published from an object port mapping.\n *\n * { target: 80, published: 8080 } → { target: 80 }\n */\nfunction stripObjectPort(port: PortObject): PortObject {\n\tconst { published: _, host_ip: __, ...rest } = port;\n\treturn rest;\n}\n\n/**\n * Strips local bind mounts (paths starting with `./`) from a Docker\n * Compose YAML string.\n *\n * When deploying to a PaaS like Dokploy or Coolify as a raw compose\n * stack, there is no cloned repository — so host-relative volume mounts\n * like `./postgres/init-databases.sh:/docker-entrypoint-initdb.d/...`\n * will fail because the file doesn't exist on the remote server.\n *\n * Named volumes (e.g. `redis-data:/data`) and absolute system paths\n * (e.g. `/var/run/docker.sock`) are kept intact.\n */\nexport function stripLocalBindMounts(composeYaml: string): string {\n\tconst doc = parse(composeYaml) as ComposeFile;\n\n\tif (!doc?.services) return composeYaml;\n\n\tfor (const [, service] of Object.entries(doc.services)) {\n\t\tif (!service.volumes || !Array.isArray(service.volumes)) continue;\n\n\t\tservice.volumes = (service.volumes as (string | Record<string, unknown>)[]).filter((vol) => {\n\t\t\tif (typeof vol === \"string\") {\n\t\t\t\t// Bind mounts starting with \"./\" reference local files\n\t\t\t\treturn !vol.startsWith(\"./\");\n\t\t\t}\n\t\t\t// Object-form: { type: \"bind\", source: \"./...\" }\n\t\t\tif (typeof vol === \"object\" && vol !== null) {\n\t\t\t\tconst src = (vol as Record<string, unknown>).source;\n\t\t\t\treturn !(typeof src === \"string\" && src.startsWith(\"./\"));\n\t\t\t}\n\t\t\treturn true;\n\t\t});\n\n\t\t// Remove empty volumes array to keep YAML clean\n\t\tif (service.volumes.length === 0) {\n\t\t\tdelete service.volumes;\n\t\t}\n\t}\n\n\treturn stringify(doc, { lineWidth: 200 });\n}\n\n/**\n * Strips security hardening options (`cap_drop`, `cap_add`, `security_opt`)\n * from all services in a Docker Compose YAML string.\n *\n * Many Docker images (PostgreSQL, Redis, MinIO, etc.) start as root and\n * use `gosu`/`su-exec` to drop privileges to a non-root user. This\n * requires `SETUID`, `SETGID`, and other capabilities. The hardened\n * compose output adds `cap_drop: ALL` + `no-new-privileges`, which\n * prevents this user switch and causes containers to crash with:\n * \"failed switching to 'postgres': operation not permitted\"\n *\n * PaaS platforms (Dokploy, Coolify) manage their own container security,\n * so these options are unnecessary and should be removed.\n */\nexport function stripSecurityHardening(composeYaml: string): string {\n\tconst doc = parse(composeYaml) as ComposeFile;\n\n\tif (!doc?.services) return composeYaml;\n\n\tfor (const [, service] of Object.entries(doc.services)) {\n\t\tdelete service.cap_drop;\n\t\tdelete service.cap_add;\n\t\tdelete service.security_opt;\n\t}\n\n\treturn stringify(doc, { lineWidth: 200 });\n}\n\n/**\n * Applies all PaaS-specific sanitisations to a Docker Compose YAML string:\n * 1. Strips host port bindings (avoids \"port already allocated\" errors)\n * 2. Strips local bind mounts (files don't exist on remote PaaS servers)\n * 3. Strips security hardening (cap_drop/security_opt break user switching)\n */\nexport function sanitizeComposeForPaas(composeYaml: string): string {\n\treturn stripSecurityHardening(stripLocalBindMounts(stripHostPorts(composeYaml)));\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"strip-host-ports.cjs","names":[],"sources":["../../src/deployers/strip-host-ports.ts"],"sourcesContent":["/**\n * Strips host port bindings from a Docker Compose YAML string.\n *\n * When deploying to a PaaS like Dokploy or Coolify, services don't need\n * host port mappings because routing is handled by the platform's built-in\n * reverse proxy (Traefik). Binding to host ports causes \"port already\n * allocated\" errors when ports are in use by other services on the server.\n *\n * Transforms port mappings:\n * \"8080:8080\" → \"8080\" (container port only)\n * \"0.0.0.0:8080:80\" → \"80\" (container port only)\n * \"8080:80/tcp\" → \"80/tcp\" (preserves protocol)\n * { published: 8080, target: 80 } → { target: 80 }\n *\n * The `expose` field is left untouched since it only defines internal ports.\n */\n\nimport { parse, stringify } from \"yaml\";\n\ninterface ComposeService {\n\tports?: (string | PortObject)[];\n\tvolumes?: (string | Record<string, unknown>)[];\n\t[key: string]: unknown;\n}\n\ninterface PortObject {\n\ttarget: number;\n\tpublished?: number | string;\n\thost_ip?: string;\n\tprotocol?: string;\n\t[key: string]: unknown;\n}\n\ninterface ComposeFile {\n\tservices?: Record<string, ComposeService>;\n\t[key: string]: unknown;\n}\n\n/**\n * Strips host port bindings from a Docker Compose YAML string,\n * keeping only the container (target) ports.\n *\n * Returns the modified YAML string.\n */\nexport function stripHostPorts(composeYaml: string): string {\n\tconst doc = parse(composeYaml) as ComposeFile;\n\n\tif (!doc?.services) return composeYaml;\n\n\tfor (const [, service] of Object.entries(doc.services)) {\n\t\tif (!service.ports || !Array.isArray(service.ports)) continue;\n\n\t\tservice.ports = service.ports.map((port) => {\n\t\t\tif (typeof port === \"string\") {\n\t\t\t\treturn stripStringPort(port);\n\t\t\t}\n\t\t\tif (typeof port === \"object\" && port !== null) {\n\t\t\t\treturn stripObjectPort(port);\n\t\t\t}\n\t\t\treturn port;\n\t\t});\n\t}\n\n\treturn stringify(doc, { lineWidth: 200 });\n}\n\n/**\n * Strips host portion from a string port mapping.\n *\n * \"8080:80\" → \"80\"\n * \"0.0.0.0:8080:80\" → \"80\"\n * \"80\" → \"80\" (no change)\n * \"80/tcp\" → \"80/tcp\"\n * \"8080:80/tcp\" → \"80/tcp\"\n */\nfunction stripStringPort(port: string): string {\n\t// Split off protocol if present (e.g. \"/tcp\", \"/udp\")\n\tconst protocolIdx = port.lastIndexOf(\"/\");\n\tlet protocol = \"\";\n\tlet portSpec = port;\n\n\tif (protocolIdx > 0) {\n\t\tprotocol = port.substring(protocolIdx); // includes the \"/\"\n\t\tportSpec = port.substring(0, protocolIdx);\n\t}\n\n\t// Split by \":\" — formats are:\n\t// \"80\" → container only\n\t// \"8080:80\" → host:container\n\t// \"0.0.0.0:8080:80\" → ip:host:container\n\tconst parts = portSpec.split(\":\");\n\n\t// Take the last part as the container port\n\tconst containerPort = parts[parts.length - 1];\n\n\treturn `${containerPort}${protocol}`;\n}\n\n/**\n * Strips host/published from an object port mapping.\n *\n * { target: 80, published: 8080 } → { target: 80 }\n */\nfunction stripObjectPort(port: PortObject): PortObject {\n\tconst { published: _, host_ip: __, ...rest } = port;\n\treturn rest;\n}\n\n/**\n * Strips local bind mounts (paths starting with `./`) from a Docker\n * Compose YAML string.\n *\n * When deploying to a PaaS like Dokploy or Coolify as a raw compose\n * stack, there is no cloned repository — so host-relative volume mounts\n * like `./postgres/init-databases.sh:/docker-entrypoint-initdb.d/...`\n * will fail because the file doesn't exist on the remote server.\n *\n * Named volumes (e.g. `redis-data:/data`) and absolute system paths\n * (e.g. `/var/run/docker.sock`) are kept intact.\n */\nexport function stripLocalBindMounts(composeYaml: string): string {\n\tconst doc = parse(composeYaml) as ComposeFile;\n\n\tif (!doc?.services) return composeYaml;\n\n\tfor (const [, service] of Object.entries(doc.services)) {\n\t\tif (!service.volumes || !Array.isArray(service.volumes)) continue;\n\n\t\tservice.volumes = (service.volumes as (string | Record<string, unknown>)[]).filter((vol) => {\n\t\t\tif (typeof vol === \"string\") {\n\t\t\t\t// Bind mounts starting with \"./\" reference local files\n\t\t\t\treturn !vol.startsWith(\"./\");\n\t\t\t}\n\t\t\t// Object-form: { type: \"bind\", source: \"./...\" }\n\t\t\tif (typeof vol === \"object\" && vol !== null) {\n\t\t\t\tconst src = (vol as Record<string, unknown>).source;\n\t\t\t\treturn !(typeof src === \"string\" && src.startsWith(\"./\"));\n\t\t\t}\n\t\t\treturn true;\n\t\t});\n\n\t\t// Remove empty volumes array to keep YAML clean\n\t\tif (service.volumes.length === 0) {\n\t\t\tdelete service.volumes;\n\t\t}\n\t}\n\n\treturn stringify(doc, { lineWidth: 200 });\n}\n\n/**\n * Strips security hardening options (`cap_drop`, `cap_add`, `security_opt`)\n * from all services in a Docker Compose YAML string.\n *\n * Many Docker images (PostgreSQL, Redis, MinIO, etc.) start as root and\n * use `gosu`/`su-exec` to drop privileges to a non-root user. This\n * requires `SETUID`, `SETGID`, and other capabilities. The hardened\n * compose output adds `cap_drop: ALL` + `no-new-privileges`, which\n * prevents this user switch and causes containers to crash with:\n * \"failed switching to 'postgres': operation not permitted\"\n *\n * PaaS platforms (Dokploy, Coolify) manage their own container security,\n * so these options are unnecessary and should be removed.\n */\nexport function stripSecurityHardening(composeYaml: string): string {\n\tconst doc = parse(composeYaml) as ComposeFile;\n\n\tif (!doc?.services) return composeYaml;\n\n\tfor (const [, service] of Object.entries(doc.services)) {\n\t\tdelete service.cap_drop;\n\t\tdelete service.cap_add;\n\t\tdelete service.security_opt;\n\t}\n\n\treturn stringify(doc, { lineWidth: 200 });\n}\n\n/**\n * Applies all PaaS-specific sanitisations to a Docker Compose YAML string:\n * 1. Strips host port bindings (avoids \"port already allocated\" errors)\n * 2. Strips local bind mounts (files don't exist on remote PaaS servers)\n * 3. Strips security hardening (cap_drop/security_opt break user switching)\n */\nexport function sanitizeComposeForPaas(composeYaml: string): string {\n\treturn stripSecurityHardening(stripLocalBindMounts(stripHostPorts(composeYaml)));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,SAAgB,eAAe,aAA6B;CAC3D,MAAM,OAAA,GAAA,KAAA,OAAY,YAAY;AAE9B,KAAI,CAAC,KAAK,SAAU,QAAO;AAE3B,MAAK,MAAM,GAAG,YAAY,OAAO,QAAQ,IAAI,SAAS,EAAE;AACvD,MAAI,CAAC,QAAQ,SAAS,CAAC,MAAM,QAAQ,QAAQ,MAAM,CAAE;AAErD,UAAQ,QAAQ,QAAQ,MAAM,KAAK,SAAS;AAC3C,OAAI,OAAO,SAAS,SACnB,QAAO,gBAAgB,KAAK;AAE7B,OAAI,OAAO,SAAS,YAAY,SAAS,KACxC,QAAO,gBAAgB,KAAK;AAE7B,UAAO;IACN;;AAGH,SAAA,GAAA,KAAA,WAAiB,KAAK,EAAE,WAAW,KAAK,CAAC;;;;;;;;;;;AAY1C,SAAS,gBAAgB,MAAsB;CAE9C,MAAM,cAAc,KAAK,YAAY,IAAI;CACzC,IAAI,WAAW;CACf,IAAI,WAAW;AAEf,KAAI,cAAc,GAAG;AACpB,aAAW,KAAK,UAAU,YAAY;AACtC,aAAW,KAAK,UAAU,GAAG,YAAY;;CAO1C,MAAM,QAAQ,SAAS,MAAM,IAAI;AAKjC,QAAO,GAFe,MAAM,MAAM,SAAS,KAEjB;;;;;;;AAQ3B,SAAS,gBAAgB,MAA8B;CACtD,MAAM,EAAE,WAAW,GAAG,SAAS,IAAI,GAAG,SAAS;AAC/C,QAAO;;;;;;;;;;;;;;AAeR,SAAgB,qBAAqB,aAA6B;CACjE,MAAM,OAAA,GAAA,KAAA,OAAY,YAAY;AAE9B,KAAI,CAAC,KAAK,SAAU,QAAO;AAE3B,MAAK,MAAM,GAAG,YAAY,OAAO,QAAQ,IAAI,SAAS,EAAE;AACvD,MAAI,CAAC,QAAQ,WAAW,CAAC,MAAM,QAAQ,QAAQ,QAAQ,CAAE;AAEzD,UAAQ,UAAW,QAAQ,QAAiD,QAAQ,QAAQ;AAC3F,OAAI,OAAO,QAAQ,SAElB,QAAO,CAAC,IAAI,WAAW,KAAK;AAG7B,OAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;IAC5C,MAAM,MAAO,IAAgC;AAC7C,WAAO,EAAE,OAAO,QAAQ,YAAY,IAAI,WAAW,KAAK;;AAEzD,UAAO;IACN;AAGF,MAAI,QAAQ,QAAQ,WAAW,EAC9B,QAAO,QAAQ;;AAIjB,SAAA,GAAA,KAAA,WAAiB,KAAK,EAAE,WAAW,KAAK,CAAC;;;;;;;;;;;;;;;;AAiB1C,SAAgB,uBAAuB,aAA6B;CACnE,MAAM,OAAA,GAAA,KAAA,OAAY,YAAY;AAE9B,KAAI,CAAC,KAAK,SAAU,QAAO;AAE3B,MAAK,MAAM,GAAG,YAAY,OAAO,QAAQ,IAAI,SAAS,EAAE;AACvD,SAAO,QAAQ;AACf,SAAO,QAAQ;AACf,SAAO,QAAQ;;AAGhB,SAAA,GAAA,KAAA,WAAiB,KAAK,EAAE,WAAW,KAAK,CAAC;;;;;;;;AAS1C,SAAgB,uBAAuB,aAA6B;AACnE,QAAO,uBAAuB,qBAAqB,eAAe,YAAY,CAAC,CAAC"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { parse, stringify } from "yaml";
|
|
2
|
-
|
|
3
2
|
//#region src/deployers/strip-host-ports.ts
|
|
4
3
|
/**
|
|
5
4
|
* Strips host port bindings from a Docker Compose YAML string.
|
|
@@ -127,7 +126,7 @@ function stripSecurityHardening(composeYaml) {
|
|
|
127
126
|
function sanitizeComposeForPaas(composeYaml) {
|
|
128
127
|
return stripSecurityHardening(stripLocalBindMounts(stripHostPorts(composeYaml)));
|
|
129
128
|
}
|
|
130
|
-
|
|
131
129
|
//#endregion
|
|
132
130
|
export { sanitizeComposeForPaas, stripHostPorts, stripLocalBindMounts, stripSecurityHardening };
|
|
131
|
+
|
|
133
132
|
//# sourceMappingURL=strip-host-ports.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strip-host-ports.mjs","names":[],"sources":["../../src/deployers/strip-host-ports.ts"],"sourcesContent":["/**\n * Strips host port bindings from a Docker Compose YAML string.\n *\n * When deploying to a PaaS like Dokploy or Coolify, services don't need\n * host port mappings because routing is handled by the platform's built-in\n * reverse proxy (Traefik). Binding to host ports causes \"port already\n * allocated\" errors when ports are in use by other services on the server.\n *\n * Transforms port mappings:\n * \"8080:8080\" → \"8080\" (container port only)\n * \"0.0.0.0:8080:80\" → \"80\" (container port only)\n * \"8080:80/tcp\" → \"80/tcp\" (preserves protocol)\n * { published: 8080, target: 80 } → { target: 80 }\n *\n * The `expose` field is left untouched since it only defines internal ports.\n */\n\nimport { parse, stringify } from \"yaml\";\n\ninterface ComposeService {\n\tports?: (string | PortObject)[];\n\tvolumes?: (string | Record<string, unknown>)[];\n\t[key: string]: unknown;\n}\n\ninterface PortObject {\n\ttarget: number;\n\tpublished?: number | string;\n\thost_ip?: string;\n\tprotocol?: string;\n\t[key: string]: unknown;\n}\n\ninterface ComposeFile {\n\tservices?: Record<string, ComposeService>;\n\t[key: string]: unknown;\n}\n\n/**\n * Strips host port bindings from a Docker Compose YAML string,\n * keeping only the container (target) ports.\n *\n * Returns the modified YAML string.\n */\nexport function stripHostPorts(composeYaml: string): string {\n\tconst doc = parse(composeYaml) as ComposeFile;\n\n\tif (!doc?.services) return composeYaml;\n\n\tfor (const [, service] of Object.entries(doc.services)) {\n\t\tif (!service.ports || !Array.isArray(service.ports)) continue;\n\n\t\tservice.ports = service.ports.map((port) => {\n\t\t\tif (typeof port === \"string\") {\n\t\t\t\treturn stripStringPort(port);\n\t\t\t}\n\t\t\tif (typeof port === \"object\" && port !== null) {\n\t\t\t\treturn stripObjectPort(port);\n\t\t\t}\n\t\t\treturn port;\n\t\t});\n\t}\n\n\treturn stringify(doc, { lineWidth: 200 });\n}\n\n/**\n * Strips host portion from a string port mapping.\n *\n * \"8080:80\" → \"80\"\n * \"0.0.0.0:8080:80\" → \"80\"\n * \"80\" → \"80\" (no change)\n * \"80/tcp\" → \"80/tcp\"\n * \"8080:80/tcp\" → \"80/tcp\"\n */\nfunction stripStringPort(port: string): string {\n\t// Split off protocol if present (e.g. \"/tcp\", \"/udp\")\n\tconst protocolIdx = port.lastIndexOf(\"/\");\n\tlet protocol = \"\";\n\tlet portSpec = port;\n\n\tif (protocolIdx > 0) {\n\t\tprotocol = port.substring(protocolIdx); // includes the \"/\"\n\t\tportSpec = port.substring(0, protocolIdx);\n\t}\n\n\t// Split by \":\" — formats are:\n\t// \"80\" → container only\n\t// \"8080:80\" → host:container\n\t// \"0.0.0.0:8080:80\" → ip:host:container\n\tconst parts = portSpec.split(\":\");\n\n\t// Take the last part as the container port\n\tconst containerPort = parts[parts.length - 1];\n\n\treturn `${containerPort}${protocol}`;\n}\n\n/**\n * Strips host/published from an object port mapping.\n *\n * { target: 80, published: 8080 } → { target: 80 }\n */\nfunction stripObjectPort(port: PortObject): PortObject {\n\tconst { published: _, host_ip: __, ...rest } = port;\n\treturn rest;\n}\n\n/**\n * Strips local bind mounts (paths starting with `./`) from a Docker\n * Compose YAML string.\n *\n * When deploying to a PaaS like Dokploy or Coolify as a raw compose\n * stack, there is no cloned repository — so host-relative volume mounts\n * like `./postgres/init-databases.sh:/docker-entrypoint-initdb.d/...`\n * will fail because the file doesn't exist on the remote server.\n *\n * Named volumes (e.g. `redis-data:/data`) and absolute system paths\n * (e.g. `/var/run/docker.sock`) are kept intact.\n */\nexport function stripLocalBindMounts(composeYaml: string): string {\n\tconst doc = parse(composeYaml) as ComposeFile;\n\n\tif (!doc?.services) return composeYaml;\n\n\tfor (const [, service] of Object.entries(doc.services)) {\n\t\tif (!service.volumes || !Array.isArray(service.volumes)) continue;\n\n\t\tservice.volumes = (service.volumes as (string | Record<string, unknown>)[]).filter((vol) => {\n\t\t\tif (typeof vol === \"string\") {\n\t\t\t\t// Bind mounts starting with \"./\" reference local files\n\t\t\t\treturn !vol.startsWith(\"./\");\n\t\t\t}\n\t\t\t// Object-form: { type: \"bind\", source: \"./...\" }\n\t\t\tif (typeof vol === \"object\" && vol !== null) {\n\t\t\t\tconst src = (vol as Record<string, unknown>).source;\n\t\t\t\treturn !(typeof src === \"string\" && src.startsWith(\"./\"));\n\t\t\t}\n\t\t\treturn true;\n\t\t});\n\n\t\t// Remove empty volumes array to keep YAML clean\n\t\tif (service.volumes.length === 0) {\n\t\t\tdelete service.volumes;\n\t\t}\n\t}\n\n\treturn stringify(doc, { lineWidth: 200 });\n}\n\n/**\n * Strips security hardening options (`cap_drop`, `cap_add`, `security_opt`)\n * from all services in a Docker Compose YAML string.\n *\n * Many Docker images (PostgreSQL, Redis, MinIO, etc.) start as root and\n * use `gosu`/`su-exec` to drop privileges to a non-root user. This\n * requires `SETUID`, `SETGID`, and other capabilities. The hardened\n * compose output adds `cap_drop: ALL` + `no-new-privileges`, which\n * prevents this user switch and causes containers to crash with:\n * \"failed switching to 'postgres': operation not permitted\"\n *\n * PaaS platforms (Dokploy, Coolify) manage their own container security,\n * so these options are unnecessary and should be removed.\n */\nexport function stripSecurityHardening(composeYaml: string): string {\n\tconst doc = parse(composeYaml) as ComposeFile;\n\n\tif (!doc?.services) return composeYaml;\n\n\tfor (const [, service] of Object.entries(doc.services)) {\n\t\tdelete service.cap_drop;\n\t\tdelete service.cap_add;\n\t\tdelete service.security_opt;\n\t}\n\n\treturn stringify(doc, { lineWidth: 200 });\n}\n\n/**\n * Applies all PaaS-specific sanitisations to a Docker Compose YAML string:\n * 1. Strips host port bindings (avoids \"port already allocated\" errors)\n * 2. Strips local bind mounts (files don't exist on remote PaaS servers)\n * 3. Strips security hardening (cap_drop/security_opt break user switching)\n */\nexport function sanitizeComposeForPaas(composeYaml: string): string {\n\treturn stripSecurityHardening(stripLocalBindMounts(stripHostPorts(composeYaml)));\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"strip-host-ports.mjs","names":[],"sources":["../../src/deployers/strip-host-ports.ts"],"sourcesContent":["/**\n * Strips host port bindings from a Docker Compose YAML string.\n *\n * When deploying to a PaaS like Dokploy or Coolify, services don't need\n * host port mappings because routing is handled by the platform's built-in\n * reverse proxy (Traefik). Binding to host ports causes \"port already\n * allocated\" errors when ports are in use by other services on the server.\n *\n * Transforms port mappings:\n * \"8080:8080\" → \"8080\" (container port only)\n * \"0.0.0.0:8080:80\" → \"80\" (container port only)\n * \"8080:80/tcp\" → \"80/tcp\" (preserves protocol)\n * { published: 8080, target: 80 } → { target: 80 }\n *\n * The `expose` field is left untouched since it only defines internal ports.\n */\n\nimport { parse, stringify } from \"yaml\";\n\ninterface ComposeService {\n\tports?: (string | PortObject)[];\n\tvolumes?: (string | Record<string, unknown>)[];\n\t[key: string]: unknown;\n}\n\ninterface PortObject {\n\ttarget: number;\n\tpublished?: number | string;\n\thost_ip?: string;\n\tprotocol?: string;\n\t[key: string]: unknown;\n}\n\ninterface ComposeFile {\n\tservices?: Record<string, ComposeService>;\n\t[key: string]: unknown;\n}\n\n/**\n * Strips host port bindings from a Docker Compose YAML string,\n * keeping only the container (target) ports.\n *\n * Returns the modified YAML string.\n */\nexport function stripHostPorts(composeYaml: string): string {\n\tconst doc = parse(composeYaml) as ComposeFile;\n\n\tif (!doc?.services) return composeYaml;\n\n\tfor (const [, service] of Object.entries(doc.services)) {\n\t\tif (!service.ports || !Array.isArray(service.ports)) continue;\n\n\t\tservice.ports = service.ports.map((port) => {\n\t\t\tif (typeof port === \"string\") {\n\t\t\t\treturn stripStringPort(port);\n\t\t\t}\n\t\t\tif (typeof port === \"object\" && port !== null) {\n\t\t\t\treturn stripObjectPort(port);\n\t\t\t}\n\t\t\treturn port;\n\t\t});\n\t}\n\n\treturn stringify(doc, { lineWidth: 200 });\n}\n\n/**\n * Strips host portion from a string port mapping.\n *\n * \"8080:80\" → \"80\"\n * \"0.0.0.0:8080:80\" → \"80\"\n * \"80\" → \"80\" (no change)\n * \"80/tcp\" → \"80/tcp\"\n * \"8080:80/tcp\" → \"80/tcp\"\n */\nfunction stripStringPort(port: string): string {\n\t// Split off protocol if present (e.g. \"/tcp\", \"/udp\")\n\tconst protocolIdx = port.lastIndexOf(\"/\");\n\tlet protocol = \"\";\n\tlet portSpec = port;\n\n\tif (protocolIdx > 0) {\n\t\tprotocol = port.substring(protocolIdx); // includes the \"/\"\n\t\tportSpec = port.substring(0, protocolIdx);\n\t}\n\n\t// Split by \":\" — formats are:\n\t// \"80\" → container only\n\t// \"8080:80\" → host:container\n\t// \"0.0.0.0:8080:80\" → ip:host:container\n\tconst parts = portSpec.split(\":\");\n\n\t// Take the last part as the container port\n\tconst containerPort = parts[parts.length - 1];\n\n\treturn `${containerPort}${protocol}`;\n}\n\n/**\n * Strips host/published from an object port mapping.\n *\n * { target: 80, published: 8080 } → { target: 80 }\n */\nfunction stripObjectPort(port: PortObject): PortObject {\n\tconst { published: _, host_ip: __, ...rest } = port;\n\treturn rest;\n}\n\n/**\n * Strips local bind mounts (paths starting with `./`) from a Docker\n * Compose YAML string.\n *\n * When deploying to a PaaS like Dokploy or Coolify as a raw compose\n * stack, there is no cloned repository — so host-relative volume mounts\n * like `./postgres/init-databases.sh:/docker-entrypoint-initdb.d/...`\n * will fail because the file doesn't exist on the remote server.\n *\n * Named volumes (e.g. `redis-data:/data`) and absolute system paths\n * (e.g. `/var/run/docker.sock`) are kept intact.\n */\nexport function stripLocalBindMounts(composeYaml: string): string {\n\tconst doc = parse(composeYaml) as ComposeFile;\n\n\tif (!doc?.services) return composeYaml;\n\n\tfor (const [, service] of Object.entries(doc.services)) {\n\t\tif (!service.volumes || !Array.isArray(service.volumes)) continue;\n\n\t\tservice.volumes = (service.volumes as (string | Record<string, unknown>)[]).filter((vol) => {\n\t\t\tif (typeof vol === \"string\") {\n\t\t\t\t// Bind mounts starting with \"./\" reference local files\n\t\t\t\treturn !vol.startsWith(\"./\");\n\t\t\t}\n\t\t\t// Object-form: { type: \"bind\", source: \"./...\" }\n\t\t\tif (typeof vol === \"object\" && vol !== null) {\n\t\t\t\tconst src = (vol as Record<string, unknown>).source;\n\t\t\t\treturn !(typeof src === \"string\" && src.startsWith(\"./\"));\n\t\t\t}\n\t\t\treturn true;\n\t\t});\n\n\t\t// Remove empty volumes array to keep YAML clean\n\t\tif (service.volumes.length === 0) {\n\t\t\tdelete service.volumes;\n\t\t}\n\t}\n\n\treturn stringify(doc, { lineWidth: 200 });\n}\n\n/**\n * Strips security hardening options (`cap_drop`, `cap_add`, `security_opt`)\n * from all services in a Docker Compose YAML string.\n *\n * Many Docker images (PostgreSQL, Redis, MinIO, etc.) start as root and\n * use `gosu`/`su-exec` to drop privileges to a non-root user. This\n * requires `SETUID`, `SETGID`, and other capabilities. The hardened\n * compose output adds `cap_drop: ALL` + `no-new-privileges`, which\n * prevents this user switch and causes containers to crash with:\n * \"failed switching to 'postgres': operation not permitted\"\n *\n * PaaS platforms (Dokploy, Coolify) manage their own container security,\n * so these options are unnecessary and should be removed.\n */\nexport function stripSecurityHardening(composeYaml: string): string {\n\tconst doc = parse(composeYaml) as ComposeFile;\n\n\tif (!doc?.services) return composeYaml;\n\n\tfor (const [, service] of Object.entries(doc.services)) {\n\t\tdelete service.cap_drop;\n\t\tdelete service.cap_add;\n\t\tdelete service.security_opt;\n\t}\n\n\treturn stringify(doc, { lineWidth: 200 });\n}\n\n/**\n * Applies all PaaS-specific sanitisations to a Docker Compose YAML string:\n * 1. Strips host port bindings (avoids \"port already allocated\" errors)\n * 2. Strips local bind mounts (files don't exist on remote PaaS servers)\n * 3. Strips security hardening (cap_drop/security_opt break user switching)\n */\nexport function sanitizeComposeForPaas(composeYaml: string): string {\n\treturn stripSecurityHardening(stripLocalBindMounts(stripHostPorts(composeYaml)));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA4CA,SAAgB,eAAe,aAA6B;CAC3D,MAAM,MAAM,MAAM,YAAY;AAE9B,KAAI,CAAC,KAAK,SAAU,QAAO;AAE3B,MAAK,MAAM,GAAG,YAAY,OAAO,QAAQ,IAAI,SAAS,EAAE;AACvD,MAAI,CAAC,QAAQ,SAAS,CAAC,MAAM,QAAQ,QAAQ,MAAM,CAAE;AAErD,UAAQ,QAAQ,QAAQ,MAAM,KAAK,SAAS;AAC3C,OAAI,OAAO,SAAS,SACnB,QAAO,gBAAgB,KAAK;AAE7B,OAAI,OAAO,SAAS,YAAY,SAAS,KACxC,QAAO,gBAAgB,KAAK;AAE7B,UAAO;IACN;;AAGH,QAAO,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;;;;;;;;;;;AAY1C,SAAS,gBAAgB,MAAsB;CAE9C,MAAM,cAAc,KAAK,YAAY,IAAI;CACzC,IAAI,WAAW;CACf,IAAI,WAAW;AAEf,KAAI,cAAc,GAAG;AACpB,aAAW,KAAK,UAAU,YAAY;AACtC,aAAW,KAAK,UAAU,GAAG,YAAY;;CAO1C,MAAM,QAAQ,SAAS,MAAM,IAAI;AAKjC,QAAO,GAFe,MAAM,MAAM,SAAS,KAEjB;;;;;;;AAQ3B,SAAS,gBAAgB,MAA8B;CACtD,MAAM,EAAE,WAAW,GAAG,SAAS,IAAI,GAAG,SAAS;AAC/C,QAAO;;;;;;;;;;;;;;AAeR,SAAgB,qBAAqB,aAA6B;CACjE,MAAM,MAAM,MAAM,YAAY;AAE9B,KAAI,CAAC,KAAK,SAAU,QAAO;AAE3B,MAAK,MAAM,GAAG,YAAY,OAAO,QAAQ,IAAI,SAAS,EAAE;AACvD,MAAI,CAAC,QAAQ,WAAW,CAAC,MAAM,QAAQ,QAAQ,QAAQ,CAAE;AAEzD,UAAQ,UAAW,QAAQ,QAAiD,QAAQ,QAAQ;AAC3F,OAAI,OAAO,QAAQ,SAElB,QAAO,CAAC,IAAI,WAAW,KAAK;AAG7B,OAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;IAC5C,MAAM,MAAO,IAAgC;AAC7C,WAAO,EAAE,OAAO,QAAQ,YAAY,IAAI,WAAW,KAAK;;AAEzD,UAAO;IACN;AAGF,MAAI,QAAQ,QAAQ,WAAW,EAC9B,QAAO,QAAQ;;AAIjB,QAAO,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;;;;;;;;;;;;;;;;AAiB1C,SAAgB,uBAAuB,aAA6B;CACnE,MAAM,MAAM,MAAM,YAAY;AAE9B,KAAI,CAAC,KAAK,SAAU,QAAO;AAE3B,MAAK,MAAM,GAAG,YAAY,OAAO,QAAQ,IAAI,SAAS,EAAE;AACvD,SAAO,QAAQ;AACf,SAAO,QAAQ;AACf,SAAO,QAAQ;;AAGhB,QAAO,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;;;;;;;;AAS1C,SAAgB,uBAAuB,aAA6B;AACnE,QAAO,uBAAuB,qBAAqB,eAAe,YAAY,CAAC,CAAC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
const require_vi_2VT5v0um = require(
|
|
2
|
-
const require_deployers_strip_host_ports = require(
|
|
3
|
-
|
|
1
|
+
const require_vi_2VT5v0um = require("../vi.2VT5v0um-CRqXre87.cjs");
|
|
2
|
+
const require_deployers_strip_host_ports = require("./strip-host-ports.cjs");
|
|
4
3
|
//#region src/deployers/strip-host-ports.test.ts
|
|
5
4
|
require_vi_2VT5v0um.describe("stripHostPorts", () => {
|
|
6
5
|
require_vi_2VT5v0um.it("strips host port from short syntax (host:container)", () => {
|
|
@@ -84,6 +83,6 @@ services:
|
|
|
84
83
|
`)).toContain("nginx");
|
|
85
84
|
});
|
|
86
85
|
});
|
|
87
|
-
|
|
88
86
|
//#endregion
|
|
87
|
+
|
|
89
88
|
//# sourceMappingURL=strip-host-ports.test.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strip-host-ports.test.cjs","names":["describe","stripHostPorts"],"sources":["../../src/deployers/strip-host-ports.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { stripHostPorts } from \"./strip-host-ports.js\";\n\ndescribe(\"stripHostPorts\", () => {\n\tit(\"strips host port from short syntax (host:container)\", () => {\n\t\tconst yaml = `\nservices:\n web:\n image: nginx\n ports:\n - \"8080:80\"\n - \"443:443\"\n`;\n\t\tconst result = stripHostPorts(yaml);\n\t\texpect(result).toContain('\"80\"');\n\t\texpect(result).toContain('\"443\"');\n\t\texpect(result).not.toContain(\"8080\");\n\t});\n\n\tit(\"strips host IP and port from extended short syntax\", () => {\n\t\tconst yaml = `\nservices:\n web:\n image: nginx\n ports:\n - \"0.0.0.0:8080:80\"\n`;\n\t\tconst result = stripHostPorts(yaml);\n\t\texpect(result).toContain('\"80\"');\n\t\texpect(result).not.toContain(\"8080\");\n\t\texpect(result).not.toContain(\"0.0.0.0\");\n\t});\n\n\tit(\"preserves protocol suffix\", () => {\n\t\tconst yaml = `\nservices:\n web:\n image: nginx\n ports:\n - \"8080:80/tcp\"\n - \"5353:53/udp\"\n`;\n\t\tconst result = stripHostPorts(yaml);\n\t\texpect(result).toContain(\"80/tcp\");\n\t\texpect(result).toContain(\"53/udp\");\n\t\texpect(result).not.toContain(\"8080\");\n\t\texpect(result).not.toContain(\"5353\");\n\t});\n\n\tit(\"keeps container-only ports unchanged\", () => {\n\t\tconst yaml = `\nservices:\n web:\n image: nginx\n ports:\n - \"80\"\n`;\n\t\tconst result = stripHostPorts(yaml);\n\t\texpect(result).toContain('\"80\"');\n\t});\n\n\tit(\"handles multiple services\", () => {\n\t\tconst yaml = `\nservices:\n web:\n image: nginx\n ports:\n - \"8080:80\"\n redis:\n image: redis\n ports:\n - \"6379:6379\"\n searxng:\n image: searxng/searxng\n ports:\n - \"8888:8080\"\n`;\n\t\tconst result = stripHostPorts(yaml);\n\t\texpect(result).toContain('\"80\"');\n\t\texpect(result).toContain('\"6379\"');\n\t\texpect(result).toContain('\"8080\"');\n\t\texpect(result).not.toContain(\"8888\");\n\t});\n\n\tit(\"returns original YAML if no services section\", () => {\n\t\tconst yaml = `version: \"3\"`;\n\t\tconst result = stripHostPorts(yaml);\n\t\texpect(result).toBe(yaml);\n\t});\n\n\tit(\"handles services with no ports\", () => {\n\t\tconst yaml = `\nservices:\n web:\n image: nginx\n`;\n\t\tconst result = stripHostPorts(yaml);\n\t\texpect(result).toContain(\"nginx\");\n\t});\n});\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"strip-host-ports.test.cjs","names":["describe","stripHostPorts"],"sources":["../../src/deployers/strip-host-ports.test.ts"],"sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { stripHostPorts } from \"./strip-host-ports.js\";\n\ndescribe(\"stripHostPorts\", () => {\n\tit(\"strips host port from short syntax (host:container)\", () => {\n\t\tconst yaml = `\nservices:\n web:\n image: nginx\n ports:\n - \"8080:80\"\n - \"443:443\"\n`;\n\t\tconst result = stripHostPorts(yaml);\n\t\texpect(result).toContain('\"80\"');\n\t\texpect(result).toContain('\"443\"');\n\t\texpect(result).not.toContain(\"8080\");\n\t});\n\n\tit(\"strips host IP and port from extended short syntax\", () => {\n\t\tconst yaml = `\nservices:\n web:\n image: nginx\n ports:\n - \"0.0.0.0:8080:80\"\n`;\n\t\tconst result = stripHostPorts(yaml);\n\t\texpect(result).toContain('\"80\"');\n\t\texpect(result).not.toContain(\"8080\");\n\t\texpect(result).not.toContain(\"0.0.0.0\");\n\t});\n\n\tit(\"preserves protocol suffix\", () => {\n\t\tconst yaml = `\nservices:\n web:\n image: nginx\n ports:\n - \"8080:80/tcp\"\n - \"5353:53/udp\"\n`;\n\t\tconst result = stripHostPorts(yaml);\n\t\texpect(result).toContain(\"80/tcp\");\n\t\texpect(result).toContain(\"53/udp\");\n\t\texpect(result).not.toContain(\"8080\");\n\t\texpect(result).not.toContain(\"5353\");\n\t});\n\n\tit(\"keeps container-only ports unchanged\", () => {\n\t\tconst yaml = `\nservices:\n web:\n image: nginx\n ports:\n - \"80\"\n`;\n\t\tconst result = stripHostPorts(yaml);\n\t\texpect(result).toContain('\"80\"');\n\t});\n\n\tit(\"handles multiple services\", () => {\n\t\tconst yaml = `\nservices:\n web:\n image: nginx\n ports:\n - \"8080:80\"\n redis:\n image: redis\n ports:\n - \"6379:6379\"\n searxng:\n image: searxng/searxng\n ports:\n - \"8888:8080\"\n`;\n\t\tconst result = stripHostPorts(yaml);\n\t\texpect(result).toContain('\"80\"');\n\t\texpect(result).toContain('\"6379\"');\n\t\texpect(result).toContain('\"8080\"');\n\t\texpect(result).not.toContain(\"8888\");\n\t});\n\n\tit(\"returns original YAML if no services section\", () => {\n\t\tconst yaml = `version: \"3\"`;\n\t\tconst result = stripHostPorts(yaml);\n\t\texpect(result).toBe(yaml);\n\t});\n\n\tit(\"handles services with no ports\", () => {\n\t\tconst yaml = `\nservices:\n web:\n image: nginx\n`;\n\t\tconst result = stripHostPorts(yaml);\n\t\texpect(result).toContain(\"nginx\");\n\t});\n});\n"],"mappings":";;;AAGAA,oBAAAA,SAAS,wBAAwB;AAChC,qBAAA,GAAG,6DAA6D;EAS/D,MAAM,SAASC,mCAAAA,eARF;;;;;;;EAQsB;AACnC,sBAAA,aAAO,OAAO,CAAC,UAAU,SAAO;AAChC,sBAAA,aAAO,OAAO,CAAC,UAAU,UAAQ;AACjC,sBAAA,aAAO,OAAO,CAAC,IAAI,UAAU,OAAO;GACnC;AAEF,qBAAA,GAAG,4DAA4D;EAQ9D,MAAM,SAASA,mCAAAA,eAPF;;;;;;EAOsB;AACnC,sBAAA,aAAO,OAAO,CAAC,UAAU,SAAO;AAChC,sBAAA,aAAO,OAAO,CAAC,IAAI,UAAU,OAAO;AACpC,sBAAA,aAAO,OAAO,CAAC,IAAI,UAAU,UAAU;GACtC;AAEF,qBAAA,GAAG,mCAAmC;EASrC,MAAM,SAASA,mCAAAA,eARF;;;;;;;EAQsB;AACnC,sBAAA,aAAO,OAAO,CAAC,UAAU,SAAS;AAClC,sBAAA,aAAO,OAAO,CAAC,UAAU,SAAS;AAClC,sBAAA,aAAO,OAAO,CAAC,IAAI,UAAU,OAAO;AACpC,sBAAA,aAAO,OAAO,CAAC,IAAI,UAAU,OAAO;GACnC;AAEF,qBAAA,GAAG,8CAA8C;AAShD,sBAAA,aADeA,mCAAAA,eAPF;;;;;;EAOsB,CACrB,CAAC,UAAU,SAAO;GAC/B;AAEF,qBAAA,GAAG,mCAAmC;EAgBrC,MAAM,SAASA,mCAAAA,eAfF;;;;;;;;;;;;;;EAesB;AACnC,sBAAA,aAAO,OAAO,CAAC,UAAU,SAAO;AAChC,sBAAA,aAAO,OAAO,CAAC,UAAU,WAAS;AAClC,sBAAA,aAAO,OAAO,CAAC,UAAU,WAAS;AAClC,sBAAA,aAAO,OAAO,CAAC,IAAI,UAAU,OAAO;GACnC;AAEF,qBAAA,GAAG,sDAAsD;EACxD,MAAM,OAAO;AAEb,sBAAA,aADeA,mCAAAA,eAAe,KAAK,CACrB,CAAC,KAAK,KAAK;GACxB;AAEF,qBAAA,GAAG,wCAAwC;AAO1C,sBAAA,aADeA,mCAAAA,eALF;;;;EAKsB,CACrB,CAAC,UAAU,QAAQ;GAChC;EACD"}
|