@akua-dev/sdk
v0.8.10
Published
TypeScript SDK for akua — render Kubernetes Packages in-process. Helm + Kustomize engines, OCI fetch, cosign verify, JSON Schema export. No `akua` binary required.
Downloads
1,594
Readme
@akua-dev/sdk
TypeScript SDK for akua. Every verb runs in-process via a bundled native addon (napi-rs) — same akua-core the CLI uses, no akua binary on $PATH required.
Install
bun add @akua-dev/sdk
pnpm add @akua-dev/sdk
npm install @akua-dev/sdkNode 22+ / Bun 1.3+. Browser target deferred to v0.2.x (the napi addon is host-side; a wasm32-unknown-unknown bundle is the path forward — see docs/spikes/engines-on-wasm32-unknown-unknown.md).
bun add resolves the right per-platform binary via optionalDependencies on @akua-dev/native-{darwin,linux,win32}-*. The meta package is @akua-dev/native; the SDK depends on it transitively.
Usage
import { Akua, AkuaUserError, AkuaRateLimitedError } from '@akua-dev/sdk';
const akua = new Akua();
const yaml = await akua.renderSource('package.k', PACKAGE_K_SOURCE, { replicas: 3 });
const lint = await akua.lint({ package: './package.k' });
const tree = await akua.tree({ workspace: '.' });
const summary = await akua.render({ package: './package.k', out: './deploy' });Every method returns a typed result validated against a JSON Schema generated from the same Rust serde types the CLI emits. Contract drift throws at the parse boundary, not as undefined.field later:
try {
await akua.render({ package: './package.k', out: './deploy' });
} catch (err) {
if (err instanceof AkuaRateLimitedError) backoff();
else if (err instanceof AkuaUserError) console.error(err.structured?.code);
else throw err;
}Examples
Runnable recipes in examples/:
bun run packages/sdk/examples/01-render-source.ts
bun run packages/sdk/examples/02-lint-package.ts
bun run packages/sdk/examples/06-diff-renders.tsTypes + schema are derived, not hand-written
src/types/*.ts— per-type TS fromts-rsderives on Rust serde types inakua-core+akua-cli.src/schemas/akua.json— a single bundled JSON Schema fromschemars. Polyglot consumers (Python, Go, agents) validate against the same shape.
Drift is guarded by task sdk:check — regenerate + git diff --exit-code.
Repo tasks
task sdk:gen # regenerate types + schema from Rust
task sdk:check # regenerate + diff-check (wired into `task ci`)
task sdk:build # bun bundle + tsc declarations → packages/sdk/dist/
task sdk:test # bun test (uses the bundled native addon)
task sdk:publish:check # npm pack --dry-runRelease flow
SDK versions track the Rust workspace version: one v<semver> tag drives a single unified release.yml workflow that builds the wasm bundle once, fans out into the native + cli matrices in parallel, then chains npm publishes (engines → per-platform native → meta-native → SDK) via job-level needs: dependencies. No npm polling, no inter-workflow races.
- Land changes on
main;task cimust be green. - Bump versions in
Cargo.toml,crates/akua-napi/package.json,packages/sdk/package.json, allcrates/akua-napi/npm/<platform>/package.json,crates/akua-native-engines-npm/package.json. Commitrelease: vX.Y.Z. - Tag
v<semver>and push. The singlerelease.ymlworkflow handles everything (npm + GitHub Release + Docker + Homebrew). Prerelease tags likev<x.y.z>-rc1publish to the npmnextdist-tag and are marked as prereleases on GitHub.
See .github/workflows/release.yml for the full job graph.
Still coming
- Browser target — bundler-build path requires
helm-engine-wasm/kustomize-engine-wasmto compile towasm32-unknown-unknown(currentlywasm32-wasip1only). See docs/spikes/engines-on-wasm32-unknown-unknown.md. - Engine
.wasmdeduplicated across platform packages via a single@akua-dev/native-enginespackage — currently each per-platform addon embeds its own copy.
