@kaupang/core 0.1.0

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 ADDED
@@ -0,0 +1,39 @@
1
+ # @kaupang/core
2
+
3
+ [![npm](https://img.shields.io/npm/v/@kaupang/core.svg)](https://www.npmjs.com/package/@kaupang/core)
4
+ [![license](https://img.shields.io/npm/l/@kaupang/core.svg)](https://github.com/kaupang-dev/kaupang/blob/main/LICENSE)
5
+
6
+ > The engine + config-authoring API behind
7
+ > [kaupang](https://github.com/kaupang-dev/kaupang).
8
+ > **Most people want the CLI:** [`@kaupang/cli`](https://www.npmjs.com/package/@kaupang/cli)
9
+ > (`npm i -g @kaupang/cli`).
10
+
11
+ This package provides the typed helpers you use to author a kaupang config — you import
12
+ it in your `kaupang.config.ts` and environment files:
13
+
14
+ ```ts
15
+ import { defineConfig, defineEnvironment, secret, use } from "@kaupang/core";
16
+ ```
17
+
18
+ - `defineConfig(config)` / `defineEnvironment(env)` — identity helpers with full
19
+ type-checking + autocomplete.
20
+ - `secret("VAR")` — a value resolved from the environment at deploy time, never written
21
+ to the generated artifact or the ledger.
22
+ - `use("preset", overrides?)` — reference a shared catalog preset.
23
+ - `defineSolution` / `definePipeline` / `defineService` — for solutions, pipelines, and
24
+ reusable service specs.
25
+ - All config **types** (`KaupangConfig`, `ServiceSpec`, `EnvironmentDefinition`, …).
26
+
27
+ You don't import this to *run* deploys — that's the CLI's job; `@kaupang/cli` depends on
28
+ it. It ships as a normal dependency so your config files resolve the helpers and types.
29
+
30
+ > An engine surface is also exposed under `@kaupang/core/internal`, but that subpath is
31
+ > **internal** — consumed by `@kaupang/cli`, not part of the stable public API.
32
+
33
+ ## Docs
34
+
35
+ See the [project README](https://github.com/kaupang-dev/kaupang#readme).
36
+
37
+ ## License
38
+
39
+ MIT © Andreas Quist Batista
@@ -0,0 +1,30 @@
1
+ import { K as KaupangConfig, E as EnvironmentDefinition, P as Pipeline, S as ServiceSpec, a as SolutionRecipe, b as SecretRef, C as CatalogRef } from './types-CNSMXHRO.js';
2
+ export { B as BackendName, c as BuildConfig, d as CatalogConfig, e as CatalogSourceConfig, D as Dependable, f as EnvMap, g as EnvValue, H as HealthcheckConfig, h as HookCommand, i as Hooks, j as PipelineStep, k as PullPolicy, l as ServiceDefinition, m as ServiceInput, T as TargetConfig, W as WaitSpec } from './types-CNSMXHRO.js';
3
+
4
+ /** Identity helper with full type-checking + autocomplete in kaupang.config.ts. */
5
+ declare function defineConfig(config: KaupangConfig): KaupangConfig;
6
+ /** Identity helper for environment files. */
7
+ declare function defineEnvironment(env: EnvironmentDefinition): EnvironmentDefinition;
8
+ /** Identity helper for a reusable service spec (e.g. shared in your repo). */
9
+ declare function defineService(spec: ServiceSpec): ServiceSpec;
10
+ /**
11
+ * Reference a service preset from the catalog, optionally overriding fields:
12
+ *
13
+ * services: { db: use("postgres", { env: { POSTGRES_DB: "shop" } }) }
14
+ */
15
+ declare function use(name: string, overrides?: Partial<ServiceSpec>): CatalogRef;
16
+ /**
17
+ * Mark an env value as a secret. kaupang emits a `${NAME}` reference (resolved by
18
+ * Docker at runtime from the process env) instead of writing the value into the
19
+ * generated artifact or the ledger:
20
+ *
21
+ * env: { DB_PASSWORD: secret("DB_PASSWORD") } // same name
22
+ * env: { DB_PASSWORD: secret("PROD_DB_PASSWORD") } // different source var
23
+ */
24
+ declare function secret(name: string): SecretRef;
25
+ /** Identity helper for a solution recipe (a named composition of environments). */
26
+ declare function defineSolution(recipe: SolutionRecipe): SolutionRecipe;
27
+ /** Identity helper for a pipeline (ordered run / up / down / build / wait steps). */
28
+ declare function definePipeline(pipeline: Pipeline): Pipeline;
29
+
30
+ export { CatalogRef, EnvironmentDefinition, KaupangConfig, Pipeline, SecretRef, ServiceSpec, SolutionRecipe, defineConfig, defineEnvironment, definePipeline, defineService, defineSolution, secret, use };
package/dist/index.js ADDED
@@ -0,0 +1,31 @@
1
+ // src/config/define.ts
2
+ function defineConfig(config) {
3
+ return config;
4
+ }
5
+ function defineEnvironment(env) {
6
+ return env;
7
+ }
8
+ function defineService(spec) {
9
+ return spec;
10
+ }
11
+ function use(name, overrides) {
12
+ return overrides ? { $catalog: name, overrides } : { $catalog: name };
13
+ }
14
+ function secret(name) {
15
+ return { $secret: name };
16
+ }
17
+ function defineSolution(recipe) {
18
+ return recipe;
19
+ }
20
+ function definePipeline(pipeline) {
21
+ return pipeline;
22
+ }
23
+ export {
24
+ defineConfig,
25
+ defineEnvironment,
26
+ definePipeline,
27
+ defineService,
28
+ defineSolution,
29
+ secret,
30
+ use
31
+ };
@@ -0,0 +1,397 @@
1
+ import { S as ServiceSpec, a as SolutionRecipe, d as CatalogConfig, l as ServiceDefinition, f as EnvMap, i as Hooks, E as EnvironmentDefinition, k as PullPolicy, D as Dependable, K as KaupangConfig, B as BackendName, g as EnvValue, b as SecretRef, h as HookCommand } from './types-CNSMXHRO.js';
2
+ export { c as BuildConfig, C as CatalogRef, e as CatalogSourceConfig, H as HealthcheckConfig, P as Pipeline, j as PipelineStep, m as ServiceInput, T as TargetConfig, W as WaitSpec } from './types-CNSMXHRO.js';
3
+
4
+ /** A catalog manifest: reusable service presets and/or solution recipes. */
5
+ interface CatalogManifest {
6
+ services?: Record<string, ServiceSpec>;
7
+ solutions?: Record<string, SolutionRecipe>;
8
+ }
9
+ interface CatalogSource {
10
+ readonly describe: string;
11
+ load(): Promise<CatalogManifest>;
12
+ }
13
+ /** Resolves presets and solutions against one or more sources (earlier sources win). */
14
+ interface CatalogResolver {
15
+ resolve(name: string): Promise<ServiceSpec>;
16
+ list(): Promise<string[]>;
17
+ resolveSolution(name: string): Promise<SolutionRecipe>;
18
+ listSolutions(): Promise<string[]>;
19
+ }
20
+ /** Build a resolver from config; lazily loads + caches each source's manifest. */
21
+ declare function createCatalogResolver(config: CatalogConfig | undefined, rootDir: string): CatalogResolver;
22
+
23
+ /** The normalized environment shape consumed by the resolver + backends. */
24
+ interface NormalizedEnvironment {
25
+ name: string;
26
+ file: string;
27
+ services: Record<string, ServiceDefinition>;
28
+ dependsOn: string[];
29
+ env: EnvMap;
30
+ hooks?: Hooks;
31
+ networks?: string[];
32
+ volumes?: string[];
33
+ }
34
+ interface NormalizeContext {
35
+ dockerRepository?: string;
36
+ defaultPull?: PullPolicy;
37
+ catalog: CatalogResolver;
38
+ }
39
+ declare function toArray(value?: Dependable): string[];
40
+ /**
41
+ * Prefix a bare image name with the docker repository.
42
+ * Fully-qualified names (anything containing "/") are left untouched, so
43
+ * public/official images should be written in full or pulled from the catalog.
44
+ */
45
+ declare function resolveImage(image: string | undefined, repo?: string): string | undefined;
46
+ declare function normalizeEnvironment(def: EnvironmentDefinition, name: string, file: string, ctx: NormalizeContext): Promise<NormalizedEnvironment>;
47
+
48
+ /** Normalized environment, ready for the resolver. */
49
+ type ResolvedEnvironment = NormalizedEnvironment;
50
+ interface LoadedConfig {
51
+ config: KaupangConfig;
52
+ configPath: string;
53
+ rootDir: string;
54
+ cacheDir: string;
55
+ project: string;
56
+ catalog: CatalogResolver;
57
+ environments: Map<string, ResolvedEnvironment>;
58
+ }
59
+ declare function findConfig(cwd?: string): string | null;
60
+ declare function loadConfig(cwd?: string): Promise<LoadedConfig>;
61
+
62
+ interface EnvironmentPlan {
63
+ name: string;
64
+ file: string;
65
+ /** Environment-scoped env vars (merged over globalEnv, under service env). */
66
+ env: EnvMap;
67
+ /** Environments this one directly depends on. */
68
+ dependsOn: string[];
69
+ /** Services in a valid start order. */
70
+ order: string[];
71
+ /** Services grouped into waves that can be started in parallel. */
72
+ waves: string[][];
73
+ services: Record<string, ServiceDefinition>;
74
+ /** Lifecycle hooks for this environment. */
75
+ hooks?: Hooks;
76
+ }
77
+ interface DeploymentPlan {
78
+ /** The environment the user asked for. */
79
+ target: string;
80
+ backend: BackendName;
81
+ /** Environments in start order: dependencies first, target last. */
82
+ environments: EnvironmentPlan[];
83
+ }
84
+ interface TopoResult {
85
+ order: string[];
86
+ waves: string[][];
87
+ }
88
+ /**
89
+ * Kahn's algorithm. `deps.get(n)` is the set of nodes that must come BEFORE n.
90
+ * Returns a flat order plus waves (each wave can be started concurrently).
91
+ * Throws on cycles or references to unknown nodes.
92
+ */
93
+ declare function topoSort(nodes: string[], deps: Map<string, string[]>, label: string): TopoResult;
94
+ /** Build a full deployment plan for `target` (including its transitive deps). */
95
+ declare function resolvePlan(target: string, environments: Map<string, ResolvedEnvironment>, backend: BackendName): DeploymentPlan;
96
+ /** Like resolvePlan but for several root environments (used by solutions). */
97
+ declare function resolveMultiPlan(roots: string[], label: string, environments: Map<string, ResolvedEnvironment>, backend: BackendName): DeploymentPlan;
98
+
99
+ interface BackendContext {
100
+ /** Directory containing kaupang.config.ts (also the cwd for spawned commands). */
101
+ rootDir: string;
102
+ /** Absolute path to the .kaupang cache directory. */
103
+ cacheDir: string;
104
+ /** Project namespace. */
105
+ project: string;
106
+ /** globalEnv merged with per-environment env (service env still wins on top). */
107
+ baseEnv: EnvMap;
108
+ /** Per-target env overrides (above environment env, below service env). */
109
+ targetEnv: EnvMap;
110
+ /** When set, force this pull behavior for the whole run (from --pull). */
111
+ pull?: PullPolicy;
112
+ }
113
+ interface BackendAction {
114
+ /** Human-readable description shown in dry-run. */
115
+ description: string;
116
+ file: string;
117
+ args: string[];
118
+ /** Optional stdin payload. */
119
+ input?: string;
120
+ }
121
+ interface MaterializedEnvironment {
122
+ /** Files to write before running actions (compose files, manifests, ...). */
123
+ files: {
124
+ path: string;
125
+ content: string;
126
+ }[];
127
+ /** Commands to bring the environment up. */
128
+ up: BackendAction[];
129
+ /** Commands to tear the environment down. */
130
+ down: BackendAction[];
131
+ /** Commands to build images for services that declare a build context. */
132
+ build: BackendAction[];
133
+ /** Commands to push built images to the registry (compose backend). */
134
+ push?: BackendAction[];
135
+ }
136
+ /**
137
+ * A backend is a pure translator: given a resolved environment it produces the
138
+ * files + commands needed. It performs no side effects — the command layer
139
+ * decides whether to write/execute (real run) or just print them (dry-run).
140
+ */
141
+ interface Backend {
142
+ readonly name: BackendName;
143
+ materialize(env: EnvironmentPlan, ctx: BackendContext): MaterializedEnvironment;
144
+ }
145
+
146
+ declare function makeContext(loaded: LoadedConfig, opts?: {
147
+ pull?: PullPolicy;
148
+ targetEnv?: EnvMap;
149
+ }): BackendContext;
150
+
151
+ declare function getBackend(name: BackendName): Backend;
152
+ declare const backendNames: BackendName[];
153
+
154
+ /** A resolved image: what was authored vs. the immutable digest we deploy. */
155
+ interface ResolvedImage {
156
+ service: string;
157
+ /** The reference as authored, e.g. "ghcr.io/acme/shop-api:latest". */
158
+ ref: string;
159
+ /** The resolved digest, e.g. "sha256:abc…". */
160
+ digest: string;
161
+ /** The digest-pinned reference we actually deploy, e.g. "ghcr.io/acme/shop-api@sha256:abc…". */
162
+ pinned: string;
163
+ /** True when the authored ref can point somewhere new on a later deploy. */
164
+ floating: boolean;
165
+ }
166
+ declare function isPinned(ref: string): boolean;
167
+ /**
168
+ * Resolve an image reference to a content digest by querying the registry.
169
+ * Uses `docker buildx imagetools inspect`, which returns the index/manifest
170
+ * digest (correct for multi-arch images). Already-pinned refs short-circuit.
171
+ */
172
+ declare function resolveDigest(ref: string): Promise<string>;
173
+ interface ResolveResult {
174
+ /** A copy of the plan with each service image rewritten to its pinned digest. */
175
+ env: EnvironmentPlan;
176
+ images: ResolvedImage[];
177
+ }
178
+ /**
179
+ * Resolve every registry-backed image in an environment to a pinned digest.
180
+ * Services with a local `build` context (and imageless services) are skipped —
181
+ * their images may not exist in any registry.
182
+ */
183
+ declare function resolveEnvironmentImages(env: EnvironmentPlan): Promise<ResolveResult>;
184
+
185
+ /** Everything deploying to a target implies: defaults, env overrides, and execution context. */
186
+ interface TargetRuntime {
187
+ name: string;
188
+ backend?: BackendName;
189
+ pull?: PullPolicy;
190
+ /** Target env overrides (merged over globalEnv + env, under service env). */
191
+ env: EnvMap;
192
+ /** Prepended to `docker …` invocations (e.g. ["--context", "prod"]). */
193
+ dockerContextArgs: string[];
194
+ /** Prepended to `kubectl …` invocations. */
195
+ kubectlContextArgs: string[];
196
+ /** Extra env injected into spawned processes (DOCKER_HOST / KUBECONFIG). */
197
+ processEnv: Record<string, string>;
198
+ }
199
+ declare function resolveTarget(config: KaupangConfig, name: string, rootDir: string): TargetRuntime;
200
+ interface AppliedAction {
201
+ file: string;
202
+ args: string[];
203
+ input?: string;
204
+ env?: Record<string, string>;
205
+ }
206
+ /** Apply a target's context flags + process env to a backend action. */
207
+ declare function applyTarget(action: BackendAction, rt: TargetRuntime): AppliedAction;
208
+
209
+ interface DeploymentRecord {
210
+ id: string;
211
+ environment: string;
212
+ /** Where it was deployed (defaults to "local"). Scopes the history. */
213
+ target: string;
214
+ backend: BackendName;
215
+ project: string;
216
+ ranAt: string;
217
+ status: "succeeded" | "failed";
218
+ /** When this deployment was a rollback, the id it restored. */
219
+ rollbackOf?: string;
220
+ /** The digests actually deployed (for display + auditing). */
221
+ images: ResolvedImage[];
222
+ /** Exactly what was applied, so a rollback replays it verbatim. */
223
+ files: {
224
+ path: string;
225
+ content: string;
226
+ }[];
227
+ up: BackendAction[];
228
+ down: BackendAction[];
229
+ }
230
+ interface Ledger {
231
+ version: number;
232
+ /** Keyed by `${environment}@${target}`. */
233
+ deployments: Record<string, DeploymentRecord[]>;
234
+ }
235
+ declare function readLedger(cacheDir: string): Ledger;
236
+ /** Sortable, human-ish id, e.g. "20260612T103045-a1b2". */
237
+ declare function newDeploymentId(date?: Date): string;
238
+ declare function appendDeployment(cacheDir: string, record: DeploymentRecord): void;
239
+ declare function history(cacheDir: string, environment: string, target: string): DeploymentRecord[];
240
+ declare function latestSuccessful(cacheDir: string, environment: string, target: string): DeploymentRecord | undefined;
241
+ /**
242
+ * The deployment to roll back TO. With `toId`, that exact (successful) record;
243
+ * otherwise the second-most-recent successful deployment (i.e. "the previous one").
244
+ */
245
+ declare function rollbackTarget(cacheDir: string, environment: string, target: string, toId?: string): DeploymentRecord | undefined;
246
+
247
+ interface ResolvedSolution {
248
+ name: string;
249
+ version?: string;
250
+ /** Top-level environments to deploy (their dependencies are resolved later). */
251
+ environments: string[];
252
+ /** Per-service image overrides, keyed by "environment.service". */
253
+ pins: Record<string, string>;
254
+ /** Env overlay applied across the solution. */
255
+ env: EnvMap;
256
+ /** Default target, if the recipe declares one. */
257
+ target?: string;
258
+ }
259
+ /**
260
+ * Resolve a solution by name. Inline `config.solutions` wins over the catalog,
261
+ * so a repo can override or define solutions locally; otherwise it falls back to
262
+ * the hosted catalog (the `service` / `http` / `file` sources).
263
+ */
264
+ declare function resolveSolution(config: KaupangConfig, catalog: CatalogResolver, name: string): Promise<ResolvedSolution>;
265
+ /** Override service images from solution pins (keyed by "environment.service"). */
266
+ declare function applyPins(plan: DeploymentPlan, pins: Record<string, string>): void;
267
+
268
+ declare const BUNDLE_MANIFEST = "manifest.json";
269
+ declare function isOciRef(ref: string): boolean;
270
+ interface BundleEnvironment {
271
+ name: string;
272
+ backend: BackendName;
273
+ images: ResolvedImage[];
274
+ /** Generated artifact, stored inside the bundle (path is bundle-relative). */
275
+ artifact: {
276
+ relPath: string;
277
+ content: string;
278
+ };
279
+ /** Commands whose file argument references `artifact.relPath` (bundle-relative). */
280
+ up: BackendAction[];
281
+ down: BackendAction[];
282
+ }
283
+ interface BundleManifest {
284
+ kaupang: string;
285
+ solution: string;
286
+ version?: string;
287
+ target: string;
288
+ project: string;
289
+ createdAt: string;
290
+ /** Whether image tarballs are included (airgap export). */
291
+ images: {
292
+ included: boolean;
293
+ tars: string[];
294
+ };
295
+ environments: BundleEnvironment[];
296
+ }
297
+ /**
298
+ * Rewrite a backend action's file argument from an absolute path to a
299
+ * bundle-relative one (used at bundle time), or back (at deploy time).
300
+ */
301
+ declare function rewriteActionPath(action: BackendAction, from: string, to: string): BackendAction;
302
+ declare function writeBundle(dir: string, manifest: BundleManifest): void;
303
+ declare function readBundle(dir: string): BundleManifest;
304
+ /** Package a bundle directory and push it as a single OCI artifact via oras. */
305
+ declare function pushBundle(dir: string, ociRef: string): Promise<void>;
306
+ /** Pull an OCI bundle artifact and extract it; returns the local bundle dir. */
307
+ declare function pullBundle(ociRef: string, intoParent: string): Promise<string>;
308
+
309
+ /** Render the full plan for a dry-run: environment graph + service waves + commands. */
310
+ declare function renderPlan(plan: DeploymentPlan, ctx: BackendContext, rt?: TargetRuntime): void;
311
+
312
+ interface RunOptions {
313
+ cwd: string;
314
+ /** When true, print the command but do not execute it. */
315
+ dryRun?: boolean;
316
+ /** Extra environment for the spawned process. */
317
+ env?: Record<string, string>;
318
+ /** Optional string piped to the process stdin (used for `kubectl apply -f -`). */
319
+ input?: string;
320
+ }
321
+ /** Toggle command echoing (set from the CLI's --verbose flag). */
322
+ declare function setVerbose(value: boolean): void;
323
+ /** Run a command with execa, echoing it first (verbose / dry-run). Honors dry-run. */
324
+ declare function run(file: string, args: string[], opts: RunOptions): Promise<void>;
325
+ /**
326
+ * True if a binary is resolvable on PATH (or is an existing absolute/relative path).
327
+ * Resolved by scanning PATH rather than spawning `<tool> --version` — the latter is
328
+ * unreliable cross-tool (`kubectl --version` is an unknown flag) and cross-platform
329
+ * (on Windows a missing binary and a bad flag both surface as a generic exit 1).
330
+ */
331
+ declare function hasBinary(file: string): Promise<boolean>;
332
+ /** Run a shell command (used for lifecycle hooks). Honors dry-run. */
333
+ declare function runShell(command: string, opts: RunOptions): Promise<void>;
334
+ /**
335
+ * The command-execution boundary. The real implementation shells out via execa;
336
+ * tests inject a fake that records calls, so the deploy/pipeline layers can be
337
+ * exercised — asserting which commands run, in what order, with which context —
338
+ * without a Docker daemon. Keep this surface tiny: it is the only seam between
339
+ * kaupang's pure logic and the outside world's side effects.
340
+ */
341
+ interface Executor {
342
+ run(file: string, args: string[], opts: RunOptions): Promise<void>;
343
+ runShell(command: string, opts: RunOptions): Promise<void>;
344
+ hasBinary(file: string): Promise<boolean>;
345
+ }
346
+ /** The real executor: execa-backed `run` / `runShell` / `hasBinary`. */
347
+ declare const defaultExecutor: Executor;
348
+ /** Parse "500ms" / "2s" / "5m" / "1h" into milliseconds. Bare numbers are seconds. */
349
+ declare function parseDuration(value: string | number): number;
350
+
351
+ interface DeployOptions {
352
+ targetName: string;
353
+ targetEnv: EnvMap;
354
+ pull?: PullPolicy;
355
+ /** Resolve image references to pinned digests before deploying. */
356
+ resolve: boolean;
357
+ }
358
+ /**
359
+ * Bring up every environment in a plan: validate secrets, run hooks, resolve +
360
+ * pin images, materialize, apply the target context, and record the ledger.
361
+ * Shared by `kaupang up` and pipeline `up` steps so behavior is identical.
362
+ */
363
+ declare function deployPlan(loaded: LoadedConfig, plan: DeploymentPlan, rt: TargetRuntime, opts: DeployOptions, executor?: Executor): Promise<DeploymentRecord[]>;
364
+
365
+ interface RunPipelineOptions {
366
+ target?: string;
367
+ dryRun: boolean;
368
+ }
369
+ declare function runPipeline(loaded: LoadedConfig, name: string, opts: RunPipelineOptions, executor?: Executor): Promise<void>;
370
+
371
+ declare function isSecret(value: EnvValue): value is SecretRef;
372
+ /** Merge env maps left → right (later wins). Secret references are preserved. */
373
+ declare function mergeEnv(...maps: (EnvMap | undefined)[]): EnvMap;
374
+ /**
375
+ * Render for Docker Compose / Swarm: literals pass through, secrets become
376
+ * `${SOURCE}` interpolation references that Docker resolves at runtime from the
377
+ * process environment. The secret value is never written into the file.
378
+ */
379
+ declare function renderComposeEnv(env: EnvMap): Record<string, string>;
380
+ /** Distinct host env var names referenced by secrets across the given maps. */
381
+ declare function requiredSecretVars(...maps: (EnvMap | undefined)[]): string[];
382
+
383
+ /** Run a list of hook commands sequentially, relative to rootDir. */
384
+ declare function runHooks(commands: HookCommand[] | undefined, opts: {
385
+ rootDir: string;
386
+ dryRun?: boolean;
387
+ executor?: Executor;
388
+ }): Promise<void>;
389
+
390
+ /** Lowercase, replace illegal chars; safe for compose projects + swarm stacks. */
391
+ declare function sanitize(name: string): string;
392
+ /** RFC 1123 label, used for kubernetes namespaces and resource names. */
393
+ declare function k8sName(name: string): string;
394
+ /** "project_env" stack/project identifier. */
395
+ declare function stackName(project: string, env: string): string;
396
+
397
+ export { type AppliedAction, BUNDLE_MANIFEST, type Backend, type BackendAction, type BackendContext, BackendName, type BundleEnvironment, type BundleManifest, CatalogConfig, type CatalogManifest, type CatalogResolver, type CatalogSource, Dependable, type DeployOptions, type DeploymentPlan, type DeploymentRecord, EnvMap, EnvValue, EnvironmentDefinition, type EnvironmentPlan, type Executor, HookCommand, Hooks, KaupangConfig, type Ledger, type LoadedConfig, type MaterializedEnvironment, type NormalizedEnvironment, PullPolicy, type ResolveResult, type ResolvedEnvironment, type ResolvedImage, type ResolvedSolution, type RunOptions, SecretRef, ServiceDefinition, ServiceSpec, SolutionRecipe, type TargetRuntime, appendDeployment, applyPins, applyTarget, backendNames, createCatalogResolver, defaultExecutor, deployPlan, findConfig, getBackend, hasBinary, history, isOciRef, isPinned, isSecret, k8sName, latestSuccessful, loadConfig, makeContext, mergeEnv, newDeploymentId, normalizeEnvironment, parseDuration, pullBundle, pushBundle, readBundle, readLedger, renderComposeEnv, renderPlan, requiredSecretVars, resolveDigest, resolveEnvironmentImages, resolveImage, resolveMultiPlan, resolvePlan, resolveSolution, resolveTarget, rewriteActionPath, rollbackTarget, run, runHooks, runPipeline, runShell, sanitize, setVerbose, stackName, toArray, topoSort, writeBundle };