@microtica/sdk
v0.2.5
Published
Microtica SDK — typed client for the Microtica API
Downloads
54
Maintainers
Readme
@microtica/sdk
A typed Node.js client for the Microtica API. It is the shared implementation
behind @microtica/cli and exposes focused resource groups for projects,
environments, apps, Git integrations, pipelines, components, identity, and
normalized log streams.
Requirements and installation
- Node.js 18 or newer
- TypeScript is optional; declaration files ship with the package
- A token generated from the Microtica Console
npm install @microtica/sdkThe package currently emits CommonJS. Both TypeScript imports and Node.js
require are supported by normal CommonJS-compatible toolchains:
import { Microtica } from "@microtica/sdk";const { Microtica } = require("@microtica/sdk");Create a client
import { Microtica } from "@microtica/sdk";
const microtica = new Microtica({
token: process.env.MICROTICA_TOKEN!,
// Per-request HTTP timeout; defaults to 60 seconds. Use 0 to disable.
requestTimeoutMs: 60_000,
});Generate the token in the Microtica Console and provide it through a secret manager or environment variable. Unknown token formats are rejected before an API request is made.
API groups
The Microtica facade creates one shared authenticated client and exposes these
groups:
| Group | Main methods |
| --- | --- |
| projects | list, get |
| envs | list, get, getDetails, getResource, clone, deploy, waitForDeploy, lastDeploy, updateResourceConfig, addResource, removeResource, undeploy, delete, deploymentLogs |
| apps | listInEnv, listInProject, get, getStatus, getDeploymentStatus, findDeployments, lastDeploy, declare, updateConfig, deployApp, getScaling, updateScaling, rawPodLogs, logs |
| git | listAccounts, getAccount, listRepositories, listBranches |
| pipelines | list, get, create, update, updateSpec, trigger, delete, history, listBuilds, getBuild, buildLogs |
| components | list, get, getSchema, create, delete |
| whoami | identity, verify |
| client | Authenticated low-level generated service clients for advanced use. |
Upstream API responses are open schemas. New properties can appear and optional properties can be missing; select the fields your application needs.
Projects and identity
const identity = microtica.whoami.identity(); // Local credential inspection.
const connectivity = await microtica.whoami.verify(); // API round trip.
const projects = await microtica.projects.list();
const project = await microtica.projects.get(projects[0].id!);Local identity exposes only safe metadata about the stored token. verify()
performs the API round trip used to confirm connectivity and project access.
Environments and resources
Use getDetails when resource configuration is required. get is intentionally
a lighter top-level environment view.
const envs = await microtica.envs.list(projectId);
const env = await microtica.envs.get(envId, projectId);
const details = await microtica.envs.getDetails(envId, projectId);
const rds = await microtica.envs.getResource(envId, projectId, "RDS");Update resource configuration
The upstream resource update replaces all configuration. The SDK protects callers by merging with current configuration by default:
await microtica.envs.updateResourceConfig(
envId,
projectId,
"Web",
{
componentVersion: "latest",
configurations: {
env: "staging",
InternalListenerArn: {
value: "SharedIngress.InternalListenerArn",
reference: true,
},
},
},
{ merge: true }, // default
);Both configuration forms are accepted:
const arrayForm = [
{ key: "env", value: "staging" },
{ key: "password", value: process.env.APP_PASSWORD!, sensitive: true },
];
const mapForm = {
env: "staging",
password: { value: process.env.APP_PASSWORD!, sensitive: true },
};Set { merge: false } only to intentionally replace the full set. The Microtica
API drops value: ""; if an explicit blank is required, store one space and trim
it in the infrastructure consumer.
Add a component resource
Configuration schemas are specific to both component and build version. Resolve the schema before creating the resource:
const { componentVersion, schema } = await microtica.components.getSchema(
projectId,
componentId,
"latest",
);
// Validate your values against `schema`, then create the instance.
await microtica.envs.addResource(envId, projectId, {
name: "Cache",
componentId,
componentVersion,
configurations: {
node_type: "cache.t4g.small",
},
});removeResource changes the environment specification; it does not immediately
destroy already provisioned infrastructure. Deploy the environment to reconcile.
Deploy and wait
const queued = await microtica.envs.deploy(envId, projectId);
const abortSignal = AbortSignal.timeout(30 * 60_000);
const finalEnv = await microtica.envs.waitForDeploy(envId, projectId, {
timeoutMs: 30 * 60_000,
pollIntervalMs: 10_000,
abortSignal,
});Partial resource deployments accept a concrete component build ID or resolve the latest successful build automatically:
await microtica.envs.deploy(envId, projectId, {
partialResources: [
{ name: "VPC" },
{ name: "Web", version: "4f3a9c21" },
],
});The SDK refuses empty versions because an empty resource override has deletion semantics in the underlying API. A partial Terraform deploy still plans the whole workspace; only the apply set is restricted.
Clone and clean up
const clone = await microtica.envs.clone(sourceEnvId, projectId, {
name: "Staging",
description: "Staging environment",
cloudProvider: "aws",
infrastructureAsCodeTool: "terraform",
awsAccountId,
awsRegion: "eu-central-1",
});Clone is idempotent by environment name and copies resources, not apps. To remove
an environment safely, call undeploy to destroy managed cloud resources, wait
for teardown, then call delete to remove the Microtica record. The SDK does not
provide the CLI's interactive confirmations; application code owns that safety
decision.
Last deployment of a resource
const last = await microtica.envs.lastDeploy("RDS", projectId, {
envId,
includeRaw: false,
});
if (last) {
console.log(last.deployedAt ?? last.startedAt);
console.log(last.envDeployId, last.envDeployStatus);
console.log(last.targetStatus, last.commitSha);
}Infrastructure resources deploy as targets within environment-level runs. The result deliberately contains both scopes: the run's ID/timestamps/status and the requested target's status/commit. Do not treat the environment status as proof that every target succeeded.
Kubernetes apps
Inspect and locate apps
const inEnv = await microtica.apps.listInEnv(envId, projectId);
const matches = await microtica.apps.findDeployments("api", projectId, {
env: envId,
});
if (matches.length !== 1) {
throw new Error("Select a cluster and namespace explicitly");
}
const locator = {
name: "api",
clusterId: matches[0].clusterId,
namespace: matches[0].namespace,
projectId,
};
const status = await microtica.apps.getStatus(locator);Deploy without losing configuration
deployApp supports two explicit configuration modes:
replaceis the SDK default and sends the supplied configuration set exactly.mergereads live configuration, safely recovers schema-defined application values when needed, overwrites supplied keys, and preserves all others.
Use merge mode for image-only deploys or partial configuration updates:
await microtica.apps.deployApp({
locator,
configurationMode: "merge",
request: {
deployment: {
image: "6ff3a2348d6265e17ab07324155e95f1ad1c729a",
},
},
});Use replace mode only with a complete configuration source of truth:
await microtica.apps.deployApp({
locator,
configurationMode: "replace",
request: {
deployment: {
image: imageTag,
configurations: [
{ key: "DOMAIN_NAME", value: "api.example.com" },
{ key: "DB_PASSWORD", value: password, sensitive: true },
],
},
},
});Sensitive values returned from live state can be secretName:KEY references.
They are safe to round-trip only when sensitive: true remains set. declare
and updateConfig update stored configuration without applying to Kubernetes;
sensitive values must be supplied again when the app is actually deployed.
Scaling
const current = await microtica.apps.getScaling(locator);
const change = await microtica.apps.updateScaling(
locator,
{
cpu: 1000, // millicores
maxCpu: 1000, // millicores
memory: 1024, // MiB
maxMemory: 2048, // MiB
minReplicas: 2,
maxReplicas: 6,
},
{ envId },
);
console.log(change.previous, change.current);The method merges with live state, preserves sensitive configuration and the container port, resolves the deployed image tag, validates CPU and replica bounds, and deploys the result. Resource changes roll pods; HPA-only changes reconcile without a pod rollout.
Last app deployment
const last = await microtica.apps.lastDeploy("api", projectId, { envId });
if (last) console.log(last.deployedAt, last.commitSha, last.initiator);Apps have independent Kubernetes deployment timelines. Use apps.lastDeploy
for apps and envs.lastDeploy for infrastructure components.
Pipelines, Git, and components
Discover Git inputs and create a pipeline:
const accounts = await microtica.git.listAccounts(projectId);
const repos = await microtica.git.listRepositories(projectId, accounts[0].gitAccountId!);
const branches = await microtica.git.listBranches(
projectId,
accounts[0].gitAccountId!,
repos[0].url!,
);
const created = await microtica.pipelines.create(projectId, {
name: "infrastructure",
repositoryUrl: repos[0].url,
gitAccountId: accounts[0].gitAccountId,
workDir: "./.microtica",
automatedTrigger: true,
branchFilter: "^(main|develop)$",
isPublic: "false",
});
await microtica.pipelines.trigger(projectId, created.pipelineId!, {
ref: "refs/heads/main",
environmentVariableOverrides: [
{ key: "TARGET_ENV", value: "staging", sensitive: false },
],
});Pipelines.trigger forwards the ref it receives; normalize plain branch names
to refs/heads/<name> in your application if necessary.
For project-wide build/deploy questions, use combined history:
const history = await microtica.pipelines.history(projectId, {
envIds: [envId],
types: ["deploy"],
from: Date.now() - 24 * 60 * 60_000,
limit: 100,
});pipelines.list and listBuilds remove large embedded specs and normalize
timestamps by default. Set { full: true } when those artifacts are required,
or fetch one pipeline/build with get/getBuild.
Components reference an existing pipeline and its artifact-producing step. A component becomes deployable after that pipeline has a successful build:
import type { CreateComponentRequest } from "@microtica/sdk";
const request: CreateComponentRequest = {
name: "network",
description: "Reusable VPC",
pipelineId,
artifactStep: "build",
type: "vpc" as CreateComponentRequest["type"],
infrastructureAsCodeTool:
"terraform" as CreateComponentRequest["infrastructureAsCodeTool"],
cloudProvider: "aws" as CreateComponentRequest["cloudProvider"],
};
const component = await microtica.components.create(projectId, request);Normalized log streams
Build, deployment, and app log methods return AsyncIterable<LogEntry> objects.
Consume the stream, then call result() for the producer's final status:
const stream = microtica.pipelines.buildLogs(
projectId,
pipelineId,
buildId,
{
follow: true,
stitch: true,
abortSignal: AbortSignal.timeout(30 * 60_000),
},
);
for await (const entry of stream) {
console.log(entry.timestamp, entry.severity, entry.source, entry.message);
}
const result = await stream.result();
console.log(result.normalized, result.statusRaw, result.note);Other producers follow the same pattern:
const deployLogs = microtica.envs.deploymentLogs(
projectId,
envId,
deploymentId,
{ follow: true, abortSignal: AbortSignal.timeout(30 * 60_000) },
);
const appLogs = microtica.apps.logs(projectId, "api", {
env: envId,
abortSignal: AbortSignal.timeout(60_000),
});Deployment logs auto-route between CloudFormation events and Terraform realtime
logs based on the environment. Build logs can stitch deploy-step events into the
pipeline stream. App logs are snapshot-only in this release; follow: true
fails validation.
The package exports the normalized log types and guards:
import type {
LogEntry,
LogSource,
NormalizedStatus,
Severity,
} from "@microtica/sdk";
import {
isLogEntry,
isEndMarker,
normalizeStatus,
} from "@microtica/sdk";Errors, cancellation, and safety
Generated service errors generally retain the Axios error shape. A practical
handler should inspect error.response?.status and error.response?.data while
preserving the original error:
try {
await microtica.envs.get(envId, projectId);
} catch (error: any) {
if (error.response) {
console.error(error.response.status, error.response.data);
}
throw error;
}Long-running polling and streaming methods accept AbortSignal. Use it together
with an application-level timeout:
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 10 * 60_000);
try {
await microtica.envs.waitForDeploy(envId, projectId, {
abortSignal: controller.signal,
});
} finally {
clearTimeout(timer);
}Important state-change rules:
envs.updateResourceConfigmerges by default;merge: falsereplaces.apps.deployAppdefaults to replace; chooseconfigurationMode: "merge"for image-only or partial-config deployment.envs.removeResourceedits the spec; it does not itself destroy cloud state.envs.deleteremoves the Microtica record and can orphan cloud resources ifundeployhas not completed.- The SDK has no interactive confirmation layer. Add confirmations, policy, or approvals in the calling application.
Low-level access and exports
microtica.client exposes authenticated generated service clients for advanced
operations not yet wrapped by a resource group:
microtica.client.project;
microtica.client.engine;
microtica.client.kube;
microtica.client.elasticsearch;
microtica.client.ap;
microtica.client.user;These clients are less stable and expose upstream service vocabulary (for example, environments are called stages). Prefer the high-level groups whenever possible.
The package also exports:
MicroticaClient,MicroticaClientOptions,DEFAULT_BASE_URLAPI_KEY_HEADER,detectCredentialKind, andCredentialKind- Resource-group classes and log-stream classes
- App, environment, pipeline, configuration, and normalized-log types
- Selected generated API request/response types such as
CreatePipelineRequest,UpdatePipelineRequest,CreateComponentRequest, andComponentSchema slimPipelineandslimBuildDetailshelpers
Refer to the generated .d.ts files in the installed package for the exact
surface matching your version.
Agent-friendly usage
When an agent writes code against the SDK:
- Read the installed TypeScript declarations instead of assuming a response shape from an older example.
- Treat responses as open schemas and narrow them at the application boundary.
- Prefer curated
lastDeployand combinedhistorymethods over correlating raw build data manually. - Default to lightweight list methods; opt into
fullonly for a specific need. - Preserve configuration metadata (
sensitive,reference) during transforms. - Use abort signals on polling and streaming work.
- Put an explicit approval layer around
undeploy,delete, and full configuration replacement.
For command-driven agents, install @microtica/cli and run
microtica agents <topic> to obtain version-matched command/output guidance.
Development
From the repository root:
npm install
npm run build --workspace @microtica/sdk
npm test --workspace @microtica/sdk
npm run typecheck --workspace @microtica/sdkThe SDK is the behavioral contract used by the CLI. Changes to public methods, configuration semantics, output normalization, or log behavior should include tests and corresponding CLI/agent documentation where applicable.
