@vibesdotdev/infra-core 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 +78 -0
- package/SPEC.md +169 -0
- package/dist/bootstrap/index.d.ts +5 -0
- package/dist/bootstrap/index.d.ts.map +1 -0
- package/dist/bootstrap/index.js +4 -0
- package/dist/bootstrap/index.js.map +1 -0
- package/dist/bootstrap/seed.descriptor.d.ts +31 -0
- package/dist/bootstrap/seed.descriptor.d.ts.map +1 -0
- package/dist/bootstrap/seed.descriptor.js +18 -0
- package/dist/bootstrap/seed.descriptor.js.map +1 -0
- package/dist/bootstrap/seed.impl-shape.d.ts +5 -0
- package/dist/bootstrap/seed.impl-shape.d.ts.map +1 -0
- package/dist/bootstrap/seed.impl-shape.js +2 -0
- package/dist/bootstrap/seed.impl-shape.js.map +1 -0
- package/dist/bootstrap/seed.kind.d.ts +5 -0
- package/dist/bootstrap/seed.kind.d.ts.map +1 -0
- package/dist/bootstrap/seed.kind.js +14 -0
- package/dist/bootstrap/seed.kind.js.map +1 -0
- package/dist/bootstrap/seed.runner.d.ts +18 -0
- package/dist/bootstrap/seed.runner.d.ts.map +1 -0
- package/dist/bootstrap/seed.runner.js +59 -0
- package/dist/bootstrap/seed.runner.js.map +1 -0
- package/dist/credentials/resolve.d.ts +80 -0
- package/dist/credentials/resolve.d.ts.map +1 -0
- package/dist/credentials/resolve.js +128 -0
- package/dist/credentials/resolve.js.map +1 -0
- package/dist/deployment.d.ts +9 -0
- package/dist/deployment.d.ts.map +1 -0
- package/dist/deployment.js +25 -0
- package/dist/deployment.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/infra.plugin.d.ts +18 -0
- package/dist/infra.plugin.d.ts.map +1 -0
- package/dist/infra.plugin.js +52 -0
- package/dist/infra.plugin.js.map +1 -0
- package/dist/kinds/alerts.kind.d.ts +192 -0
- package/dist/kinds/alerts.kind.d.ts.map +1 -0
- package/dist/kinds/alerts.kind.js +116 -0
- package/dist/kinds/alerts.kind.js.map +1 -0
- package/dist/kinds/artifact.kind.d.ts +96 -0
- package/dist/kinds/artifact.kind.d.ts.map +1 -0
- package/dist/kinds/artifact.kind.js +53 -0
- package/dist/kinds/artifact.kind.js.map +1 -0
- package/dist/kinds/cache.kind.d.ts +128 -0
- package/dist/kinds/cache.kind.d.ts.map +1 -0
- package/dist/kinds/cache.kind.js +90 -0
- package/dist/kinds/cache.kind.js.map +1 -0
- package/dist/kinds/database.kind.d.ts +141 -0
- package/dist/kinds/database.kind.d.ts.map +1 -0
- package/dist/kinds/database.kind.js +103 -0
- package/dist/kinds/database.kind.js.map +1 -0
- package/dist/kinds/discovery.d.ts +20 -0
- package/dist/kinds/discovery.d.ts.map +1 -0
- package/dist/kinds/discovery.js +25 -0
- package/dist/kinds/discovery.js.map +1 -0
- package/dist/kinds/git-hosting.kind.d.ts +98 -0
- package/dist/kinds/git-hosting.kind.d.ts.map +1 -0
- package/dist/kinds/git-hosting.kind.js +81 -0
- package/dist/kinds/git-hosting.kind.js.map +1 -0
- package/dist/kinds/index.d.ts +16 -0
- package/dist/kinds/index.d.ts.map +1 -0
- package/dist/kinds/index.js +16 -0
- package/dist/kinds/index.js.map +1 -0
- package/dist/kinds/logs.kind.d.ts +91 -0
- package/dist/kinds/logs.kind.d.ts.map +1 -0
- package/dist/kinds/logs.kind.js +73 -0
- package/dist/kinds/logs.kind.js.map +1 -0
- package/dist/kinds/object-storage.kind.d.ts +85 -0
- package/dist/kinds/object-storage.kind.d.ts.map +1 -0
- package/dist/kinds/object-storage.kind.js +81 -0
- package/dist/kinds/object-storage.kind.js.map +1 -0
- package/dist/kinds/observability.kind.d.ts +176 -0
- package/dist/kinds/observability.kind.d.ts.map +1 -0
- package/dist/kinds/observability.kind.js +120 -0
- package/dist/kinds/observability.kind.js.map +1 -0
- package/dist/kinds/package-registry.kind.d.ts +89 -0
- package/dist/kinds/package-registry.kind.d.ts.map +1 -0
- package/dist/kinds/package-registry.kind.js +78 -0
- package/dist/kinds/package-registry.kind.js.map +1 -0
- package/dist/kinds/queue.kind.d.ts +113 -0
- package/dist/kinds/queue.kind.d.ts.map +1 -0
- package/dist/kinds/queue.kind.js +86 -0
- package/dist/kinds/queue.kind.js.map +1 -0
- package/dist/kinds/rum.kind.d.ts +113 -0
- package/dist/kinds/rum.kind.d.ts.map +1 -0
- package/dist/kinds/rum.kind.js +80 -0
- package/dist/kinds/rum.kind.js.map +1 -0
- package/dist/kinds/sandbox.kind.d.ts +111 -0
- package/dist/kinds/sandbox.kind.d.ts.map +1 -0
- package/dist/kinds/sandbox.kind.js +94 -0
- package/dist/kinds/sandbox.kind.js.map +1 -0
- package/dist/kinds/web-app.kind.d.ts +99 -0
- package/dist/kinds/web-app.kind.d.ts.map +1 -0
- package/dist/kinds/web-app.kind.js +86 -0
- package/dist/kinds/web-app.kind.js.map +1 -0
- package/dist/kinds/worker.kind.d.ts +244 -0
- package/dist/kinds/worker.kind.d.ts.map +1 -0
- package/dist/kinds/worker.kind.js +171 -0
- package/dist/kinds/worker.kind.js.map +1 -0
- package/dist/schemas.d.ts +125 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +102 -0
- package/dist/schemas.js.map +1 -0
- package/package.json +92 -0
- package/src/bootstrap/index.ts +15 -0
- package/src/bootstrap/seed.descriptor.ts +24 -0
- package/src/bootstrap/seed.impl-shape.ts +5 -0
- package/src/bootstrap/seed.kind.ts +26 -0
- package/src/bootstrap/seed.runner.ts +87 -0
- package/src/credentials/resolve.ts +205 -0
- package/src/deployment.ts +57 -0
- package/src/index.ts +149 -0
- package/src/infra.plugin.ts +54 -0
- package/src/kinds/alerts.kind.ts +164 -0
- package/src/kinds/artifact.kind.ts +96 -0
- package/src/kinds/cache.kind.ts +104 -0
- package/src/kinds/database.kind.ts +120 -0
- package/src/kinds/discovery.ts +26 -0
- package/src/kinds/git-hosting.kind.ts +100 -0
- package/src/kinds/index.ts +139 -0
- package/src/kinds/logs.kind.ts +104 -0
- package/src/kinds/object-storage.kind.ts +101 -0
- package/src/kinds/observability.kind.ts +178 -0
- package/src/kinds/package-registry.kind.ts +95 -0
- package/src/kinds/queue.kind.ts +102 -0
- package/src/kinds/rum.kind.ts +135 -0
- package/src/kinds/sandbox.kind.ts +115 -0
- package/src/kinds/web-app.kind.ts +103 -0
- package/src/kinds/worker.kind.ts +203 -0
- package/src/schemas.ts +127 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kind: infra/sandbox
|
|
3
|
+
*
|
|
4
|
+
* Persistent isolated execution environment with shell, filesystem, and
|
|
5
|
+
* subprocess capabilities. Used for agent code execution, tool sandboxing,
|
|
6
|
+
* and long-running background tasks.
|
|
7
|
+
*
|
|
8
|
+
* Schema shape: strict common base + `config` discriminated union.
|
|
9
|
+
*
|
|
10
|
+
* - The base defines fields universal across every adapter:
|
|
11
|
+
* id/kind/name + the sandbox shape (entrypoint, image, limits,
|
|
12
|
+
* outboundProxy, liveView, persistent, env).
|
|
13
|
+
* - Adapter-specific fields live under `config`. Each adapter package
|
|
14
|
+
* defines its own concrete schema under its discriminator key.
|
|
15
|
+
*/
|
|
16
|
+
import * as z from 'zod/v4';
|
|
17
|
+
import { createRuntimeKind } from '@vibesdotdev/runtime/factory/kind';
|
|
18
|
+
import type { RuntimeKindDescriptorRecord } from '@vibesdotdev/runtime/schemas/kind';
|
|
19
|
+
import { RuntimeDescriptorSchema } from '@vibesdotdev/runtime/schemas/descriptor';
|
|
20
|
+
import type { RuntimeDescriptor } from '@vibesdotdev/runtime/schemas/descriptor';
|
|
21
|
+
import { deploymentEnvRequirementSchema } from '../schemas.ts';
|
|
22
|
+
import { INFRA_DISCOVERY_PATTERN, extractStem } from './discovery.ts';
|
|
23
|
+
|
|
24
|
+
export const SandboxOutboundProxySchema = z.object({
|
|
25
|
+
binding: z.string().min(1),
|
|
26
|
+
workerPath: z.string().min(1).optional(),
|
|
27
|
+
allowedHosts: z.array(z.string()).default([])
|
|
28
|
+
});
|
|
29
|
+
export type SandboxOutboundProxy = z.infer<typeof SandboxOutboundProxySchema>;
|
|
30
|
+
|
|
31
|
+
export const SandboxResourceLimitsSchema = z.object({
|
|
32
|
+
cpu: z.string().optional(),
|
|
33
|
+
memory: z.string().optional(),
|
|
34
|
+
disk: z.string().optional(),
|
|
35
|
+
maxSubprocesses: z.number().int().positive().optional(),
|
|
36
|
+
timeoutSeconds: z.number().int().positive().optional()
|
|
37
|
+
});
|
|
38
|
+
export type SandboxResourceLimits = z.infer<typeof SandboxResourceLimitsSchema>;
|
|
39
|
+
|
|
40
|
+
const SandboxBaseSchema = RuntimeDescriptorSchema.extend({
|
|
41
|
+
kind: z.literal('infra/sandbox'),
|
|
42
|
+
|
|
43
|
+
/** Shell or script to run on sandbox start. */
|
|
44
|
+
entrypoint: z.string().optional(),
|
|
45
|
+
|
|
46
|
+
/** Container image or template snapshot. */
|
|
47
|
+
image: z.string().optional(),
|
|
48
|
+
|
|
49
|
+
/** Resource limits. */
|
|
50
|
+
limits: SandboxResourceLimitsSchema.optional(),
|
|
51
|
+
|
|
52
|
+
/** Outbound egress proxy (CF Outbound Workers for Sandboxes). */
|
|
53
|
+
outboundProxy: SandboxOutboundProxySchema.optional(),
|
|
54
|
+
|
|
55
|
+
/** Enable Live View for human-in-loop debugging. */
|
|
56
|
+
liveView: z.boolean().optional(),
|
|
57
|
+
|
|
58
|
+
/** Persist state between sessions. */
|
|
59
|
+
persistent: z.boolean().optional(),
|
|
60
|
+
|
|
61
|
+
/** Environment variable requirements. */
|
|
62
|
+
env: z.array(deploymentEnvRequirementSchema).optional()
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
export const CloudflareSandboxConfigSchema = z.object({
|
|
66
|
+
/** Container image or template snapshot. */
|
|
67
|
+
image: z.string().optional()
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
export const DockerSandboxConfigSchema = z.object({
|
|
71
|
+
/** Container image. */
|
|
72
|
+
image: z.string(),
|
|
73
|
+
/** Volume mounts (hostPath: containerPath). */
|
|
74
|
+
volumes: z.record(z.string(), z.string()).optional()
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
export const DigitalOceanDropletSandboxConfigSchema = z.object({
|
|
78
|
+
/** Droplet size slug (e.g., 's-2vcpu-2gb'). */
|
|
79
|
+
dropletSize: z.string().min(1)
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
export const SandboxConfigSchema = z.union([
|
|
83
|
+
CloudflareSandboxConfigSchema.extend({ adapter: z.literal('cloudflare-sandbox') }),
|
|
84
|
+
DockerSandboxConfigSchema.extend({ adapter: z.literal('docker') }),
|
|
85
|
+
DigitalOceanDropletSandboxConfigSchema.extend({ adapter: z.literal('digitalocean-droplet') })
|
|
86
|
+
]);
|
|
87
|
+
|
|
88
|
+
export const SandboxDescriptorSchema = SandboxBaseSchema.extend({
|
|
89
|
+
/**
|
|
90
|
+
* Adapter-specific configuration. Discriminated union — each adapter
|
|
91
|
+
* package defines its own config schema under its discriminator key.
|
|
92
|
+
*/
|
|
93
|
+
config: SandboxConfigSchema.optional()
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
export type SandboxDescriptor = z.infer<typeof SandboxDescriptorSchema>;
|
|
97
|
+
|
|
98
|
+
class DefaultSandboxImplementation {
|
|
99
|
+
constructor(
|
|
100
|
+
public readonly descriptor: RuntimeDescriptor,
|
|
101
|
+
public readonly context: unknown
|
|
102
|
+
) {}
|
|
103
|
+
|
|
104
|
+
get config(): SandboxDescriptor {
|
|
105
|
+
return this.descriptor as SandboxDescriptor;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export const sandboxKind = createRuntimeKind<SandboxDescriptor, DefaultSandboxImplementation>({
|
|
110
|
+
id: 'infra/sandbox',
|
|
111
|
+
descriptorSchema: SandboxDescriptorSchema,
|
|
112
|
+
defaultImplementation: DefaultSandboxImplementation,
|
|
113
|
+
discoveryPattern: INFRA_DISCOVERY_PATTERN,
|
|
114
|
+
extractStem
|
|
115
|
+
});
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kind: infra/web-app
|
|
3
|
+
*
|
|
4
|
+
* Describes a deployable web application (SvelteKit, static site, etc.).
|
|
5
|
+
*
|
|
6
|
+
* Schema shape: strict common base + `config` discriminated union.
|
|
7
|
+
*
|
|
8
|
+
* - The base defines fields universal across every adapter:
|
|
9
|
+
* id/kind/name + the deployment shape every web-app declares
|
|
10
|
+
* (domain, appDir, outputDir, runtime, env, dependsOn).
|
|
11
|
+
* - Adapter-specific fields (cfWorkerName, secretsStoreId, digitaloceanAppName, …)
|
|
12
|
+
* live exclusively under `config`. Each adapter package defines its own
|
|
13
|
+
* concrete schema under its discriminator key.
|
|
14
|
+
*/
|
|
15
|
+
import * as z from 'zod/v4';
|
|
16
|
+
import { createRuntimeKind } from '@vibesdotdev/runtime/factory/kind';
|
|
17
|
+
import type { RuntimeKindDescriptorRecord } from '@vibesdotdev/runtime/schemas/kind';
|
|
18
|
+
import { RuntimeDescriptorSchema } from '@vibesdotdev/runtime/schemas/descriptor';
|
|
19
|
+
import type { RuntimeDescriptor } from '@vibesdotdev/runtime/schemas/descriptor';
|
|
20
|
+
import { deploymentEnvRequirementSchema } from '../schemas.ts';
|
|
21
|
+
import { INFRA_DISCOVERY_PATTERN, extractStem } from './discovery.ts';
|
|
22
|
+
|
|
23
|
+
export const WebAppDependencySchema = z.object({
|
|
24
|
+
serviceId: z.string().min(1),
|
|
25
|
+
reason: z.string().optional()
|
|
26
|
+
});
|
|
27
|
+
export type WebAppDependency = z.infer<typeof WebAppDependencySchema>;
|
|
28
|
+
|
|
29
|
+
const WebAppBaseSchema = RuntimeDescriptorSchema.extend({
|
|
30
|
+
kind: z.literal('infra/web-app'),
|
|
31
|
+
|
|
32
|
+
/** Primary domain for this app (e.g., 'auth.vibes.dev'). */
|
|
33
|
+
domain: z.string().min(1),
|
|
34
|
+
|
|
35
|
+
/** Application source directory (e.g., 'apps/auth-web'). */
|
|
36
|
+
appDir: z.string().min(1),
|
|
37
|
+
|
|
38
|
+
/** Build output directory (e.g., '.svelte-kit/cloudflare'). */
|
|
39
|
+
outputDir: z.string().min(1),
|
|
40
|
+
|
|
41
|
+
/** Runtime environment for app deployments. */
|
|
42
|
+
runtime: z.enum(['edge', 'node']),
|
|
43
|
+
|
|
44
|
+
/** Environment variable requirements. */
|
|
45
|
+
env: z.array(deploymentEnvRequirementSchema).optional(),
|
|
46
|
+
|
|
47
|
+
/** Service dependencies. */
|
|
48
|
+
dependsOn: z.array(WebAppDependencySchema).optional()
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
export const CloudflareWorkersWebAppConfigSchema = z.object({
|
|
52
|
+
/** Cloudflare Workers script name (e.g., "vibes-ai"). */
|
|
53
|
+
cfWorkerName: z.string().min(1),
|
|
54
|
+
/** Path to the `_worker.js` entry point relative to outputDir. */
|
|
55
|
+
workerEntry: z.string().min(1).default('_worker.js'),
|
|
56
|
+
/** Compatibility date for wrangler. */
|
|
57
|
+
compatibilityDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),
|
|
58
|
+
/** Compatibility flags for wrangler. */
|
|
59
|
+
compatibilityFlags: z.array(z.string()).default(['nodejs_compat']),
|
|
60
|
+
/** Environment variables to include. */
|
|
61
|
+
env: z.record(z.string(), z.string()).default({}),
|
|
62
|
+
/** Cloudflare Secrets Store ID for secret bindings. */
|
|
63
|
+
secretsStoreId: z.string().min(1).optional()
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
export const DigitalOceanAppWebAppConfigSchema = z.object({
|
|
67
|
+
/** DigitalOcean App name. */
|
|
68
|
+
digitaloceanAppName: z.string().min(1)
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
export const WebAppConfigSchema = z.union([
|
|
72
|
+
CloudflareWorkersWebAppConfigSchema.extend({ adapter: z.literal('cloudflare-workers') }),
|
|
73
|
+
DigitalOceanAppWebAppConfigSchema.extend({ adapter: z.literal('digitalocean-apps') })
|
|
74
|
+
]);
|
|
75
|
+
|
|
76
|
+
export const WebAppDescriptorSchema = WebAppBaseSchema.extend({
|
|
77
|
+
/**
|
|
78
|
+
* Adapter-specific configuration. Discriminated union — each adapter
|
|
79
|
+
* package defines its own config schema under its discriminator key.
|
|
80
|
+
*/
|
|
81
|
+
config: WebAppConfigSchema.optional()
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
export type WebAppDescriptor = z.infer<typeof WebAppDescriptorSchema>;
|
|
85
|
+
|
|
86
|
+
class DefaultWebAppImplementation {
|
|
87
|
+
constructor(
|
|
88
|
+
public readonly descriptor: RuntimeDescriptor,
|
|
89
|
+
public readonly context: unknown
|
|
90
|
+
) {}
|
|
91
|
+
|
|
92
|
+
get config(): WebAppDescriptor {
|
|
93
|
+
return this.descriptor as WebAppDescriptor;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export const webAppKind = createRuntimeKind<WebAppDescriptor, DefaultWebAppImplementation>({
|
|
98
|
+
id: 'infra/web-app',
|
|
99
|
+
descriptorSchema: WebAppDescriptorSchema,
|
|
100
|
+
defaultImplementation: DefaultWebAppImplementation,
|
|
101
|
+
discoveryPattern: INFRA_DISCOVERY_PATTERN,
|
|
102
|
+
extractStem
|
|
103
|
+
});
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kind: infra/worker
|
|
3
|
+
*
|
|
4
|
+
* Describes a background worker process.
|
|
5
|
+
*
|
|
6
|
+
* Schema shape: strict common base + `config` discriminated union.
|
|
7
|
+
*
|
|
8
|
+
* - The base defines fields universal across adapters: id/kind/name +
|
|
9
|
+
* the worker shape (entrypoint, queues, concurrency, scaling, env).
|
|
10
|
+
* - Adapter-specific fields (namespace, image, healthPort, …) live under
|
|
11
|
+
* `config`. Each adapter package defines its own concrete schema.
|
|
12
|
+
*/
|
|
13
|
+
import * as z from 'zod/v4';
|
|
14
|
+
import { createRuntimeKind } from '@vibesdotdev/runtime/factory/kind';
|
|
15
|
+
import type { RuntimeKindDescriptorRecord } from '@vibesdotdev/runtime/schemas/kind';
|
|
16
|
+
import { RuntimeDescriptorSchema } from '@vibesdotdev/runtime/schemas/descriptor';
|
|
17
|
+
import type { RuntimeDescriptor } from '@vibesdotdev/runtime/schemas/descriptor';
|
|
18
|
+
import { deploymentEnvRequirementSchema } from '../schemas.ts';
|
|
19
|
+
import { INFRA_DISCOVERY_PATTERN, extractStem } from './discovery.ts';
|
|
20
|
+
|
|
21
|
+
export const WorkerScalingSchema = z.object({
|
|
22
|
+
min: z.number().int().nonnegative().default(1),
|
|
23
|
+
max: z.number().int().positive().default(1),
|
|
24
|
+
cpu: z.string().optional(),
|
|
25
|
+
memory: z.string().optional()
|
|
26
|
+
});
|
|
27
|
+
export type WorkerScaling = z.infer<typeof WorkerScalingSchema>;
|
|
28
|
+
|
|
29
|
+
const WorkerBaseSchema = RuntimeDescriptorSchema.extend({
|
|
30
|
+
kind: z.literal('infra/worker'),
|
|
31
|
+
|
|
32
|
+
/** Path to worker entrypoint (e.g., 'packages/workers/src/ai/entrypoint.ts'). */
|
|
33
|
+
entrypoint: z.string().min(1).optional(),
|
|
34
|
+
|
|
35
|
+
/** Queue names this worker consumes from. */
|
|
36
|
+
queues: z.array(z.string().min(1)).optional(),
|
|
37
|
+
|
|
38
|
+
/** Worker concurrency. */
|
|
39
|
+
concurrency: z.number().int().positive().optional(),
|
|
40
|
+
|
|
41
|
+
/** Scaling configuration. */
|
|
42
|
+
scaling: WorkerScalingSchema.optional(),
|
|
43
|
+
|
|
44
|
+
/** Environment variable requirements. */
|
|
45
|
+
env: z.array(deploymentEnvRequirementSchema).optional()
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
export const DoksDeploymentWorkerConfigSchema = z.object({
|
|
49
|
+
/** Kubernetes namespace (default: vibes). */
|
|
50
|
+
namespace: z.string().min(1).default('vibes'),
|
|
51
|
+
/** Container image (default: vibes/{id}:latest). */
|
|
52
|
+
image: z.string().min(1).optional(),
|
|
53
|
+
/** Health probe port (default: 8080). */
|
|
54
|
+
healthPort: z.number().int().positive().default(8080),
|
|
55
|
+
/** Health probe path (default: /healthz). */
|
|
56
|
+
healthPath: z.string().min(1).default('/healthz'),
|
|
57
|
+
/** Readiness probe path (default: /readyz). */
|
|
58
|
+
readyPath: z.string().min(1).default('/readyz')
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
export const CloudflareWorkersWorkerConfigSchema = z.object({
|
|
62
|
+
/** Cloudflare Workers script name (e.g., "vibes-jobs"). */
|
|
63
|
+
cfWorkerName: z.string().min(1),
|
|
64
|
+
/** Path to the `_worker.js` entry point relative to outputDir. */
|
|
65
|
+
workerEntry: z.string().min(1).default('_worker.js'),
|
|
66
|
+
/** Compatibility date for wrangler. */
|
|
67
|
+
compatibilityDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),
|
|
68
|
+
/** Compatibility flags for wrangler. */
|
|
69
|
+
compatibilityFlags: z.array(z.string()).default(['nodejs_compat']),
|
|
70
|
+
/** Environment variables to include. */
|
|
71
|
+
env: z.record(z.string(), z.string()).default({}),
|
|
72
|
+
/** Cloudflare Secrets Store ID for secret bindings. */
|
|
73
|
+
secretsStoreId: z.string().min(1).optional(),
|
|
74
|
+
/**
|
|
75
|
+
* Detailed queue-consumer config. When present, these override the
|
|
76
|
+
* coarse `queues: string[]` field on the base descriptor and let
|
|
77
|
+
* declarations control batch size, retries, and dead-letter routing.
|
|
78
|
+
*/
|
|
79
|
+
consumers: z
|
|
80
|
+
.array(
|
|
81
|
+
z.object({
|
|
82
|
+
queue: z.string().min(1),
|
|
83
|
+
maxBatchSize: z.number().int().positive().default(10),
|
|
84
|
+
maxRetries: z.number().int().min(0).default(3),
|
|
85
|
+
deadLetterQueue: z.string().optional()
|
|
86
|
+
})
|
|
87
|
+
)
|
|
88
|
+
.default([]),
|
|
89
|
+
/** Durable Object class bindings. */
|
|
90
|
+
durableObjects: z
|
|
91
|
+
.array(
|
|
92
|
+
z.object({
|
|
93
|
+
binding: z.string().regex(/^[_A-Z0-9]+$/),
|
|
94
|
+
className: z.string().min(1),
|
|
95
|
+
scriptName: z.string().min(1).optional()
|
|
96
|
+
})
|
|
97
|
+
)
|
|
98
|
+
.default([]),
|
|
99
|
+
/** Durable Object migrations. */
|
|
100
|
+
migrations: z
|
|
101
|
+
.array(
|
|
102
|
+
z.object({
|
|
103
|
+
tag: z.string().min(1),
|
|
104
|
+
newClasses: z.array(z.string().min(1)).optional(),
|
|
105
|
+
renamedClasses: z
|
|
106
|
+
.array(z.object({ from: z.string().min(1), to: z.string().min(1) }))
|
|
107
|
+
.optional(),
|
|
108
|
+
deletedClasses: z.array(z.string().min(1)).optional(),
|
|
109
|
+
newSqliteClasses: z.array(z.string().min(1)).optional()
|
|
110
|
+
})
|
|
111
|
+
)
|
|
112
|
+
.default([]),
|
|
113
|
+
/** Service bindings — call other Workers from this Worker. */
|
|
114
|
+
services: z
|
|
115
|
+
.array(
|
|
116
|
+
z.object({
|
|
117
|
+
binding: z.string().regex(/^[_A-Z0-9]+$/),
|
|
118
|
+
service: z.string().min(1),
|
|
119
|
+
environment: z.string().min(1).optional()
|
|
120
|
+
})
|
|
121
|
+
)
|
|
122
|
+
.default([]),
|
|
123
|
+
/** D1 database bindings. */
|
|
124
|
+
d1Databases: z
|
|
125
|
+
.array(
|
|
126
|
+
z.object({
|
|
127
|
+
binding: z.string().regex(/^[_A-Z0-9]+$/),
|
|
128
|
+
databaseName: z.string().min(1),
|
|
129
|
+
databaseId: z.string().min(1)
|
|
130
|
+
})
|
|
131
|
+
)
|
|
132
|
+
.default([]),
|
|
133
|
+
/** KV namespace bindings. */
|
|
134
|
+
kvNamespaces: z
|
|
135
|
+
.array(
|
|
136
|
+
z.object({
|
|
137
|
+
binding: z.string().min(1),
|
|
138
|
+
id: z.string().min(1)
|
|
139
|
+
})
|
|
140
|
+
)
|
|
141
|
+
.default([]),
|
|
142
|
+
/** R2 bucket bindings. */
|
|
143
|
+
r2Buckets: z
|
|
144
|
+
.array(
|
|
145
|
+
z.object({
|
|
146
|
+
binding: z.string().min(1),
|
|
147
|
+
bucketName: z.string().min(1)
|
|
148
|
+
})
|
|
149
|
+
)
|
|
150
|
+
.default([]),
|
|
151
|
+
/** Queue producer bindings (worker can also produce to queues). */
|
|
152
|
+
queueProducers: z
|
|
153
|
+
.array(
|
|
154
|
+
z.object({
|
|
155
|
+
queue: z.string().min(1),
|
|
156
|
+
binding: z.string().min(1)
|
|
157
|
+
})
|
|
158
|
+
)
|
|
159
|
+
.default([]),
|
|
160
|
+
/** Enable smart placement. */
|
|
161
|
+
smartPlacement: z.boolean().default(false),
|
|
162
|
+
/**
|
|
163
|
+
* Whether this is a job-consumer Worker. When true, deploy step
|
|
164
|
+
* auto-injects the JOB_RESULT_STORE Durable Object binding +
|
|
165
|
+
* initial migration via `generateJobConsumerWorkerConfig` from
|
|
166
|
+
* `@vibesdotdev/infra-cloudflare`.
|
|
167
|
+
*/
|
|
168
|
+
jobConsumer: z.boolean().default(false)
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
export const WorkerConfigSchema = z.union([
|
|
172
|
+
DoksDeploymentWorkerConfigSchema.extend({ adapter: z.literal('doks-deployment') }),
|
|
173
|
+
CloudflareWorkersWorkerConfigSchema.extend({ adapter: z.literal('cloudflare-workers') })
|
|
174
|
+
]);
|
|
175
|
+
|
|
176
|
+
export const WorkerDescriptorSchema = WorkerBaseSchema.extend({
|
|
177
|
+
/**
|
|
178
|
+
* Adapter-specific configuration. Discriminated union — each adapter
|
|
179
|
+
* package defines its own config schema under its discriminator key.
|
|
180
|
+
*/
|
|
181
|
+
config: WorkerConfigSchema.optional()
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
export type WorkerDescriptor = z.infer<typeof WorkerDescriptorSchema>;
|
|
185
|
+
|
|
186
|
+
class DefaultWorkerImplementation {
|
|
187
|
+
constructor(
|
|
188
|
+
public readonly descriptor: RuntimeDescriptor,
|
|
189
|
+
public readonly context: unknown
|
|
190
|
+
) {}
|
|
191
|
+
|
|
192
|
+
get config(): WorkerDescriptor {
|
|
193
|
+
return this.descriptor as WorkerDescriptor;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export const workerKind = createRuntimeKind<WorkerDescriptor, DefaultWorkerImplementation>({
|
|
198
|
+
id: 'infra/worker',
|
|
199
|
+
descriptorSchema: WorkerDescriptorSchema,
|
|
200
|
+
defaultImplementation: DefaultWorkerImplementation,
|
|
201
|
+
discoveryPattern: INFRA_DISCOVERY_PATTERN,
|
|
202
|
+
extractStem
|
|
203
|
+
});
|
package/src/schemas.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as z from 'zod/v4';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Deployment providers with active adapter implementations.
|
|
5
|
+
* Only providers backed by adapter packages are enumerated.
|
|
6
|
+
* - cloudflare-workers: via infra-cloudflare
|
|
7
|
+
* - digitalocean-app: via infra-doks
|
|
8
|
+
*/
|
|
9
|
+
export const deploymentProviderSchema = z.enum([
|
|
10
|
+
'cloudflare-workers',
|
|
11
|
+
'digitalocean-app'
|
|
12
|
+
]);
|
|
13
|
+
export type DeploymentProvider = z.infer<typeof deploymentProviderSchema>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Map of valid provider × runtime combinations.
|
|
17
|
+
* Used for cross-validation in appDeploymentSchema refinement.
|
|
18
|
+
*/
|
|
19
|
+
const VALID_PROVIDER_RUNTIME_MATRIX: Record<DeploymentProvider, readonly string[]> = {
|
|
20
|
+
'cloudflare-workers': ['edge', 'worker'],
|
|
21
|
+
'digitalocean-app': ['node', 'worker']
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const appRuntimeSchema = z.enum(['edge', 'node', 'worker', 'browser']);
|
|
25
|
+
export type AppRuntime = z.infer<typeof appRuntimeSchema>;
|
|
26
|
+
|
|
27
|
+
export const deploymentOriginSchema = z.object({
|
|
28
|
+
hostname: z.string().min(1),
|
|
29
|
+
origin: z.string().url(),
|
|
30
|
+
kind: z.enum(['primary', 'redirect', 'preview', 'internal']).default('primary'),
|
|
31
|
+
description: z.string().optional()
|
|
32
|
+
});
|
|
33
|
+
export type DeploymentOrigin = z.infer<typeof deploymentOriginSchema>;
|
|
34
|
+
|
|
35
|
+
export const deploymentBuildSchema = z.object({
|
|
36
|
+
workspaceRootDir: z.string().min(1).default('.'),
|
|
37
|
+
appDir: z.string().min(1),
|
|
38
|
+
installCommand: z.string().min(1).optional(),
|
|
39
|
+
buildCommand: z.string().min(1),
|
|
40
|
+
outputDir: z.string().min(1)
|
|
41
|
+
});
|
|
42
|
+
export type DeploymentBuild = z.infer<typeof deploymentBuildSchema>;
|
|
43
|
+
|
|
44
|
+
export const deploymentEnvRequirementSchema = z.object({
|
|
45
|
+
name: z.string().regex(/^[_A-Z0-9]+$/),
|
|
46
|
+
public: z.boolean().optional(),
|
|
47
|
+
required: z.boolean().optional(),
|
|
48
|
+
value: z.string().optional(),
|
|
49
|
+
secret: z.boolean().optional(),
|
|
50
|
+
description: z.string().optional(),
|
|
51
|
+
/**
|
|
52
|
+
* Override the secret name in the remote store. Defaults to `name` when omitted.
|
|
53
|
+
* Only meaningful when `secret: true` and the deployment targets a shared
|
|
54
|
+
* Secrets Store binding (e.g. `secrets_store_secrets[].secret_name`).
|
|
55
|
+
*/
|
|
56
|
+
storeKey: z.string().min(1).optional()
|
|
57
|
+
});
|
|
58
|
+
export type DeploymentEnvRequirement = z.infer<typeof deploymentEnvRequirementSchema>;
|
|
59
|
+
|
|
60
|
+
export const deploymentDependencySchema = z.object({
|
|
61
|
+
appId: z.string().min(1),
|
|
62
|
+
reason: z.string().min(1)
|
|
63
|
+
});
|
|
64
|
+
export type DeploymentDependency = z.infer<typeof deploymentDependencySchema>;
|
|
65
|
+
|
|
66
|
+
export const deploymentUpstreamSchema = z.object({
|
|
67
|
+
name: z.string().min(1),
|
|
68
|
+
origin: z.string().url(),
|
|
69
|
+
purpose: z.string().min(1),
|
|
70
|
+
originEnvVar: z
|
|
71
|
+
.string()
|
|
72
|
+
.regex(/^[_A-Z0-9]+$/)
|
|
73
|
+
.optional()
|
|
74
|
+
});
|
|
75
|
+
export type DeploymentUpstream = z.infer<typeof deploymentUpstreamSchema>;
|
|
76
|
+
|
|
77
|
+
export const appDeploymentSchema = z
|
|
78
|
+
.object({
|
|
79
|
+
appId: z.string().min(1),
|
|
80
|
+
appName: z.string().min(1),
|
|
81
|
+
provider: deploymentProviderSchema,
|
|
82
|
+
runtime: appRuntimeSchema,
|
|
83
|
+
build: deploymentBuildSchema,
|
|
84
|
+
origins: z.array(deploymentOriginSchema).min(1),
|
|
85
|
+
env: z.array(deploymentEnvRequirementSchema).default([]),
|
|
86
|
+
dependsOn: z.array(deploymentDependencySchema).default([]),
|
|
87
|
+
upstreams: z.array(deploymentUpstreamSchema).default([]),
|
|
88
|
+
tags: z.array(z.string()).default([]),
|
|
89
|
+
/** Cloudflare KV namespace bindings (provider-specific extension). */
|
|
90
|
+
kvNamespaces: z
|
|
91
|
+
.array(
|
|
92
|
+
z.object({
|
|
93
|
+
binding: z.string().min(1),
|
|
94
|
+
id: z.string().min(1),
|
|
95
|
+
preview_id: z.string().optional()
|
|
96
|
+
})
|
|
97
|
+
)
|
|
98
|
+
.default([]),
|
|
99
|
+
/**
|
|
100
|
+
* One-off commands to run before the Worker deploy (e.g. DB migrations,
|
|
101
|
+
* seed scripts, cache warmers). Executed sequentially in the appDir.
|
|
102
|
+
*/
|
|
103
|
+
preDeployCommands: z
|
|
104
|
+
.array(
|
|
105
|
+
z.object({
|
|
106
|
+
command: z.string().min(1),
|
|
107
|
+
description: z.string().optional()
|
|
108
|
+
})
|
|
109
|
+
)
|
|
110
|
+
.default([])
|
|
111
|
+
})
|
|
112
|
+
.refine(
|
|
113
|
+
(data: { provider: DeploymentProvider; runtime: string }) => {
|
|
114
|
+
const validRuntimes = VALID_PROVIDER_RUNTIME_MATRIX[data.provider];
|
|
115
|
+
return validRuntimes.includes(data.runtime);
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
error: (issue) => {
|
|
119
|
+
const data = issue.input as { provider: DeploymentProvider; runtime: string };
|
|
120
|
+
return `Invalid runtime "${data.runtime}" for provider "${data.provider}". Valid runtimes: ${VALID_PROVIDER_RUNTIME_MATRIX[data.provider].join(', ')}`;
|
|
121
|
+
},
|
|
122
|
+
path: ['runtime']
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
export type AppDeploymentInput = z.input<typeof appDeploymentSchema>;
|
|
127
|
+
export type AppDeployment = z.infer<typeof appDeploymentSchema>;
|