@vibesdotdev/infra-doks 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -0
- package/SPEC.md +285 -0
- package/dist/client/digitalocean-app-deploy.client.d.ts +46 -0
- package/dist/client/digitalocean-app-deploy.client.d.ts.map +1 -0
- package/dist/client/digitalocean-app-deploy.client.js +135 -0
- package/dist/client/digitalocean-app-deploy.client.js.map +1 -0
- package/dist/client/index.d.ts +15 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +18 -0
- package/dist/client/index.js.map +1 -0
- package/dist/cloud/base.d.ts +33 -0
- package/dist/cloud/base.d.ts.map +1 -0
- package/dist/cloud/base.js +86 -0
- package/dist/cloud/base.js.map +1 -0
- package/dist/cloud/digitalocean.d.ts +33 -0
- package/dist/cloud/digitalocean.d.ts.map +1 -0
- package/dist/cloud/digitalocean.js +258 -0
- package/dist/cloud/digitalocean.js.map +1 -0
- package/dist/cloud/factory.d.ts +28 -0
- package/dist/cloud/factory.d.ts.map +1 -0
- package/dist/cloud/factory.js +151 -0
- package/dist/cloud/factory.js.map +1 -0
- package/dist/cloud/index.d.ts +12 -0
- package/dist/cloud/index.d.ts.map +1 -0
- package/dist/cloud/index.js +11 -0
- package/dist/cloud/index.js.map +1 -0
- package/dist/doks.plugin.d.ts +41 -0
- package/dist/doks.plugin.d.ts.map +1 -0
- package/dist/doks.plugin.js +287 -0
- package/dist/doks.plugin.js.map +1 -0
- package/dist/implementations/deployment.impl.d.ts +34 -0
- package/dist/implementations/deployment.impl.d.ts.map +1 -0
- package/dist/implementations/deployment.impl.js +86 -0
- package/dist/implementations/deployment.impl.js.map +1 -0
- package/dist/implementations/droplet.impl.d.ts +85 -0
- package/dist/implementations/droplet.impl.d.ts.map +1 -0
- package/dist/implementations/droplet.impl.js +113 -0
- package/dist/implementations/droplet.impl.js.map +1 -0
- package/dist/implementations/gitea.impl.d.ts +68 -0
- package/dist/implementations/gitea.impl.d.ts.map +1 -0
- package/dist/implementations/gitea.impl.js +295 -0
- package/dist/implementations/gitea.impl.js.map +1 -0
- package/dist/implementations/managed-db.impl.d.ts +25 -0
- package/dist/implementations/managed-db.impl.d.ts.map +1 -0
- package/dist/implementations/managed-db.impl.js +31 -0
- package/dist/implementations/managed-db.impl.js.map +1 -0
- package/dist/implementations/managed-redis.impl.d.ts +37 -0
- package/dist/implementations/managed-redis.impl.d.ts.map +1 -0
- package/dist/implementations/managed-redis.impl.js +40 -0
- package/dist/implementations/managed-redis.impl.js.map +1 -0
- package/dist/implementations/spaces.impl.d.ts +36 -0
- package/dist/implementations/spaces.impl.d.ts.map +1 -0
- package/dist/implementations/spaces.impl.js +40 -0
- package/dist/implementations/spaces.impl.js.map +1 -0
- package/dist/implementations/statefulset.impl.d.ts +65 -0
- package/dist/implementations/statefulset.impl.d.ts.map +1 -0
- package/dist/implementations/statefulset.impl.js +165 -0
- package/dist/implementations/statefulset.impl.js.map +1 -0
- package/dist/implementations/verdaccio.impl.d.ts +65 -0
- package/dist/implementations/verdaccio.impl.d.ts.map +1 -0
- package/dist/implementations/verdaccio.impl.js +259 -0
- package/dist/implementations/verdaccio.impl.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/kubernetes/index.d.ts +95 -0
- package/dist/kubernetes/index.d.ts.map +1 -0
- package/dist/kubernetes/index.js +625 -0
- package/dist/kubernetes/index.js.map +1 -0
- package/dist/secrets/index.d.ts +4 -0
- package/dist/secrets/index.d.ts.map +1 -0
- package/dist/secrets/index.js +4 -0
- package/dist/secrets/index.js.map +1 -0
- package/dist/secrets/vault.descriptor.d.ts +10 -0
- package/dist/secrets/vault.descriptor.d.ts.map +1 -0
- package/dist/secrets/vault.descriptor.js +25 -0
- package/dist/secrets/vault.descriptor.js.map +1 -0
- package/dist/secrets/vault.impl.cloud.d.ts +40 -0
- package/dist/secrets/vault.impl.cloud.d.ts.map +1 -0
- package/dist/secrets/vault.impl.cloud.js +178 -0
- package/dist/secrets/vault.impl.cloud.js.map +1 -0
- package/dist/secrets/vault.impl.d.ts +29 -0
- package/dist/secrets/vault.impl.d.ts.map +1 -0
- package/dist/secrets/vault.impl.js +137 -0
- package/dist/secrets/vault.impl.js.map +1 -0
- package/dist/types.d.ts +509 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +47 -0
- package/dist/types.js.map +1 -0
- package/package.json +145 -0
- package/src/client/digitalocean-app-deploy.client.ts +226 -0
- package/src/client/index.ts +24 -0
- package/src/cloud/base.ts +149 -0
- package/src/cloud/digitalocean.ts +363 -0
- package/src/cloud/factory.ts +190 -0
- package/src/cloud/index.ts +81 -0
- package/src/doks.plugin.ts +401 -0
- package/src/implementations/deployment.impl.ts +93 -0
- package/src/implementations/droplet.impl.ts +157 -0
- package/src/implementations/gitea.impl.ts +319 -0
- package/src/implementations/managed-db.impl.ts +37 -0
- package/src/implementations/managed-redis.impl.ts +49 -0
- package/src/implementations/spaces.impl.ts +52 -0
- package/src/implementations/statefulset.impl.ts +186 -0
- package/src/implementations/verdaccio.impl.ts +300 -0
- package/src/index.ts +136 -0
- package/src/kubernetes/index.ts +754 -0
- package/src/secrets/index.ts +9 -0
- package/src/secrets/vault.descriptor.ts +28 -0
- package/src/secrets/vault.impl.cloud.ts +278 -0
- package/src/secrets/vault.impl.ts +149 -0
- package/src/types.ts +563 -0
package/README.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# @vibesdotdev/infra-doks
|
|
2
|
+
|
|
3
|
+
DigitalOcean / DOKS adapter for Vibes runtime kinds. Supplies the
|
|
4
|
+
DigitalOcean / DOKS-flavored descriptor + implementation pairs the
|
|
5
|
+
runtime selects when scope resolves to a DO/cluster target.
|
|
6
|
+
|
|
7
|
+
The contract lives in [SPEC.md](./SPEC.md). This README is usage notes.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
bun add @vibesdotdev/infra-doks
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Workspace-internal — declared as `"@vibesdotdev/infra-doks": "workspace:*"`.
|
|
16
|
+
|
|
17
|
+
## Plugin
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import doksPlugin from '@vibesdotdev/infra-doks/plugin';
|
|
21
|
+
import { createRuntime } from '@vibesdotdev/runtime';
|
|
22
|
+
import infraPlugin from '@vibesdotdev/infra-core/plugin';
|
|
23
|
+
|
|
24
|
+
const runtime = createRuntime();
|
|
25
|
+
await runtime.use(infraPlugin);
|
|
26
|
+
await runtime.use(doksPlugin);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`doksPlugin` depends on the `infra` plugin from `infra-core`. Activate
|
|
30
|
+
`infra-core` first so the kinds are registered before `doksPlugin` adds
|
|
31
|
+
its loaders.
|
|
32
|
+
|
|
33
|
+
## What's wired today
|
|
34
|
+
|
|
35
|
+
Only the `secrets/store` Vault pair. After bootstrap, the runtime can
|
|
36
|
+
resolve a HashiCorp Vault-backed `secrets/store` for environments
|
|
37
|
+
running inside a Kubernetes cluster:
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { getVibesSecretsClient } from '@vibesdotdev/secrets/runtime/client';
|
|
41
|
+
|
|
42
|
+
const secrets = await getVibesSecretsClient();
|
|
43
|
+
const dbPassword = await secrets.get('staging', 'POSTGRES_PASSWORD');
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The Vault descriptor is `hardware: ['cloud']` only. It will not match on
|
|
47
|
+
consumer hardware. Auth uses (in order) descriptor `token`, the
|
|
48
|
+
`VAULT_TOKEN` env var, then exchanges the in-pod K8s service-account JWT
|
|
49
|
+
at `/var/run/secrets/kubernetes.io/serviceaccount/token` for a Vault
|
|
50
|
+
token via `/v1/auth/kubernetes/login`. All three failing throws.
|
|
51
|
+
|
|
52
|
+
Vault KV path layout matches the deployment Helm chart's secret groups:
|
|
53
|
+
`{mount}/app`, `{mount}/oauth`, `{mount}/artifacts`,
|
|
54
|
+
`{mount}/infrastructure`. New keys default to the `app` group.
|
|
55
|
+
|
|
56
|
+
## What's not wired (migration debt)
|
|
57
|
+
|
|
58
|
+
The K8s and DO managed-service generators are exported but not
|
|
59
|
+
registered against `infra/*` kinds yet. They are usable as standalone
|
|
60
|
+
functions, but consuming them this way bypasses the runtime selection
|
|
61
|
+
flow:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import { generateK8sDeployment } from '@vibesdotdev/infra-doks';
|
|
65
|
+
|
|
66
|
+
const manifest = generateK8sDeployment(workerDescriptor);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
See [SPEC.md](./SPEC.md) → **Migration debt** for the path to wiring
|
|
70
|
+
these as descriptor + impl pairs (mirroring the
|
|
71
|
+
[`infra-cloudflare`](../infra-cloudflare) plugin layout).
|
|
72
|
+
|
|
73
|
+
## Vault tier mapping
|
|
74
|
+
|
|
75
|
+
The descriptor's `config.mount` is the default. At resolution time the
|
|
76
|
+
impl picks a mount per environment:
|
|
77
|
+
|
|
78
|
+
| `environment` | Vault mount |
|
|
79
|
+
| ------------- | ------------------- |
|
|
80
|
+
| `staging` | `staging` |
|
|
81
|
+
| `production` | `production` |
|
|
82
|
+
| anything else | `config.mount` (default `staging`) |
|
|
83
|
+
|
|
84
|
+
Override the default address or mount via the descriptor's `config`
|
|
85
|
+
record (string-valued, per the `secrets/store` schema).
|
|
86
|
+
|
|
87
|
+
## Tests
|
|
88
|
+
|
|
89
|
+
```sh
|
|
90
|
+
bun test packages/infra-doks
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Covers plugin shape and deterministic generator output. No live Vault,
|
|
94
|
+
Kubernetes, or DigitalOcean API access is exercised.
|
|
95
|
+
|
|
96
|
+
Type gate:
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
bun --bun tsc -p packages/infra-doks/tsconfig.json --noEmit
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Related
|
|
103
|
+
|
|
104
|
+
- [`infra-core`](../infra-core) — kinds and base schemas.
|
|
105
|
+
- [`infra-cloudflare`](../infra-cloudflare) — sibling Cloudflare adapter.
|
|
106
|
+
- [`secrets`](../secrets) — `secrets/store` kind, interface, default impl.
|
|
107
|
+
- [`deploy`](../deploy) — orchestration that consumes the manifests.
|
package/SPEC.md
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
# @vibesdotdev/infra-doks
|
|
2
|
+
|
|
3
|
+
DigitalOcean / DOKS adapter for runtime kinds defined elsewhere: `infra/*`
|
|
4
|
+
from [`infra-core`](../infra-core/SPEC.md) and `secrets/store` from
|
|
5
|
+
[`secrets`](../secrets/SPEC.md). Each kind defines a base descriptor
|
|
6
|
+
schema, an implementation interface, and a pass-through default impl in
|
|
7
|
+
its owning package; this package supplies the DigitalOcean / DOKS
|
|
8
|
+
**descriptor + impl** pair the runtime selects when scope resolves to a
|
|
9
|
+
DO/cluster target. The canonical adapter pattern lives in
|
|
10
|
+
[`infra-cloudflare`](../infra-cloudflare/SPEC.md) — same plugin shape,
|
|
11
|
+
same `createRuntimeImplementation` bridge, same per-impl descriptor
|
|
12
|
+
schemas alongside the generators. Every adapter pair owned here is REGISTERED with the runtime via
|
|
13
|
+
`runtime.registerLoader` in `onActivate` (`vault`, `doks-deployment`,
|
|
14
|
+
`doks-statefulset` for queue and database, `do-managed-postgres`,
|
|
15
|
+
`do-managed-redis`, `do-spaces`, `gitea-doks`, `verdaccio-doks`, plus the
|
|
16
|
+
`digitalocean-droplet` sandbox). Whether each registration is reached by
|
|
17
|
+
an in-repo consumer is a separate question — see "Consumers" below.
|
|
18
|
+
Today the registered set splits roughly in half: `vault`,
|
|
19
|
+
`digitalocean-droplet`, `gitea-doks`, and `verdaccio-doks` have live
|
|
20
|
+
consumers; the rest are registered-only (and `infra/generate.ts` even
|
|
21
|
+
inlines a parallel shape for `doks-deployment` and `do-spaces` that
|
|
22
|
+
drifts from this package's generator).
|
|
23
|
+
|
|
24
|
+
## Owns
|
|
25
|
+
|
|
26
|
+
- **Plugin descriptor:** `doksPlugin` (id `infra-doks`, depends on `infra`).
|
|
27
|
+
In `onActivate`, lazy-registers each pair via `runtime.registerLoader`.
|
|
28
|
+
Implementations are `await import()`-ed inside the loader, never at
|
|
29
|
+
module load.
|
|
30
|
+
- **`secrets/store` `vault` descriptor + impl** (`./secrets`). Descriptor in `vault.descriptor.ts`
|
|
31
|
+
(`backend: 'vault'`, `hardware: ['cloud']`,
|
|
32
|
+
`tiers: ['staging', 'production']`, default address
|
|
33
|
+
`http://vault.observability.svc.cluster.local:8200`, K8s auth method).
|
|
34
|
+
Impl in `vault.impl.ts` is a `SecretsStoreImplementation` walking the
|
|
35
|
+
fixed Vault KV v2 path groups `app`/`oauth`/`artifacts`/
|
|
36
|
+
`infrastructure`, defaulting new keys to `app`. HTTP client in
|
|
37
|
+
`vault.client.ts` (K8s service-account token exchange against
|
|
38
|
+
`/v1/auth/kubernetes/login`). Priority 30. `createVaultStore` wraps
|
|
39
|
+
the store in `createRuntimeImplementation`.
|
|
40
|
+
- **`infra/worker` `doks-deployment` descriptor + impl** (`./implementations/deployment`).
|
|
41
|
+
Adapter descriptor schema `DoksDeploymentDescriptorSchema` co-located with
|
|
42
|
+
`generateK8sDeployment` generator. Implementation produces a K8s
|
|
43
|
+
Deployment manifest. Priority 20.
|
|
44
|
+
- **`infra/queue` `doks-statefulset` descriptor + impl** (`./implementations/statefulset`).
|
|
45
|
+
Adapter descriptor schema `DoksQueueDescriptorSchema` co-located with
|
|
46
|
+
`generateK8sStatefulSet` generator for Kafka/Redpanda. Implementation
|
|
47
|
+
produces a K8s StatefulSet manifest. Priority 20.
|
|
48
|
+
- **`infra/database` `doks-statefulset` descriptor + impl** (`./implementations/statefulset`).
|
|
49
|
+
Adapter descriptor schema `DoksDatabaseDescriptorSchema` co-located with
|
|
50
|
+
`generateK8sStatefulSet` generator for self-hosted Postgres. Implementation
|
|
51
|
+
produces a K8s StatefulSet manifest. Priority 20.
|
|
52
|
+
- **`infra/database` `do-managed-postgres` descriptor + impl** (`./implementations/managed-db`).
|
|
53
|
+
Adapter descriptor schema `DOManagedPostgresDescriptorSchema` co-located with
|
|
54
|
+
`generateDOManagedDB` generator. Implementation produces a DO Managed Database
|
|
55
|
+
API spec. Priority 30 (higher than StatefulSet so managed is preferred when adapter
|
|
56
|
+
matches).
|
|
57
|
+
- **`infra/cache` `do-managed-redis` descriptor + impl** (`./implementations/managed-redis`).
|
|
58
|
+
Adapter descriptor schema `DOManagedRedisDescriptorSchema` co-located with
|
|
59
|
+
`generateDOManagedRedis` generator. Implementation produces a DO Managed Redis
|
|
60
|
+
API spec. Priority 20.
|
|
61
|
+
- **`infra/object-storage` `do-spaces` descriptor + impl** (`./implementations/spaces`).
|
|
62
|
+
Adapter descriptor schema `DOSpacesDescriptorSchema` co-located with
|
|
63
|
+
`generateDOSpaces` generator. Implementation produces a DO Spaces API spec.
|
|
64
|
+
Priority 20.
|
|
65
|
+
- **`infra/git-hosting` `gitea-doks` descriptor + impl** (`./implementations/gitea.impl`).
|
|
66
|
+
Adapter descriptor schema `GiteaDoksDescriptorSchema` co-located with
|
|
67
|
+
`generateGiteaManifest` generator. Implementation produces K8s
|
|
68
|
+
Deployment + Service + PersistentVolumeClaim + Ingress manifests for Gitea.
|
|
69
|
+
Priority 20.
|
|
70
|
+
- **`infra/package-registry` `verdaccio-doks` descriptor + impl** (`./implementations/verdaccio.impl`).
|
|
71
|
+
Adapter descriptor schema `VerdaccioDoksDescriptorSchema` co-located with
|
|
72
|
+
`generateVerdaccioManifest` generator. Implementation produces K8s
|
|
73
|
+
Deployment + Service + PersistentVolumeClaim + ConfigMap + Ingress manifests
|
|
74
|
+
for Verdaccio. Priority 20.
|
|
75
|
+
- **`infra/sandbox` `digitalocean-droplet` descriptor + impl**
|
|
76
|
+
(`./implementations/droplet`). Implements the `digitalocean-droplet`
|
|
77
|
+
variant of `infra/sandbox` whose schema already lives in
|
|
78
|
+
[`infra-core`](../infra-core/SPEC.md). Wires the existing
|
|
79
|
+
`DigitalOceanProvider` (`./cloud/digitalocean.ts`) into the runtime
|
|
80
|
+
kind resolution path: creates the droplet via DO `/v2/droplets`,
|
|
81
|
+
waits for `status: 'active'`, returns
|
|
82
|
+
`{ instanceId, publicIp, privateIp, region, createdAt }`. Optional
|
|
83
|
+
`cloudInitScript` is forwarded as `user_data`. Priority 20.
|
|
84
|
+
- **Manifest output types** (`./types`): K8s API subset (`K8sDeployment`,
|
|
85
|
+
`K8sStatefulSet`, `K8sService`, `K8sConfigMap`, `K8sSecret`,
|
|
86
|
+
`K8sContainer`, `K8sPodSpec`, `K8sPodTemplateSpec`, `K8sProbe`,
|
|
87
|
+
`K8sResourceRequirements`, `K8sLabelSelector`, `K8sVolumeClaimTemplate`)
|
|
88
|
+
and DO managed-service spec shapes (`DOManagedDBSpec`,
|
|
89
|
+
`DOManagedRedisSpec`, `DOSpacesSpec`).
|
|
90
|
+
- **Manifest generator functions** (`./implementations`): pure functions
|
|
91
|
+
`generateK8sDeployment`, `generateK8sStatefulSet`,
|
|
92
|
+
`generateDOManagedDB`, `generateDOManagedRedis`, `generateDOSpaces`,
|
|
93
|
+
`generateGiteaManifest`, `generateVerdaccioManifest`.
|
|
94
|
+
Each takes an adapter-specific descriptor and returns a manifest object,
|
|
95
|
+
namespace `vibes`, name `vibes-{descriptor.id}`.
|
|
96
|
+
- **`runtime/client` `digitalocean-app-deploy` descriptor + impl**
|
|
97
|
+
(`./client`). `DigitalOceanAppDeployClient extends BaseRuntimeClient`
|
|
98
|
+
exposes `deployApp(options): Promise<DeployAppResult>` — translates an
|
|
99
|
+
`AppDeployment` to a DO App spec and POSTs `/apps` (create) or PUTs
|
|
100
|
+
`/apps/{id}` (update) via the v2 REST API. Consumed by
|
|
101
|
+
[`infra-deploy`](../infra-deploy/SPEC.md)'s CLI run handler through the
|
|
102
|
+
published `getDigitalOceanAppDeployClient()` helper. Reads
|
|
103
|
+
`DIGITALOCEAN_API_TOKEN` from the operator's env (secrets-manager
|
|
104
|
+
brokerage tracked in `infra-deploy/SPEC.md` migration debt).
|
|
105
|
+
|
|
106
|
+
## Does not own
|
|
107
|
+
|
|
108
|
+
- Infra runtime kinds and their base descriptor schemas →
|
|
109
|
+
[`infra-core`](../infra-core/SPEC.md).
|
|
110
|
+
- `secrets/store` kind, `SecretsStoreImplementation` interface, default
|
|
111
|
+
in-process impl, and env-requirement resolution →
|
|
112
|
+
[`secrets`](../secrets/SPEC.md).
|
|
113
|
+
- Cloudflare descriptor + impl pairs (Workers / Queues / R2 / KV /
|
|
114
|
+
cloudflare-api `secrets/store`) →
|
|
115
|
+
[`infra-cloudflare`](../infra-cloudflare/SPEC.md).
|
|
116
|
+
- `kubectl apply`, deployment orchestration, env materialization, and the
|
|
117
|
+
`infra/` workspace tree → [`infra-deploy`](../infra-deploy/SPEC.md).
|
|
118
|
+
- DigitalOcean API clients that actually create Managed DB / Redis /
|
|
119
|
+
Spaces resources. Generators here produce request-shaped specs only;
|
|
120
|
+
the only DO API client surface in this package is the
|
|
121
|
+
`DigitalOceanAppDeployClient` (App Platform deploys) and the existing
|
|
122
|
+
`DigitalOceanProvider` (droplets, volumes, VPCs) — both behind the
|
|
123
|
+
runtime kind resolution path, not via direct import.
|
|
124
|
+
|
|
125
|
+
## Hard rules
|
|
126
|
+
|
|
127
|
+
- The plugin registers every implementation through
|
|
128
|
+
`runtime.registerLoader` in `onActivate`. Do not import
|
|
129
|
+
implementations at module load — Vault auth touches Node FS and the
|
|
130
|
+
network and must not run on `import`.
|
|
131
|
+
- Adapter packages provide descriptor + impl pairs for kinds defined
|
|
132
|
+
elsewhere. Defining a new kind here is a layering violation — add it
|
|
133
|
+
to its owning package (`infra-core`, `secrets`, …) first.
|
|
134
|
+
- The descriptor + impl unit follows infra-cloudflare's shape: each
|
|
135
|
+
`*.impl.ts` co-locates the adapter descriptor schema (extending the
|
|
136
|
+
base kind with adapter-specific fields), the generator, and the output
|
|
137
|
+
type; the plugin file holds the `create*Impl(input)` factory that
|
|
138
|
+
parses the descriptor and wraps the generator in
|
|
139
|
+
`createRuntimeImplementation`; `onActivate` calls `registerLoader` for
|
|
140
|
+
each pair. Do not split these layers across additional files.
|
|
141
|
+
- Each kind's implementation interface is defined in its owning package.
|
|
142
|
+
`secrets/store` requires the full `SecretsStoreImplementation` CRUD
|
|
143
|
+
interface; `infra/*` kinds expect `{ generateConfig: () => …Manifest }`
|
|
144
|
+
per the cloudflare precedent. Adapters fulfill the kind's interface
|
|
145
|
+
exactly; do not invent a parallel interface.
|
|
146
|
+
- Vault auth precedence: descriptor `token`, then `VAULT_TOKEN` env,
|
|
147
|
+
then exchange the K8s service-account JWT at
|
|
148
|
+
`/var/run/secrets/kubernetes.io/serviceaccount/token` for a Vault
|
|
149
|
+
token. Failing all three throws — never silently fall through.
|
|
150
|
+
- The `digitalocean-droplet` impl is the only path through which
|
|
151
|
+
`DigitalOceanProvider` (`./cloud/digitalocean.ts`) is reachable from
|
|
152
|
+
the runtime. Direct imports of `./cloud/digitalocean.ts` from
|
|
153
|
+
feature packages are layering violations; that class moves from
|
|
154
|
+
orphan to runtime-bound on this landing.
|
|
155
|
+
- Droplet creation is idempotent against the descriptor `id`: a second
|
|
156
|
+
call with the same id returns the existing droplet rather than
|
|
157
|
+
creating a duplicate. Tag droplets with `vibes:resourceId=<id>` to
|
|
158
|
+
make the lookup cheap.
|
|
159
|
+
- DO API token resolution: descriptor override →
|
|
160
|
+
`DIGITALOCEAN_API_TOKEN` env → `packages/secrets`
|
|
161
|
+
`cloud-credentials.digitalocean.token` once brokerage lands. Same
|
|
162
|
+
precedence the rest of this package uses.
|
|
163
|
+
- The Vault descriptor is `hardware: ['cloud']` only. It must not
|
|
164
|
+
register on consumer hardware; the in-cluster Vault address is
|
|
165
|
+
unreachable elsewhere.
|
|
166
|
+
- Manifest generators are pure: descriptor in, plain object out, no
|
|
167
|
+
I/O, no side effects. Probes, resource requests/limits, namespace
|
|
168
|
+
`vibes`, and the `vibes-{descriptor.id}` naming convention are part
|
|
169
|
+
of the contract — change them only with a deploy-side coordinated
|
|
170
|
+
update.
|
|
171
|
+
- Vault KV path groups (`app`, `oauth`, `artifacts`, `infrastructure`)
|
|
172
|
+
match the deployment Helm chart's secret groups. Adding a new group
|
|
173
|
+
requires updating this list and the chart in lockstep.
|
|
174
|
+
- Manifest generators are config transforms and stay pure; the only
|
|
175
|
+
runtime-bound clients that perform I/O are the `runtime/client`
|
|
176
|
+
`digitalocean-app-deploy` (App Platform deploys) and the existing
|
|
177
|
+
`digitalocean-droplet` `infra/sandbox` impl (droplets). Adding another
|
|
178
|
+
cloud-API surface means adding a new `runtime/client` or kind impl —
|
|
179
|
+
never a top-level export bypassing the runtime.
|
|
180
|
+
- The `digitalocean-app-deploy` client reads `DIGITALOCEAN_API_TOKEN`
|
|
181
|
+
from process env today (matches the `digitalocean-droplet` impl
|
|
182
|
+
precedence). End-state: resolve `cloud-credentials.digitalocean.token`
|
|
183
|
+
via `packages/secrets` per actor scope.
|
|
184
|
+
|
|
185
|
+
## Consumers
|
|
186
|
+
|
|
187
|
+
Status of each impl pair's consumption path:
|
|
188
|
+
|
|
189
|
+
- **`secrets/store` → `vault`**: consumed by `infra/vault-setup.ts` via Vault HTTP
|
|
190
|
+
client; production-wired.
|
|
191
|
+
- **`infra/sandbox` → `digitalocean-droplet`**: consumed by
|
|
192
|
+
`packages/runner-adapter-digitalocean` (GPU on-demand inference). Required at
|
|
193
|
+
runtime — removing this loader breaks GPU runner activation.
|
|
194
|
+
- **`runtime/client` → `digitalocean-app-deploy`**: consumed by
|
|
195
|
+
[`infra-deploy`](../infra-deploy/SPEC.md) via
|
|
196
|
+
`getDigitalOceanAppDeployClient()` in
|
|
197
|
+
`packages/infra-deploy/src/cli/run/infra-deploy.run.cli-command.impl.ts`.
|
|
198
|
+
Required for `vibes infra deploy run` against DO App Platform apps.
|
|
199
|
+
- **`infra/git-hosting` → `gitea-doks`** and
|
|
200
|
+
**`infra/package-registry` → `verdaccio-doks`**: consumed by `infra/generate.ts`
|
|
201
|
+
via direct `generateGiteaManifest` / `generateVerdaccioManifest` imports
|
|
202
|
+
(not via the runtime resolver). Active in DOKS apply phase.
|
|
203
|
+
- **`infra/worker` → `doks-deployment`**, **`infra/queue` → `doks-statefulset`**,
|
|
204
|
+
**`infra/database` → `doks-statefulset` / `do-managed-postgres`**,
|
|
205
|
+
**`infra/cache` → `do-managed-redis`**, **`infra/object-storage` → `do-spaces`**:
|
|
206
|
+
registered with the runtime but no in-repo consumer resolves them yet.
|
|
207
|
+
`infra/generate.ts` inlines its own K8s Deployment YAML for the
|
|
208
|
+
`doks-deployment` workers (`ai-workers`, `crawl-workers`, `workbench-workers`)
|
|
209
|
+
with a DIFFERENT shape than `generateK8sDeployment` (different image prefix
|
|
210
|
+
`ghcr.io/vibes-dev` vs. `vibes/`, inline `env[]` vs. `envFrom: configMapRef`,
|
|
211
|
+
includes `HorizontalPodAutoscaler`). The infra-doks generator is the
|
|
212
|
+
canonical target shape; `infra/generate.ts` is the current production shape.
|
|
213
|
+
Consolidation needs a deploy-side coordinated test pass (apply against a
|
|
214
|
+
DOKS cluster, diff manifests) — tracked as migration debt below.
|
|
215
|
+
|
|
216
|
+
## Migration debt
|
|
217
|
+
|
|
218
|
+
- [ ] **`infra/generate.ts` doks-deployment / do-spaces inlining drift.**
|
|
219
|
+
`infra/generate.ts` inlines K8s Deployment + HPA YAML and DO Spaces JSON
|
|
220
|
+
rather than routing through `generateK8sDeployment` / `generateDOSpaces`.
|
|
221
|
+
Reconciling requires aligning the infra-doks generators with the inline
|
|
222
|
+
shapes (add HPA support, default image prefix `ghcr.io/vibes-dev`, allow
|
|
223
|
+
inline env + secret env) and running an apply-dry-run diff against the
|
|
224
|
+
current `infra/generated/k8s-*-workers.yaml` files before flipping over.
|
|
225
|
+
|
|
226
|
+
- [ ] **`infra/git-hosting` and `infra/package-registry` impl pairs are new.**
|
|
227
|
+
`gitea.impl.ts` and `verdaccio.impl.ts` register `gitea-doks` and `verdaccio-doks`
|
|
228
|
+
loaders for the new kinds. Both implementations follow the existing impl pattern.
|
|
229
|
+
Full validation: `createRuntimeAsset` calls must validate `config` against the
|
|
230
|
+
kind's registered `descriptorSchema` once the runtime `config` field migration
|
|
231
|
+
in `runtime` is complete.
|
|
232
|
+
|
|
233
|
+
- [x] **Five DOKS/DO descriptor + impl pairs are unbuilt.** The generators
|
|
234
|
+
exist, but each impl file was missing its adapter descriptor schema,
|
|
235
|
+
the plugin was missing its `create*Impl(input)` factory, and
|
|
236
|
+
`onActivate` was missing the matching `registerLoader` call.
|
|
237
|
+
**Resolution:** Mirrored `infra-cloudflare` exactly:
|
|
238
|
+
- `infra/worker` ← `generateK8sDeployment` via `doks-deployment` loader (priority 20)
|
|
239
|
+
- `infra/queue` ← `generateK8sStatefulSet` via `doks-statefulset` loader (priority 20)
|
|
240
|
+
- `infra/database` ← `generateK8sStatefulSet` via `doks-statefulset` loader (priority 20)
|
|
241
|
+
and `generateDOManagedDB` via `do-managed-postgres` loader (priority 30)
|
|
242
|
+
- `infra/cache` ← `generateDOManagedRedis` via `do-managed-redis` loader (priority 20)
|
|
243
|
+
- `infra/object-storage` ← `generateDOSpaces` via `do-spaces` loader (priority 20)
|
|
244
|
+
Each implementation follows the `{ generateConfig: () => Manifest }` shape
|
|
245
|
+
per the cloudflare precedent.
|
|
246
|
+
- [x] **`package.json#exports` wildcard cleanup.**
|
|
247
|
+
**Resolution:** Replaced `"./implementations/*": "./src/implementations/*"` with
|
|
248
|
+
explicit per-impl subpaths:
|
|
249
|
+
- `./implementations/deployment`
|
|
250
|
+
- `./implementations/statefulset`
|
|
251
|
+
- `./implementations/managed-db`
|
|
252
|
+
- `./implementations/managed-redis`
|
|
253
|
+
- `./implementations/spaces`
|
|
254
|
+
Grep found no in-repo consumer of the wildcard.
|
|
255
|
+
- [x] **`infra-core`'s `deploymentProviderSchema` enum coordination.**
|
|
256
|
+
**Resolution:** This is already cross-recorded in [`infra-core`](../infra-core/SPEC.md)
|
|
257
|
+
migration debt. The `infra-doks` package provides the implementations; the enum
|
|
258
|
+
trim in `infra-core` is a separate action item tracked there.
|
|
259
|
+
|
|
260
|
+
## Public entrypoints
|
|
261
|
+
|
|
262
|
+
`.`, `./plugin`, `./implementations/deployment`, `./implementations/statefulset`,
|
|
263
|
+
`./implementations/managed-db`, `./implementations/managed-redis`,
|
|
264
|
+
`./implementations/spaces`, `./implementations/gitea`, `./implementations/verdaccio`,
|
|
265
|
+
`./secrets`, `./cloud`, `./kubernetes`, `./types`, `./client`.
|
|
266
|
+
|
|
267
|
+
Wildcard / migration-era subpaths: None — the explicit per-impl subpaths above
|
|
268
|
+
replace the former `./implementations/*` wildcard.
|
|
269
|
+
|
|
270
|
+
## Verification
|
|
271
|
+
|
|
272
|
+
`bun test` from `packages/infra-doks`. Covers plugin shape (`id`,
|
|
273
|
+
`dependencies`, `name`) and deterministic-output tests for each of
|
|
274
|
+
`deployment.impl`, `statefulset.impl`, `managed-db.impl`,
|
|
275
|
+
`managed-redis.impl`, `spaces.impl`. No live Vault, Kubernetes API, or
|
|
276
|
+
DigitalOcean API contact is exercised; those are deploy-time gates.
|
|
277
|
+
Type gate is `bun --bun tsc -p tsconfig.json --noEmit`.
|
|
278
|
+
|
|
279
|
+
## Links
|
|
280
|
+
|
|
281
|
+
- [infra-core/SPEC.md](../infra-core/SPEC.md)
|
|
282
|
+
- [infra-cloudflare/SPEC.md](../infra-cloudflare/SPEC.md)
|
|
283
|
+
- [secrets/SPEC.md](../secrets/SPEC.md)
|
|
284
|
+
- [runtime/SPEC.md](../runtime/SPEC.md)
|
|
285
|
+
- [infra-deploy/SPEC.md](../infra-deploy/SPEC.md)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DigitalOcean App Platform Deploy Client
|
|
3
|
+
*
|
|
4
|
+
* Canonical `runtime/client` (id `digitalocean-app-deploy`) for creating or
|
|
5
|
+
* updating an App Platform application from an `AppDeployment` manifest.
|
|
6
|
+
* Uses the DigitalOcean REST API v2 directly (no `doctl` dependency).
|
|
7
|
+
*
|
|
8
|
+
* Consumers resolve via `getDigitalOceanAppDeployClient()` (preferred)
|
|
9
|
+
* or `getVibesClient<DigitalOceanAppDeployClient>('digitalocean-app-deploy')`.
|
|
10
|
+
*
|
|
11
|
+
* For the initial deploy, the DO App needs a source reference. The common case
|
|
12
|
+
* is a git repo reference — the CLI writes the app spec; the operator connects
|
|
13
|
+
* the git repo in the DO dashboard once. Subsequent calls update the spec.
|
|
14
|
+
*
|
|
15
|
+
* Credentials: reads `DIGITALOCEAN_API_TOKEN` from the operator's environment.
|
|
16
|
+
* (Secrets-manager integration is tracked in `infra-deploy/SPEC.md` Migration
|
|
17
|
+
* debt — once landed, this client will resolve the token via secrets/store.)
|
|
18
|
+
*/
|
|
19
|
+
import type { VibesRuntime } from '@vibesdotdev/runtime';
|
|
20
|
+
import { BaseRuntimeClient, type RuntimeClientDescriptor } from '@vibesdotdev/runtime-client';
|
|
21
|
+
import type { AppDeployment } from '@vibesdotdev/infra-core/deployment';
|
|
22
|
+
export interface DeployAppOptions {
|
|
23
|
+
deployment: AppDeployment;
|
|
24
|
+
/** Existing DO App id (for updates). Omit to create a new App. */
|
|
25
|
+
appId?: string;
|
|
26
|
+
/** Region slug, e.g. 'nyc', 'sfo3', 'ams'. */
|
|
27
|
+
region?: string;
|
|
28
|
+
/** Git repo reference for the app source (github/gitlab). */
|
|
29
|
+
git?: {
|
|
30
|
+
repoCloneUrl?: string;
|
|
31
|
+
branch?: string;
|
|
32
|
+
};
|
|
33
|
+
/** Environment name for DO (e.g. 'production'). */
|
|
34
|
+
environmentName?: string;
|
|
35
|
+
dryRun?: boolean;
|
|
36
|
+
onLine?: (stream: 'stdout' | 'stderr', line: string) => void;
|
|
37
|
+
}
|
|
38
|
+
export interface DeployAppResult {
|
|
39
|
+
appId: string;
|
|
40
|
+
liveUrl?: string;
|
|
41
|
+
}
|
|
42
|
+
export declare class DigitalOceanAppDeployClient extends BaseRuntimeClient {
|
|
43
|
+
constructor(descriptor?: RuntimeClientDescriptor, context?: unknown, runtime?: VibesRuntime);
|
|
44
|
+
deployApp(options: DeployAppOptions): Promise<DeployAppResult>;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=digitalocean-app-deploy.client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digitalocean-app-deploy.client.d.ts","sourceRoot":"","sources":["../../src/client/digitalocean-app-deploy.client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EACN,iBAAiB,EACjB,KAAK,uBAAuB,EAC5B,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAIxE,MAAM,WAAW,gBAAgB;IAChC,UAAU,EAAE,aAAa,CAAC;IAC1B,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,GAAG,CAAC,EAAE;QACL,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,mDAAmD;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7D;AAED,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAiID,qBAAa,2BAA4B,SAAQ,iBAAiB;gBAEhE,UAAU,GAAE,uBAGX,EACD,OAAO,CAAC,EAAE,OAAO,EACjB,OAAO,CAAC,EAAE,YAAY;IAKjB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;CAmCpE"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DigitalOcean App Platform Deploy Client
|
|
3
|
+
*
|
|
4
|
+
* Canonical `runtime/client` (id `digitalocean-app-deploy`) for creating or
|
|
5
|
+
* updating an App Platform application from an `AppDeployment` manifest.
|
|
6
|
+
* Uses the DigitalOcean REST API v2 directly (no `doctl` dependency).
|
|
7
|
+
*
|
|
8
|
+
* Consumers resolve via `getDigitalOceanAppDeployClient()` (preferred)
|
|
9
|
+
* or `getVibesClient<DigitalOceanAppDeployClient>('digitalocean-app-deploy')`.
|
|
10
|
+
*
|
|
11
|
+
* For the initial deploy, the DO App needs a source reference. The common case
|
|
12
|
+
* is a git repo reference — the CLI writes the app spec; the operator connects
|
|
13
|
+
* the git repo in the DO dashboard once. Subsequent calls update the spec.
|
|
14
|
+
*
|
|
15
|
+
* Credentials: reads `DIGITALOCEAN_API_TOKEN` from the operator's environment.
|
|
16
|
+
* (Secrets-manager integration is tracked in `infra-deploy/SPEC.md` Migration
|
|
17
|
+
* debt — once landed, this client will resolve the token via secrets/store.)
|
|
18
|
+
*/
|
|
19
|
+
import { getRuntimeEnv } from '@vibesdotdev/runtime';
|
|
20
|
+
import { BaseRuntimeClient } from '@vibesdotdev/runtime-client';
|
|
21
|
+
const DO_API_BASE = 'https://api.digitalocean.com/v2';
|
|
22
|
+
function authHeader() {
|
|
23
|
+
const token = getRuntimeEnv('DIGITALOCEAN_API_TOKEN') ?? '';
|
|
24
|
+
if (!token) {
|
|
25
|
+
throw new Error('DIGITALOCEAN_API_TOKEN is not set. Generate one at https://cloud.digitalocean.com/account/api/tokens and set it in your env.');
|
|
26
|
+
}
|
|
27
|
+
return `Bearer ${token}`;
|
|
28
|
+
}
|
|
29
|
+
async function doFetch(path, init) {
|
|
30
|
+
const response = await fetch(`${DO_API_BASE}${path}`, {
|
|
31
|
+
...init,
|
|
32
|
+
headers: {
|
|
33
|
+
Authorization: authHeader(),
|
|
34
|
+
'Content-Type': 'application/json',
|
|
35
|
+
...(init?.headers ?? {})
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
if (!response.ok) {
|
|
39
|
+
const body = await response.text();
|
|
40
|
+
throw new Error(`DO API ${response.status} ${path}: ${body}`);
|
|
41
|
+
}
|
|
42
|
+
if (response.status === 204)
|
|
43
|
+
return undefined;
|
|
44
|
+
return (await response.json());
|
|
45
|
+
}
|
|
46
|
+
function buildAppSpec(deployment, options) {
|
|
47
|
+
const envs = deployment.env
|
|
48
|
+
.filter((requirement) => typeof requirement.value === 'string')
|
|
49
|
+
.map((requirement) => ({
|
|
50
|
+
key: requirement.name,
|
|
51
|
+
value: requirement.value,
|
|
52
|
+
scope: 'RUN_AND_BUILD_TIME',
|
|
53
|
+
type: (requirement.secret ? 'SECRET' : 'GENERAL')
|
|
54
|
+
}));
|
|
55
|
+
const github = {
|
|
56
|
+
repo: options.git?.repoCloneUrl,
|
|
57
|
+
branch: options.git?.branch ?? 'main',
|
|
58
|
+
deploy_on_push: false
|
|
59
|
+
};
|
|
60
|
+
const isStaticRuntime = deployment.runtime === 'browser' || deployment.runtime === 'edge';
|
|
61
|
+
const sourceDir = deployment.build.appDir;
|
|
62
|
+
const outputDir = deployment.build.outputDir;
|
|
63
|
+
if (isStaticRuntime) {
|
|
64
|
+
return {
|
|
65
|
+
name: deployment.appId,
|
|
66
|
+
region: options.region ?? 'nyc',
|
|
67
|
+
static_sites: [
|
|
68
|
+
{
|
|
69
|
+
name: deployment.appId,
|
|
70
|
+
build_command: deployment.build.buildCommand,
|
|
71
|
+
source_dir: sourceDir,
|
|
72
|
+
output_dir: outputDir,
|
|
73
|
+
github: options.git?.repoCloneUrl ? github : undefined,
|
|
74
|
+
envs
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
name: deployment.appId,
|
|
81
|
+
region: options.region ?? 'nyc',
|
|
82
|
+
services: [
|
|
83
|
+
{
|
|
84
|
+
name: deployment.appId,
|
|
85
|
+
instance_count: 1,
|
|
86
|
+
instance_size_slug: 'apps-s-1vcpu-0.5gb',
|
|
87
|
+
http_port: 3000,
|
|
88
|
+
build_command: deployment.build.buildCommand,
|
|
89
|
+
run_command: 'node build',
|
|
90
|
+
source_dir: sourceDir,
|
|
91
|
+
github: options.git?.repoCloneUrl ? github : undefined,
|
|
92
|
+
envs,
|
|
93
|
+
health_check: { http_path: '/' }
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
export class DigitalOceanAppDeployClient extends BaseRuntimeClient {
|
|
99
|
+
constructor(descriptor = {
|
|
100
|
+
id: 'digitalocean-app-deploy',
|
|
101
|
+
kind: 'runtime/client'
|
|
102
|
+
}, context, runtime) {
|
|
103
|
+
super(descriptor, context, runtime);
|
|
104
|
+
}
|
|
105
|
+
async deployApp(options) {
|
|
106
|
+
const { deployment, onLine } = options;
|
|
107
|
+
const spec = buildAppSpec(deployment, options);
|
|
108
|
+
if (options.dryRun) {
|
|
109
|
+
onLine?.('stdout', `[dry-run] DO App spec for '${deployment.appId}':`);
|
|
110
|
+
onLine?.('stdout', JSON.stringify(spec, null, 2));
|
|
111
|
+
return { appId: options.appId ?? '(new)' };
|
|
112
|
+
}
|
|
113
|
+
if (options.appId) {
|
|
114
|
+
onLine?.('stdout', `Updating DO App ${options.appId}...`);
|
|
115
|
+
const updated = await doFetch(`/apps/${options.appId}`, {
|
|
116
|
+
method: 'PUT',
|
|
117
|
+
body: JSON.stringify({ spec })
|
|
118
|
+
});
|
|
119
|
+
return {
|
|
120
|
+
appId: updated.app.id,
|
|
121
|
+
liveUrl: updated.app.live_url
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
onLine?.('stdout', `Creating DO App '${deployment.appId}'...`);
|
|
125
|
+
const created = await doFetch(`/apps`, {
|
|
126
|
+
method: 'POST',
|
|
127
|
+
body: JSON.stringify({ spec })
|
|
128
|
+
});
|
|
129
|
+
return {
|
|
130
|
+
appId: created.app.id,
|
|
131
|
+
liveUrl: created.app.live_url
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=digitalocean-app-deploy.client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digitalocean-app-deploy.client.js","sourceRoot":"","sources":["../../src/client/digitalocean-app-deploy.client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public surface for the infra-doks runtime clients.
|
|
3
|
+
*
|
|
4
|
+
* Consumers resolve the App Platform deploy client via
|
|
5
|
+
* `getDigitalOceanAppDeployClient()` (preferred) or, for type-pinned generic
|
|
6
|
+
* resolution, `getVibesClient<DigitalOceanAppDeployClient>('digitalocean-app-deploy')`.
|
|
7
|
+
*
|
|
8
|
+
* Requires `doksPlugin` to be registered with the runtime so the
|
|
9
|
+
* `runtime/client` descriptor + loader for id `digitalocean-app-deploy` are
|
|
10
|
+
* resolvable.
|
|
11
|
+
*/
|
|
12
|
+
import { DigitalOceanAppDeployClient } from './digitalocean-app-deploy.client';
|
|
13
|
+
export { DigitalOceanAppDeployClient, type DeployAppOptions, type DeployAppResult } from './digitalocean-app-deploy.client';
|
|
14
|
+
export declare function getDigitalOceanAppDeployClient(): Promise<DigitalOceanAppDeployClient>;
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAE/E,OAAO,EACN,2BAA2B,EAC3B,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,MAAM,kCAAkC,CAAC;AAE1C,wBAAsB,8BAA8B,IAAI,OAAO,CAAC,2BAA2B,CAAC,CAE3F"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public surface for the infra-doks runtime clients.
|
|
3
|
+
*
|
|
4
|
+
* Consumers resolve the App Platform deploy client via
|
|
5
|
+
* `getDigitalOceanAppDeployClient()` (preferred) or, for type-pinned generic
|
|
6
|
+
* resolution, `getVibesClient<DigitalOceanAppDeployClient>('digitalocean-app-deploy')`.
|
|
7
|
+
*
|
|
8
|
+
* Requires `doksPlugin` to be registered with the runtime so the
|
|
9
|
+
* `runtime/client` descriptor + loader for id `digitalocean-app-deploy` are
|
|
10
|
+
* resolvable.
|
|
11
|
+
*/
|
|
12
|
+
import { getVibesClient } from '@vibesdotdev/runtime-client';
|
|
13
|
+
import { DigitalOceanAppDeployClient } from './digitalocean-app-deploy.client.js';
|
|
14
|
+
export { DigitalOceanAppDeployClient } from './digitalocean-app-deploy.client.js';
|
|
15
|
+
export async function getDigitalOceanAppDeployClient() {
|
|
16
|
+
return getVibesClient('digitalocean-app-deploy');
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAE/E,OAAO,EACN,2BAA2B,EAG3B,MAAM,kCAAkC,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,8BAA8B;IACnD,OAAO,cAAc,CAA8B,yBAAyB,CAAC,CAAC;AAC/E,CAAC"}
|