### Interact with Project Models
Source: https://github.com/mittwald/api-client-js/blob/master/packages/models/README.md
Examples demonstrating how to get, create, update, and query project models, including using references and accessing server details.
```typescript
// Get a detailed project
const detailedProject = await Project.get("p-vka9t3");
// Create a project reference
const projectRef = Project.ofId("p-vka9t3");
// Get the detailed project from the reference
const anotherDetailedProject = await projectRef.getDetailed();
// Update project description
await detailedProject.updateDescription("My new description!");
// This method just needs the ID and a description and
// thus is also available on the reference
await projectRef.updateDescription("My new description!");
// Accessing the projects server reference
const server = project.server;
// List all projects of this server
const serversProjects = await server.projects.execute();
// List all projects
const allProjects = await Project.query().execute();
// Iterate over project List Models
for (const project of serversProjects) {
await project.leave();
}
```
--------------------------------
### Install Dependencies and Compile Project
Source: https://github.com/mittwald/api-client-js/blob/master/CONTRIBUTING.md
Run these commands to install project dependencies and compile the project locally.
```shell
$ yarn install
$ yarn compile
```
--------------------------------
### Set Path Parameters for Project Get
Source: https://github.com/mittwald/api-client-js/blob/master/packages/mittwald/README.md
Example of setting the 'projectId' path parameter when fetching a specific project.
```javascript
// Setting the projectId path parameters
const project = await mittwaldApi.project.getProject({
projectId: "p-xxxxx",
});
```
--------------------------------
### Install API Client with Yarn
Source: https://github.com/mittwald/api-client-js/blob/master/packages/mittwald/README.md
Install the @mittwald/api-client package using Yarn.
```shell
yarn add @mittwald/api-client
```
--------------------------------
### Install React Use Promise Package
Source: https://github.com/mittwald/api-client-js/blob/master/packages/mittwald/README.md
Install the additional @mittwald/react-use-promise package required for the React client.
```shell
yarn add @mittwald/react-use-promise
```
--------------------------------
### Setup API Client with API Token
Source: https://github.com/mittwald/api-client-js/blob/master/packages/models/README.md
Initialize the API client using an API token from environment variables.
```typescript
import { api } from "@mittwald/api-models";
api.setupWithApiToken(process.env.MW_API_TOKEN);
```
--------------------------------
### Example of Server Model with Projects Query
Source: https://github.com/mittwald/api-client-js/blob/master/packages/models/README.md
Demonstrates how a Server model can expose a ProjectsListQuery property, allowing for efficient querying of associated projects.
```typescript
class Server {
public readonly projects: ProjectsListQuery;
public constructor(id: string) {
this.projects = new ProjectListQuery({
server: this,
});
}
}
```
--------------------------------
### Interact with API Domains and Operations
Source: https://context7.com/mittwald/api-client-js/llms.txt
Demonstrates making API calls to different domains (e.g., project, app, database) using typed request objects. Supports path parameters, query parameters, and data payloads. Includes examples for creating, getting, and listing resources, with status assertions.
```typescript
import { MittwaldAPIV2Client, assertStatus, assertOneOfStatus } from "@mittwald/api-client";
const client = MittwaldAPIV2Client.newWithToken(process.env.MITTWALD_API_TOKEN!);
// Create a MySQL database
const createResp = await client.database.createMysqlDatabase({
pathParameters: { projectId: "abc123" },
data: {
database: { name: "my_db", characterSettings: { characterSet: "utf8mb4", collate: "utf8mb4_unicode_ci" } },
user: { name: "my_user", password: "Str0ng!Pass", accessLevel: "full", externalAccess: false },
},
});
assertStatus(createResp, 201);
const dbId = createResp.data.id;
// Get the database, tolerating both found and not-found
const getResp = await client.database.getMysqlDatabase({
pathParameters: { mysqlDatabaseId: dbId },
});
assertOneOfStatus(getResp, [200, 404]);
if (getResp.status === 200) {
console.log("DB name:", getResp.data.name);
} else {
console.log("Database not found");
}
// List all MySQL databases for a project with pagination
const listResp = await client.database.listMysqlDatabases({
pathParameters: { projectId: "abc123" },
queryParameters: { limit: 25, skip: 0 },
});
assertStatus(listResp, 200);
```
--------------------------------
### Install API Models Package
Source: https://github.com/mittwald/api-client-js/blob/master/packages/models/README.md
Install the @mittwald/api-models package using yarn.
```shell
yarn add @mittwald/api-models
```
--------------------------------
### Migrate Project Get Request from V2 to V3
Source: https://github.com/mittwald/api-client-js/blob/master/packages/mittwald/README.md
Compares the V2 and V3 syntax for making a project get request, highlighting the change in how path parameters are handled.
```javascript
// V2
mittwaldApi.project.getProject({
pathParameters: {
projectId: "p-xxxxx",
},
});
// V3
mittwaldApi.project.getProject({
projectId: "p-xxxxx",
});
```
--------------------------------
### Initialize API Client with Token
Source: https://github.com/mittwald/api-client-js/blob/master/packages/mittwald/README.md
Example of creating a MittwaldAPIV2Client instance using an API access token.
```typescript
import { MittwaldAPIV2Client } from "@mittwald/api-client";
const mittwaldApi = MittwaldAPIClient.newWithToken("your-access-token");
const projects = await mittwaldApi.project.listProjects();
```
--------------------------------
### Usage of Async Methods in React
Source: https://github.com/mittwald/api-client-js/blob/master/packages/models/README.md
Examples showing how to use asynchronous methods with the '.use()' property for React components, leveraging AsyncResources.
```typescript
const detailedProject = Project.get.use("p-vka9t3");
// Create a project reference
const projectRef = Project.ofId("p-vka9t3");
// Get the detailed project from the reference
const anotherDetailedProject = projectRef.getDetailed.use();
// Accessing the projects server reference
const server = project.server;
// List all projects of this server
const serversProjects = server.projects.execute.use();
// List all projects
const allProjects = Project.query().execute.use();
```
--------------------------------
### Enable Event Consistency Handling
Source: https://github.com/mittwald/api-client-js/blob/master/packages/commons/README.md
Use `withEventConsistencyHandling` to automatically handle the `etag` response header and set it as the `if-event-reached` request header for GET requests, opting into event consistency.
```typescript
const client = new APIClient({ baseURL });
const authenticatedClient = withEventConsistencyHandling(client);
```
--------------------------------
### withEventConsistencyHandling
Source: https://github.com/mittwald/api-client-js/blob/master/packages/commons/README.md
An interceptor that opts into event consistency handling by automatically managing the `ETag` and `if-event-reached` headers for GET requests.
```APIDOC
## withEventConsistencyHandling(client)
### Description
Enables event consistency handling. For GET requests, this interceptor automatically sets the `ETag` response header as the `if-event-reached` request header.
### Parameters
- **client**: An instance of `APIClient`.
### Returns
An `APIClient` instance configured with the event consistency handling interceptor.
### Example
```ts
const client = new APIClient({ baseURL });
const authenticatedClient = withEventConsistencyHandling(client);
```
```
--------------------------------
### withEventConsistencyHandling(client)
Source: https://context7.com/mittwald/api-client-js/llms.txt
Attaches response and request interceptors to a client instance to handle event consistency. It captures `etag` headers from mutating responses and forwards them as `if-event-reached` on subsequent GET requests.
```APIDOC
## `withEventConsistencyHandling(client)` — Attach consistency interceptor
Attaches two interceptors: a response interceptor that captures `etag` headers from mutating responses, and a request interceptor that forwards the captured value as `if-event-reached` on GET requests. Accepts both client instances and Axios instances.
```typescript
import { withEventConsistencyHandling, withAccessToken } from "@mittwald/api-client-commons";
import { MittwaldAPIV2Client } from "@mittwald/api-client";
const client = withEventConsistencyHandling(
withAccessToken(
MittwaldAPIV2Client.newUnauthenticated(),
process.env.MITTWALD_API_TOKEN,
),
);
// Now any mutation's etag is tracked and forwarded to subsequent GETs
await client.mail.createMailAddress({
pathParameters: { projectId: "abc123" },
data: { address: "info@example.com", forwardAddresses: [] },
});
// This read will automatically include `if-event-reached` header
const mailResp = await client.mail.listMailAddresses({
pathParameters: { projectId: "abc123" },
});
assertStatus(mailResp, 200);
```
```
--------------------------------
### client.withEventConsistencyHandling()
Source: https://context7.com/mittwald/api-client-js/llms.txt
Activates the event-consistency interceptor that tracks mutating-request `etag` response headers and automatically forwards the latest value as `if-event-reached` on subsequent GET requests, ensuring reads reflect the most recent write.
```APIDOC
## client.withEventConsistencyHandling()
### Description
Activates the event-consistency interceptor that tracks mutating-request `etag` response headers and automatically forwards the latest value as `if-event-reached` on subsequent GET requests, ensuring reads reflect the most recent write.
### Usage
```typescript
import { MittwaldAPIV2Client, assertStatus } from "@mittwald/api-client";
const client = MittwaldAPIV2Client.newWithToken(process.env.MITTWALD_API_TOKEN!)
.withEventConsistencyHandling();
// After a mutation, subsequent reads will include the event ID automatically
const patchResp = await client.project.updateProjectDescription({
pathParameters: { projectId: "abc123" },
data: { description: "Updated description" },
});
assertStatus(patchResp, 200);
// This GET will carry if-event-reached from the patch's etag
const getResp = await client.project.getProject({
pathParameters: { projectId: "abc123" },
});
assertStatus(getResp, 200);
console.log("Description is now:", getResp.data.description);
```
```
--------------------------------
### Enable Eventual Consistency Headers with client.withEventConsistencyHandling()
Source: https://context7.com/mittwald/api-client-js/llms.txt
Activates the event-consistency interceptor. It tracks mutating-request `etag` response headers and automatically forwards the latest value as `if-event-reached` on subsequent GET requests, ensuring reads reflect the most recent write.
```typescript
import { MittwaldAPIV2Client, assertStatus } from "@mittwald/api-client";
const client = MittwaldAPIV2Client.newWithToken(process.env.MITTWALD_API_TOKEN!)
.withEventConsistencyHandling();
// After a mutation, subsequent reads will include the event ID automatically
const patchResp = await client.project.updateProjectDescription({
pathParameters: { projectId: "abc123" },
data: { description: "Updated description" },
});
assertStatus(patchResp, 200);
// This GET will carry if-event-reached from the patch's etag
const getResp = await client.project.getProject({
pathParameters: { projectId: "abc123" },
});
assertStatus(getResp, 200);
console.log("Description is now:", getResp.data.description);
```
--------------------------------
### Generate TypeScript API Client from OpenAPI Spec (CLI)
Source: https://context7.com/mittwald/api-client-js/llms.txt
The primary CLI command to generate typed TypeScript files from an OpenAPI spec. Install the generator globally or as a dev dependency, then use 'acg generate' with input and output paths.
```shell
# Install the generator
npm install -D @mittwald/api-code-generator
# Validate the spec first
acg validate spec/openapi.json
# Generate the client
acg generate \
--name MyAPIV2 \
--optionalHeader x-access-token \
spec/openapi.json \
src/generated
# Generated output:
# src/generated/descriptors.ts – operation metadata
# src/generated/types.ts – request/response TypeScript types
# src/generated/client.ts – Axios-based typed client class
# src/generated/client-react.ts – React suspense resource wrappers
```
--------------------------------
### Attach Event Consistency Interceptor to API Client
Source: https://context7.com/mittwald/api-client-js/llms.txt
Attaches response and request interceptors to track etags from mutating responses and forward them as 'if-event-reached' on subsequent GET requests. Accepts both client and Axios instances.
```typescript
import { withEventConsistencyHandling, withAccessToken } from "@mittwald/api-client-commons";
import { MittwaldAPIV2Client } from "@mittwald/api-client";
const client = withEventConsistencyHandling(
withAccessToken(
MittwaldAPIV2Client.newUnauthenticated(),
process.env.MITTWALD_API_TOKEN,
),
);
// Now any mutation's etag is tracked and forwarded to subsequent GETs
await client.mail.createMailAddress({
pathParameters: { projectId: "abc123" },
data: { address: "info@example.com", forwardAddresses: [] },
});
// This read will automatically include `if-event-reached` header
const mailResp = await client.mail.listMailAddresses({
pathParameters: { projectId: "abc123" },
});
assertStatus(mailResp, 200);
```
--------------------------------
### api.setupWithApiToken(token)
Source: https://context7.com/mittwald/api-client-js/llms.txt
Initializes the domain model layer by wiring high-level domain models to the live API. This method must be called once at application startup before using any model class.
```APIDOC
## `api.setupWithApiToken(token)` — Initialize domain model layer
Wires the high-level domain models to the live API by creating an authenticated client and injecting all behavior implementations. Must be called once at app startup before using any model class.
```typescript
import { api, Project, Customer, Server } from "@mittwald/api-models";
// Initialize once at startup
api.setupWithApiToken(process.env.MITTWALD_API_TOKEN!);
// Now all model classes work against the live API
const projects = await Project.list();
console.log("Projects:", projects.map((p) => p.data.description));
const customer = await Customer.get("cst-abc123");
console.log("Customer:", customer.data.name);
// Access nested relations
const customerProjects = await customer.projects.execute();
console.log("Customer's projects:", customerProjects.items.map((p) => p.data.description));
```
```
--------------------------------
### Initialize and Use React API Client
Source: https://github.com/mittwald/api-client-js/blob/master/packages/mittwald/README.md
Demonstrates how to initialize the React API client from a base client and use it to fetch and display a list of projects. Handles potential API errors by throwing an ApiClientError.
```javascript jsx
import { MittwaldAPIV2Client } from "@mittwald/api-client";
import { MittwaldAPIV2ClientReact } from "@mittwald/api-client/react";
const api = MittwaldAPIV2Client.newUnauthenticated();
const apiReact = MittwaldAPIV2ClientReact.fromBaseClient(api);
const ProjectsList = () => {
// apiReact.project.listProjects() returns an AsyncResource that can be "used"
const projects = apiReact.project.listProjects().use({
autoRefresh: {
seconds: 30,
},
});
return (
{projects.map((p) => (
- {p.description}
))}
);
};
```
--------------------------------
### Run Test Suite
Source: https://github.com/mittwald/api-client-js/blob/master/CONTRIBUTING.md
Execute this command to run the project's test suite.
```shell
$ yarn test
```
--------------------------------
### Configure Request Parameters
Source: https://github.com/mittwald/api-client-js/blob/master/packages/mittwald/README.md
Demonstrates setting path parameters, headers, query parameters, and request body for an API operation.
```javascript
const response = await mittwaldApi.category.operation({
// path parameters
pathParameter1: "param1",
pathParameter2: "param2",
// parameters in header
headers: {
"x-header": "header",
},
// query parameters
queryParameters: {
queryParameter1: "queryParam1",
queryParameter2: "queryParam2",
},
// JSON object in request body
data: {
data1: "data1",
data2: "data2",
},
});
```
--------------------------------
### Create React Client Instance
Source: https://github.com/mittwald/api-client-js/blob/master/packages/mittwald/README.md
Instantiate a React-aligned API client from a base client instance.
```javascript
const api = MittwaldAPIV2Client.newUnauthenticated();
const apiReact = MittwaldAPIV2ClientReact.fromBaseClient(api);
```
--------------------------------
### Project Model
Source: https://context7.com/mittwald/api-client-js/llms.txt
Represents a Mittwald project, providing static finder methods, mutation methods, and typed relational accessors. All async methods are wrapped with `provideReact` and can be called as plain async functions or used as React hooks.
```APIDOC
## `Project` model — Domain object for mittwald projects
Provides static finder methods, mutation methods, and typed relational accessors. All async methods are wrapped with `provideReact` and can be called as plain async functions or used as React hooks.
```typescript
import { api, Project } from "@mittwald/api-models";
api.setupWithApiToken(process.env.MITTWALD_API_TOKEN!);
// Find by ID (returns undefined if not found)
const project = await Project.find("p-abc123");
if (!project) {
console.log("Project not found");
process.exit(1);
}
console.log("Description:", project.data.description);
console.log("Customer ID:", project.customer.id);
// Update description
await project.updateDescription("New description");
// List ingresses for the project
const ingressList = await project.ingresses.execute();
console.log("Ingresses:", ingressList.items.map((i) => i.data.hostname));
// Create a new project on a server
const newProject = await Project.create("srv-xyz789", "My New Project");
console.log("Created project ID:", newProject.id);
// In React: suspending component
function MyComponent({ projectId }: { projectId: string }) {
// .use() suspends until data is available
const project = Project.get.use(projectId);
return {project.data.description}
;
}
```
```
--------------------------------
### Generate API Client with CLI
Source: https://github.com/mittwald/api-client-js/blob/master/packages/generator/README.md
Use the `acg generate` command to build your API client. Specify the client name, input OpenAPI spec, output directory, and optional headers.
```shell
acg generate --name MittwaldAPIV2 spec/openapi.json src/generated --optionalHeader x-access-token
```
--------------------------------
### MittwaldAPIClient.newWithCredentials(email, password)
Source: https://context7.com/mittwald/api-client-js/llms.txt
Authenticates with email and password, then returns a fully authenticated client. It throws an ApiClientError if login fails.
```APIDOC
## MittwaldAPIClient.newWithCredentials(email, password) — Authenticate with email + password
Performs a login request, extracts the session token, and returns a fully authenticated client. Throws `ApiClientError` if login fails.
```typescript
import { MittwaldAPIV2Client } from "@mittwald/api-client";
const client = await MittwaldAPIV2Client.newWithCredentials(
"user@example.com",
"s3cr3tP@ss",
);
const response = await client.user.getOwnAccount();
assertStatus(response, 200);
console.log("Logged in as:", response.data.email);
```
```
--------------------------------
### Initialize API Client with Token
Source: https://context7.com/mittwald/api-client-js/llms.txt
Initialize the domain model layer with an API token. This must be called once at application startup before using any model class.
```typescript
import { api, Project, Customer, Server } from "@mittwald/api-models";
// Initialize once at startup
api.setupWithApiToken(process.env.MITTWALD_API_TOKEN!);
```
```typescript
// Now all model classes work against the live API
const projects = await Project.list();
console.log("Projects:", projects.map((p) => p.data.description));
const customer = await Customer.get("cst-abc123");
console.log("Customer:", customer.data.name);
// Access nested relations
const customerProjects = await customer.projects.execute();
console.log("Customer's projects:", customerProjects.items.map((p) => p.data.description));
```
--------------------------------
### Project Model Operations
Source: https://context7.com/mittwald/api-client-js/llms.txt
Demonstrates static finder, mutation, and relational accessors for the Project model. Async methods can be used as plain async functions or React hooks.
```typescript
import { api, Project } from "@mittwald/api-models";
api.setupWithApiToken(process.env.MITTWALD_API_TOKEN!);
```
```typescript
// Find by ID (returns undefined if not found)
const project = await Project.find("p-abc123");
if (!project) {
console.log("Project not found");
process.exit(1);
}
console.log("Description:", project.data.description);
console.log("Customer ID:", project.customer.id);
```
```typescript
// Update description
await project.updateDescription("New description");
```
```typescript
// List ingresses for the project
const ingressList = await project.ingresses.execute();
console.log("Ingresses:", ingressList.items.map((i) => i.data.hostname));
```
```typescript
// Create a new project on a server
const newProject = await Project.create("srv-xyz789", "My New Project");
console.log("Created project ID:", newProject.id);
```
```typescript
// In React: suspending component
function MyComponent({ projectId }: { projectId: string }) {
// .use() suspends until data is available
const project = Project.get.use(projectId);
return {project.data.description}
;
}
```
--------------------------------
### Implement API Interaction via Behaviors
Source: https://github.com/mittwald/api-client-js/blob/master/packages/models/README.md
Shows the recommended approach where API interactions are delegated to behaviors, promoting loose coupling and testability.
```typescript
class ProjectDetailed {
public static async find(id: string): Promise {
const data = await config.project.behaviors.find(id);
if (data !== undefined) {
return new Project(data.id, data);
}
}
}
```
--------------------------------
### Import API Client
Source: https://github.com/mittwald/api-client-js/blob/master/packages/mittwald/README.md
Import the MittwaldAPIV2Client from the @mittwald/api-client package.
```typescript
import { MittwaldAPIV2Client } from "@mittwald/api-client";
```
--------------------------------
### MittwaldAPIClient.newUnauthenticated()
Source: https://context7.com/mittwald/api-client-js/llms.txt
Creates a client without any authentication, suitable for accessing public endpoints.
```APIDOC
## MittwaldAPIClient.newUnauthenticated() — Unauthenticated client
Creates a client without authentication. Useful for public endpoints (e.g., listing available software versions).
```typescript
import { MittwaldAPIV2Client } from "@mittwald/api-client";
const client = MittwaldAPIV2Client.newUnauthenticated();
const response = await client.app.listApps({});
assertStatus(response, 200);
console.log("Available apps:", response.data.map((a) => a.name));
```
```
--------------------------------
### React Suspense Client for API Operations
Source: https://context7.com/mittwald/api-client-js/llms.txt
Demonstrates using the auto-generated React client to wrap API operations as suspense-compatible resources. Use `.use()` within a React component wrapped in ``.
```typescript
import { MittwaldAPIClientReact } from "@mittwald/api-client/react";
import { MittwaldAPIV2Client } from "@mittwald/api-client";
import React, { Suspense } from "react";
const baseClient = MittwaldAPIV2Client.newWithToken(process.env.MITTWALD_API_TOKEN!);
const reactClient = new MittwaldAPIClientReact(baseClient);
```
```typescript
function ProjectDetail({ projectId }: { projectId: string }) {
// Suspends until the API responds; throws on error
const project = reactClient.project.getProject
.use({ pathParameters: { projectId } });
return (
{project.data.description}
Customer: {project.data.customerId}
);
}
```
```typescript
function App() {
return (
Loading…}>
);
}
```
--------------------------------
### Implement API Behavior
Source: https://github.com/mittwald/api-client-js/blob/master/packages/models/README.md
Provides a concrete implementation for the API behavior, handling the actual API request and response processing.
```typescript
import { ProjectBehaviors } from "./types.js";
import { assertStatus, MittwaldAPIV2Client } from "@mittwald/api-client";
export const apiProjectBehaviors = (
client: MittwaldAPIV2Client,
): ProjectBehaviors => ({
find: async (id) => {
const response = await client.project.getProject({
projectId: id,
});
if (response.status === 200) {
return response.data;
}
assertStatus(response, 403);
},
});
```
--------------------------------
### Customer Model Operations
Source: https://context7.com/mittwald/api-client-js/llms.txt
Illustrates customer-specific operations including listing, detail retrieval, and updates. Also shows traversal to related servers and projects.
```typescript
import { api, Customer } from "@mittwald/api-models";
api.setupWithApiToken(process.env.MITTWALD_API_TOKEN!);
```
```typescript
// List all customers with default pagination
const query = Customer.query({ limit: 20 });
const list = await query.execute();
console.log(`Showing ${list.items.length} of ${list.totalCount} customers`);
for (const item of list.items) {
console.log(item.id, item.data.name);
}
```
```typescript
// Get a single customer (throws ObjectNotFoundError if missing)
const customer = await Customer.get("cst-abc123");
await customer.update({ name: "Updated Name" });
```
```typescript
// Traverse to related resources
const servers = await customer.servers.execute();
console.log("Servers:", servers.items.map((s) => s.id));
const projects = await customer.projects.execute();
console.log("Projects:", projects.items.map((p) => p.data.description));
```
--------------------------------
### Authenticate Client with Email and Password
Source: https://context7.com/mittwald/api-client-js/llms.txt
Performs a login request using email and password, extracts the session token, and returns an authenticated client. Throws ApiClientError on login failure.
```typescript
import { MittwaldAPIV2Client } from "@mittwald/api-client";
const client = await MittwaldAPIV2Client.newWithCredentials(
"user@example.com",
"s3cr3tP@ss",
);
const response = await client.user.getOwnAccount();
assertStatus(response, 200);
console.log("Logged in as:", response.data.email);
```
--------------------------------
### Create Authenticated Client with API Token
Source: https://context7.com/mittwald/api-client-js/llms.txt
Instantiates a MittwaldAPIV2Client with an API token for server-side usage. The token is sent as the 'x-access-token' header. Handles all API scenarios explicitly.
```typescript
import { MittwaldAPIV2Client } from "@mittwald/api-client";
import { assertStatus } from "@mittwald/api-client";
const client = MittwaldAPIV2Client.newWithToken(process.env.MITTWALD_API_TOKEN!);
// List all projects the authenticated user can access
const response = await client.project.listProjects({});
assertStatus(response, 200);
// response.data is typed as the full project list array
console.log(response.data.map((p) => `${p.id}: ${p.description}`));
```
--------------------------------
### MittwaldAPIClient.newWithToken(apiToken)
Source: https://context7.com/mittwald/api-client-js/llms.txt
Creates an authenticated MittwaldAPIClient instance using an API token. This is suitable for server-side applications.
```APIDOC
## MittwaldAPIClient.newWithToken(apiToken) — Create authenticated client
Instantiates a `MittwaldAPIClient` that attaches the given API token as the `x-access-token` header on every request. This is the standard entry point for server-side usage.
```typescript
import { MittwaldAPIV2Client } from "@mittwald/api-client";
import { assertStatus } from "@mittwald/api-client";
const client = MittwaldAPIV2Client.newWithToken(process.env.MITTWALD_API_TOKEN!);
// List all projects the authenticated user can access
const response = await client.project.listProjects({});
assertStatus(response, 200);
// response.data is typed as the full project list array
console.log(response.data.map((p) => `${p.id}: ${p.description}`));
```
```
--------------------------------
### Customer Model
Source: https://context7.com/mittwald/api-client-js/llms.txt
Represents a Mittwald customer, mirroring the `Project` pattern with customer-specific operations. Includes traversal to related servers and projects.
```APIDOC
## `Customer` model — Domain object for mittwald customers
Mirrors the `Project` pattern with customer-specific operations: listing, detail retrieval, and update. Includes traversal to related servers and projects.
```typescript
import { api, Customer } from "@mittwald/api-models";
api.setupWithApiToken(process.env.MITTWALD_API_TOKEN!);
// List all customers with default pagination
const query = Customer.query({ limit: 20 });
const list = await query.execute();
console.log(`Showing ${list.items.length} of ${list.totalCount} customers`);
for (const item of list.items) {
console.log(item.id, item.data.name);
}
// Get a single customer (throws ObjectNotFoundError if missing)
const customer = await Customer.get("cst-abc123");
await customer.update({ name: "Updated Name" });
// Traverse to related resources
const servers = await customer.servers.execute();
console.log("Servers:", servers.items.map((s) => s.id));
const projects = await customer.projects.execute();
console.log("Projects:", projects.items.map((p) => p.data.description));
```
```
--------------------------------
### client..(requestObject)
Source: https://context7.com/mittwald/api-client-js/llms.txt
Provides access to API operations organized by domain (e.g., project, app, database). Each operation takes a typed request object.
```APIDOC
## client..(requestObject) — Domain-organized API calls
Every API domain is a property on the client (e.g., `client.project`, `client.app`, `client.database`). Each operation accepts a typed request object with `pathParameters`, `queryParameters`, `data`, and optional `headers`.
```typescript
import { MittwaldAPIV2Client, assertStatus, assertOneOfStatus } from "@mittwald/api-client";
const client = MittwaldAPIV2Client.newWithToken(process.env.MITTWALD_API_TOKEN!);
// Create a MySQL database
const createResp = await client.database.createMysqlDatabase({
pathParameters: { projectId: "abc123" },
data: {
database: { name: "my_db", characterSettings: { characterSet: "utf8mb4", collate: "utf8mb4_unicode_ci" } },
user: { name: "my_user", password: "Str0ng!Pass", accessLevel: "full", externalAccess: false },
},
});
assertStatus(createResp, 201);
const dbId = createResp.data.id;
// Get the database, tolerating both found and not-found
const getResp = await client.database.getMysqlDatabase({
pathParameters: { mysqlDatabaseId: dbId },
});
assertOneOfStatus(getResp, [200, 404]);
if (getResp.status === 200) {
console.log("DB name:", getResp.data.name);
} else {
console.log("Database not found");
}
// List all MySQL databases for a project with pagination
const listResp = await client.database.listMysqlDatabases({
pathParameters: { projectId: "abc123" },
queryParameters: { limit: 25, skip: 0 },
});
assertStatus(listResp, 200);
```
```
--------------------------------
### Generate TypeScript API Client Programmatically
Source: https://github.com/mittwald/api-client-js/blob/master/packages/generator/README.md
This TypeScript code demonstrates how to use the API client generator programmatically. It loads the OpenAPI spec, parses it, and generates descriptors, types, and the client code.
```typescript
import * as path from "path";
import { UniversalContentLoader } from "@mittwald/api-code-generator/js";
import { UniversalFileLoader } from "@mittwald/api-code-generator/js";
import { OpenApiSpec } from "@mittwald/api-code-generator/js";
import { CodeGenerationModel } from "@mittwald/api-code-generator/js";
import { prepareTypeScriptOutput } from "@mittwald/api-code-generator/js";
import { writeIfChangedAsync } from "@mittwald/api-code-generator/js";
const name = "MittwaldAPIV2";
const inout = `${process.cwd()}/spec/openapi.json`;
const output = `${process.cwd()}/src/generated`;
// Loading OpenAPI spec
const loader = new UniversalContentLoader(new UniversalFileLoader(input));
const openApiDoc = await loader.load();
// Parsing OpenAPI spec
const spec = await OpenApiSpec.parse(openApiDoc, {
skipValidation: flags.skipValidation,
});
// Building transformation model
const model = CodeGenerationModel.fromDoc(name, spec.document);
// Generating descriptors
const descriptorsFileContent = model.paths.compileDescriptors();
await writeIfChangedAsync(
path.join(output, "descriptors.ts"),
await prepareTypeScriptOutput(descriptorsFileContent),
);
// Generating types
const typesFileContent = await model.compileTypes({
rootNamespace: flags.name,
optionalHeaders: ["x-access-token"],
});
await writeIfChangedAsync(
path.join(output, "types.ts"),
await prepareTypeScriptOutput(typesFileContent),
);
// Generating client
const clientFileContent = model.paths.compileClient();
await writeIfChangedAsync(
path.join(output, "client.ts"),
await prepareTypeScriptOutput(clientFileContent),
);
// if needed: Generating React client
const reactClientFileContent = model.paths.compileReactClient();
await writeIfChangedAsync(
path.join(output, "client-react.ts"),
await prepareTypeScriptOutput(reactClientFileContent),
);
```
--------------------------------
### Add Custom HTTP Headers with Axios
Source: https://github.com/mittwald/api-client-js/blob/master/packages/mittwald/README.md
Shows how to add custom HTTP headers to all requests made by the API client by accessing the underlying Axios instance.
```typescript
client.axios.defaults.headers["User-Agent"] = `your-tool/v1.2.3`;
```
--------------------------------
### Use Behaviors in Model
Source: https://github.com/mittwald/api-client-js/blob/master/packages/models/README.md
Illustrates how a model class utilizes the defined behaviors to perform its operations, such as finding data.
```typescript
import { config } from "../../config/config.js";
class ProjectDetailed {
public static async find(id: string): Promise {
const data = await config.project.behaviors.find(id);
if (data !== undefined) {
return new Project(data.id, data);
}
}
}
```
--------------------------------
### Reference API Request and Response Types with TypeScript
Source: https://github.com/mittwald/api-client-js/blob/master/packages/mittwald/README.md
Illustrates how to import and reference specific request and response types from the MittwaldAPIV2 namespace for use in TypeScript projects.
```typescript
import { MittwaldAPIV2 } from "@mittwald/api-client";
type ProjectData = MittwaldAPIV2.Operations.ProjectGetProject.ResponseData;
// Reference "non-200" response type
type ProjectNotFoundData =
MittwaldAPIV2.Operations.ProjectGetProject.ResponseData<404>;
type CreateProjectData =
MittwaldAPIV2.Operations.ProjectCreateProject.RequestData;
```
--------------------------------
### Provide React Compatibility for Async Methods
Source: https://github.com/mittwald/api-client-js/blob/master/packages/models/README.md
Enhances asynchronous model methods with a `use`-method property for seamless integration with React using `@mittwald/react-use-promise`.
```typescript
class ProjectDetailed {
public static find = provideReact(
async (id: string): Promise => {
const data = await config.behaviors.project.find(id);
if (data !== undefined) {
return new ProjectDetailed(data);
}
},
);
}
```
--------------------------------
### Add Access Token to API Client
Source: https://github.com/mittwald/api-client-js/blob/master/packages/commons/README.md
Use `withToken` to automatically add the user's access token as a request header for all API requests.
```typescript
const client = new APIClient({ baseURL });
const authenticatedClient = withToken(client, token);
```
--------------------------------
### MittwaldAPIV2ClientReact
Source: https://context7.com/mittwald/api-client-js/llms.txt
The auto-generated React client wraps every readable API operation as a suspense-compatible resource. Each method returns a value that can be consumed with `.use()` inside a React component wrapped in ``.
```APIDOC
## `MittwaldAPIV2ClientReact` — React suspense client (generated)
The auto-generated React client wraps every readable API operation as a suspense-compatible resource. Each method returns a value that can be consumed with `.use()` inside a React component wrapped in ``.
```typescript
import { MittwaldAPIClientReact } from "@mittwald/api-client/react";
import { MittwaldAPIV2Client } from "@mittwald/api-client";
import React, { Suspense } from "react";
const baseClient = MittwaldAPIV2Client.newWithToken(process.env.MITTWALD_API_TOKEN!);
const reactClient = new MittwaldAPIClientReact(baseClient);
function ProjectDetail({ projectId }: { projectId: string }) {
// Suspends until the API responds; throws on error
const project = reactClient.project.getProject
.use({ pathParameters: { projectId } });
return (
{project.data.description}
Customer: {project.data.customerId}
);
}
function App() {
return (
Loading…}>
);
}
```
```
--------------------------------
### withAccessToken(client, token, headerName)
Source: https://context7.com/mittwald/api-client-js/llms.txt
Adds an Axios request interceptor that injects `x-access-token` header on every request where the header is not already present. Works with both `ApiClientBase` subclasses and raw `AxiosInstance` objects.
```APIDOC
## withAccessToken(client, token, headerName)
### Description
Adds an Axios request interceptor that injects `x-access-token` header on every request where the header is not already present. Works with both `ApiClientBase` subclasses and raw `AxiosInstance` objects.
### Usage
```typescript
import axios from "axios";
import { withAccessToken } from "@mittwald/api-client-commons";
import { MittwaldAPIV2Client } from "@mittwald/api-client";
// Usage with the high-level client
const client = MittwaldAPIV2Client.newUnauthenticated();
withAccessToken(client, "my-api-token-here");
// Usage with a raw axios instance
const axiosInstance = axios.create({ baseURL: "https://api.mittwald.de/" });
withAccessToken(axiosInstance, "my-api-token-here");
// Custom header name (for non-standard APIs)
withAccessToken(client, "my-token", "Authorization");
```
```
--------------------------------
### Programmatic Generation with `CodeGenerationModel`
Source: https://context7.com/mittwald/api-client-js/llms.txt
Allows for programmatic generation of API clients using TypeScript. This is useful for custom build scripts, CI pipelines, or advanced code generation workflows.
```APIDOC
### `CodeGenerationModel` + programmatic generation — TypeScript API
Generates a client programmatically — useful for build scripts, CI pipelines, or custom code generation workflows.
```typescript
import * as path from "path";
import {
UniversalContentLoader,
UniversalFileLoader,
OpenApiSpec,
CodeGenerationModel,
prepareTypeScriptOutput,
writeIfChangedAsync,
} from "@mittwald/api-code-generator/js";
const name = "MyAPIV2";
const input = path.resolve("spec/openapi.json");
const output = path.resolve("src/generated");
// Load and parse the OpenAPI spec
const loader = new UniversalContentLoader(new UniversalFileLoader(input));
const openApiDoc = await loader.load();
const spec = await OpenApiSpec.parse(openApiDoc, { skipValidation: false });
// Build the transformation model
const model = CodeGenerationModel.fromDoc(name, spec.document);
// Emit descriptors
await writeIfChangedAsync(
path.join(output, "descriptors.ts"),
await prepareTypeScriptOutput(model.paths.compileDescriptors()),
);
// Emit types
await writeIfChangedAsync(
path.join(output, "types.ts"),
await prepareTypeScriptOutput(
await model.compileTypes({ rootNamespace: name, optionalHeaders: ["x-access-token"] }),
),
);
// Emit client
await writeIfChangedAsync(
path.join(output, "client.ts"),
await prepareTypeScriptOutput(model.paths.compileClient()),
);
// Emit React client (optional)
await writeIfChangedAsync(
path.join(output, "client-react.ts"),
await prepareTypeScriptOutput(model.paths.compileReactClient()),
);
console.log("Code generation complete.");
```
```
--------------------------------
### Create Unauthenticated Client
Source: https://context7.com/mittwald/api-client-js/llms.txt
Creates a MittwaldAPIV2Client without authentication, suitable for accessing public endpoints like listing available software versions.
```typescript
import { MittwaldAPIV2Client } from "@mittwald/api-client";
const client = MittwaldAPIV2Client.newUnauthenticated();
const response = await client.app.listApps({});
assertStatus(response, 200);
console.log("Available apps:", response.data.map((a) => a.name));
```
--------------------------------
### assertOneOfStatus(response, expectedStatuses)
Source: https://context7.com/mittwald/api-client-js/llms.txt
Like `assertStatus`, but accepts an array of acceptable status codes. Useful for optional resources or operations with multiple valid outcomes.
```APIDOC
## assertOneOfStatus(response, expectedStatuses)
### Description
Like `assertStatus`, but accepts an array of acceptable status codes. Useful for optional resources or operations with multiple valid outcomes.
### Usage
```typescript
import { MittwaldAPIV2Client, assertOneOfStatus } from "@mittwald/api-client";
const client = MittwaldAPIV2Client.newWithToken(process.env.MITTWALD_API_TOKEN!);
const response = await client.project.getProject({
pathParameters: { projectId: "maybe-existing-id" },
});
assertOneOfStatus(response, [200, 404]);
if (response.status === 200) {
console.log("Found:", response.data.description);
} else {
console.log("Not found, status:", response.status);
}
```
```
--------------------------------
### Programmatic TypeScript API Client Generation
Source: https://context7.com/mittwald/api-client-js/llms.txt
Generates an API client programmatically using the CodeGenerationModel. This is useful for build scripts or CI pipelines. Ensure all necessary modules are imported and paths are correctly resolved.
```typescript
import * as path from "path";
import {
UniversalContentLoader,
UniversalFileLoader,
OpenApiSpec,
CodeGenerationModel,
prepareTypeScriptOutput,
writeIfChangedAsync,
} from "@mittwald/api-code-generator/js";
const name = "MyAPIV2";
const input = path.resolve("spec/openapi.json");
const output = path.resolve("src/generated");
// Load and parse the OpenAPI spec
const loader = new UniversalContentLoader(new UniversalFileLoader(input));
const openApiDoc = await loader.load();
const spec = await OpenApiSpec.parse(openApiDoc, { skipValidation: false });
// Build the transformation model
const model = CodeGenerationModel.fromDoc(name, spec.document);
// Emit descriptors
await writeIfChangedAsync(
path.join(output, "descriptors.ts"),
await prepareTypeScriptOutput(model.paths.compileDescriptors()),
);
// Emit types
await writeIfChangedAsync(
path.join(output, "types.ts"),
await prepareTypeScriptOutput(
await model.compileTypes({ rootNamespace: name, optionalHeaders: ["x-access-token"] }),
),
);
// Emit client
await writeIfChangedAsync(
path.join(output, "client.ts"),
await prepareTypeScriptOutput(model.paths.compileClient()),
);
// Emit React client (optional)
await writeIfChangedAsync(
path.join(output, "client-react.ts"),
await prepareTypeScriptOutput(model.paths.compileReactClient()),
);
console.log("Code generation complete.");
```
--------------------------------
### withAccessToken
Source: https://github.com/mittwald/api-client-js/blob/master/packages/commons/README.md
An interceptor that automatically adds the user's access token to every API request as an Authorization header.
```APIDOC
## withAccessToken(client, token)
### Description
Automatically sets the `Authorization` request header with the provided `token` for all API requests made by the `client`.
### Parameters
- **client**: An instance of `APIClient`.
- **token** (string): The access token to be used for authentication.
### Returns
An `APIClient` instance configured with the access token interceptor.
### Example
```ts
const client = new APIClient({ baseURL });
const authenticatedClient = withToken(client, token);
```
```
--------------------------------
### Define Behavior Interface
Source: https://github.com/mittwald/api-client-js/blob/master/packages/models/README.md
Defines the interface for project behaviors, specifying the methods that concrete behavior implementations must provide.
```typescript
export interface ProjectBehaviors {
find: (id: string) => Promise;
updateDescription: (projectId: string, description: string) => Promise;
}
```
--------------------------------
### Assert One of Multiple HTTP Statuses with assertOneOfStatus()
Source: https://context7.com/mittwald/api-client-js/llms.txt
Accepts an array of acceptable status codes, similar to `assertStatus`. Useful for optional resources or operations with multiple valid outcomes, such as checking for a resource that might exist (200) or not (404).
```typescript
import { MittwaldAPIV2Client, assertOneOfStatus } from "@mittwald/api-client";
const client = MittwaldAPIV2Client.newWithToken(process.env.MITTWALD_API_TOKEN!);
const response = await client.project.getProject({
pathParameters: { projectId: "maybe-existing-id" },
});
assertOneOfStatus(response, [200, 404]);
if (response.status === 200) {
console.log("Found:", response.data.description);
} else {
console.log("Not found, status:", response.status);
}
```
--------------------------------
### Validate OpenAPI Spec with CLI
Source: https://github.com/mittwald/api-client-js/blob/master/packages/generator/README.md
Use the `acg validate` command to validate your OpenAPI specification file.
```shell
acg validate spec/openapi.json
```
--------------------------------
### extractTotalCountHeader(response)
Source: https://context7.com/mittwald/api-client-js/llms.txt
Reads the `x-pagination-totalcount` response header from a 200 list response and returns it as a number. Throws if the header is absent or invalid.
```APIDOC
## extractTotalCountHeader(response)
### Description
Reads the `x-pagination-totalcount` response header from a 200 list response and returns it as a number. Throws if the header is absent or invalid.
### Usage
```typescript
import { MittwaldAPIV2Client, extractTotalCountHeader } from "@mittwald/api-client";
const client = MittwaldAPIV2Client.newWithToken(process.env.MITTWALD_API_TOKEN!);
const response = await client.project.listProjects({
queryParameters: { limit: 1 },
});
const totalCount = extractTotalCountHeader(response);
console.log(`Total projects: ${totalCount}`);
// Fetch all pages
const allProjects = [];
const pageSize = 50;
for (let skip = 0; skip < totalCount; skip += pageSize) {
const page = await client.project.listProjects({
queryParameters: { limit: pageSize, skip },
});
assertStatus(page, 200);
allProjects.push(...page.data);
}
```
```
--------------------------------
### `acg generate`
Source: https://context7.com/mittwald/api-client-js/llms.txt
The primary CLI command for `@mittwald/api-code-generator`. It reads an OpenAPI JSON/YAML specification and generates typed TypeScript files for an API client, including descriptors, types, and client implementations.
```APIDOC
## `@mittwald/api-code-generator`
### `acg generate` — CLI: Generate TypeScript API client from OpenAPI spec
The primary CLI command. Reads an OpenAPI JSON/YAML spec and emits typed TypeScript files: `descriptors.ts`, `types.ts`, `client.ts`, and optionally `client-react.ts`.
```shell
# Install the generator
npm install -D @mittwald/api-code-generator
# Validate the spec first
acg validate spec/openapi.json
# Generate the client
acg generate \
--name MyAPIV2 \
--optionalHeader x-access-token \
spec/openapi.json \
src/generated
# Generated output:
# src/generated/descriptors.ts – operation metadata
# src/generated/types.ts – request/response TypeScript types
# src/generated/client.ts – Axios-based typed client class
# src/generated/client-react.ts – React suspense resource wrappers
```
```
--------------------------------
### Avoid Direct API Calls in Models
Source: https://github.com/mittwald/api-client-js/blob/master/packages/models/README.md
Demonstrates an anti-pattern where API calls are made directly within the model class. This leads to tight coupling and makes testing difficult.
```typescript
class ProjectDetailed {
public static async find(
id: string,
): Promise {
const response = await client.project.getProject({
id,
});
if (response.status === 200) {
return new Project(response.data.id, response.data);
}
assertStatus(response, 403);
}
}
```