Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions packages/api-client/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# AI Agent Guide for @shopware/api-client

This document provides guidance for AI assistants working with the `@shopware/api-client` package.

## TL;DR

**What**: Fully typed HTTP client for Shopware 6 Store API and Admin API
**Tech**: TypeScript, ofetch, openapi-fetch-runtime
**Types**: Generated from OpenAPI spec via `@shopware/api-gen` CLI

**Quick Start**:
```bash
pnpm run build # Build the package
pnpm run dev # Stub mode for development (hot reload)
pnpm run test # Run tests
```

**Before commits**: `pnpm run lint:fix && pnpm format && pnpm run typecheck`

## Package Overview

`@shopware/api-client` is a thin, typed wrapper around [ofetch](https://github.com/unjs/ofetch). Its key feature is the `operations` generic that carries OpenAPI operation types end-to-end — from the `invoke()` call signature to the return type. Users either import the bundled default types or replace them with types generated from their own Shopware instance via `@shopware/api-gen`.

## Directory Structure

```
api-client/
├── src/
│ ├── createAPIClient.ts # Store API client factory
│ ├── createAdminAPIClient.ts # Admin API client factory
│ ├── errorInterceptor.ts # ApiClientError + error parsing
│ ├── helpers.ts # encodeForQuery helper
│ └── index.ts # Public exports
├── api-types/
│ ├── storeApiTypes.d.ts # Bundled Store API types (generated)
│ ├── adminApiTypes.d.ts # Bundled Admin API types (generated)
│ └── storeApiSchema.overrides.json # Default JSON patches applied during generation
├── src/fetch/ # Low-level fetch wrappers
└── _tests/ # Vitest tests with mock server
```

## Key Files

- [src/createAPIClient.ts](src/createAPIClient.ts) — `createAPIClient<operations>()` factory; hooks, context token management, `invoke()`
- [src/createAdminAPIClient.ts](src/createAdminAPIClient.ts) — `createAdminAPIClient<operations>()` factory; OAuth2 (password + client_credentials), session persistence
- [src/errorInterceptor.ts](src/errorInterceptor.ts) — `ApiClientError` class with parsed API error details
- [src/helpers.ts](src/helpers.ts) — `encodeForQuery()` for compressed GET criteria
- [api-types/storeApiSchema.overrides.json](api-types/storeApiSchema.overrides.json) — default patches shipped with the package (referenced by `api-gen` users)

## Type System

The entire type safety model flows from a single generic parameter `operations`:

```
createAPIClient<operations>() → client.invoke("operationId method /path", body)
↑ typed by operations key
```

The `operations` type is a map of `"operationId method /path"` keys to objects describing `body`, `query`, `pathParams`, `response`, and `responseCode`.

**Three sources for `operations`**:
1. **Bundled default** — `@shopware/api-client/store-api-types` or `@shopware/api-client/admin-api-types`
2. **Generated from instance** — `./api-types/storeApiTypes` (via `@shopware/api-gen`)
3. **Extended/overridden** — `./api-types/storeApiTypes.overrides.ts` (merges generated + custom)

When working on this package, never edit `api-types/*.d.ts` manually — they are generated artifacts. To regenerate them, use `@shopware/api-gen` with the appropriate schema.

## Common Tasks

### Adding a hook

Hooks are registered in `createAPIClient.ts` / `createAdminAPIClient.ts`. Available hook names are typed via the `ClientHooks` interface. Add new hook types there first, then wire them into the fetch lifecycle.

### Fixing error handling

Error parsing lives in `errorInterceptor.ts`. The `ApiClientError` class wraps raw API responses and exposes `details` for structured error data.

### Updating bundled types

Bundled types (`api-types/*.d.ts`) are generated — do not edit them. To update:
```bash
# From repo root
pnpm run generate-types
```
This runs `@shopware/api-gen` against the configured Shopware instance and regenerates the `.d.ts` files.

### Adding new `fetchOptions`

The allowed subset of `ofetch` options is explicitly listed in the client types. If a new option needs to be exposed, add it to the `FetchOptions` type in `src/createAPIClient.ts` and document it in the README.

## Testing

Tests live in `_tests/` and use Vitest with a mock HTTP server (no real Shopware instance needed).

```bash
pnpm run test # Run all tests
pnpm run test:watch # Watch mode
```

Tests exercise `invoke()` calls, hook firing, error parsing, and auth flows. When adding features, add matching tests.

## Relationship with @shopware/api-gen

`@shopware/api-gen` is the CLI companion that produces the `operations` and `components` types consumed here. The two packages are decoupled — `api-client` ships default types for convenience, but end users are encouraged to generate their own.

The default patches file `api-types/storeApiSchema.overrides.json` is referenced by `api-gen` users via:
```json
{ "store-api": { "patches": ["./node_modules/@shopware/api-client/api-types/storeApiSchema.overrides.json"] } }
```

Keep this file in sync when the bundled types are regenerated.

## References

- [README.md](README.md) — User-facing docs including setup, type customization, usage examples
- [@shopware/api-gen](../api-gen/README.md) — Type generation CLI
- [frontends.shopware.com](https://frontends.shopware.com/) — Full documentation
141 changes: 141 additions & 0 deletions packages/api-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,147 @@ adminApiClient.hook("onAuthChange", (sessionData) => {

the rest works the same as store-api client.

## Customizing API Types

The client is fully typed via a generic `operations` parameter. You can use the bundled default types or generate and override types from your own Shopware instance.

### Generating types from your instance

Use [@shopware/api-gen](https://www.npmjs.com/package/@shopware/api-gen) to generate TypeScript types directly from your Shopware instance's OpenAPI schema.

```bash
# 1. Load the schema from your running Shopware instance
pnpx @shopware/api-gen loadSchema --apiType=store

# 2. Generate TypeScript types
pnpx @shopware/api-gen generate --apiType=store
```

This creates `api-types/storeApiTypes.ts` (or `adminApiTypes.ts` for Admin API). Point `shopware.d.ts` to your generated types instead of the bundled defaults:

```typescript
// shopware.d.ts
declare module "#shopware" {
import type { createAPIClient } from "@shopware/api-client";

export type operations = import("./api-types/storeApiTypes").operations;
export type Schemas = import("./api-types/storeApiTypes").components["schemas"];
export type ApiClient = ReturnType<typeof createAPIClient<operations>>;
}
```

All code importing from `#shopware` will now use your instance's types automatically.

Add a script to `package.json` to make regeneration easy:

```json
{
"scripts": {
"generate-types": "shopware-api-gen generate --apiType=store"
}
}
```

### TypeScript overrides

If your instance has custom fields, custom endpoints, or incorrect types in the OpenAPI spec, you can override or extend the generated types without modifying the generated file directly.

Create an overrides file next to the generated types:

- `api-types/storeApiTypes.overrides.ts` — for Store API
- `api-types/adminApiTypes.overrides.ts` — for Admin API

Create `api-types/storeApiTypes.overrides.ts` with your merged types:

```typescript
// api-types/storeApiTypes.overrides.ts
import type { components as mainComponents } from "./storeApiTypes";

// Extend schemas with your custom fields
export type components = mainComponents & {
schemas: Schemas;
};

export type Schemas = {
// Fully override an existing schema
Product: mainComponents["schemas"]["Product"] & {
customFields: {
my_custom_field: string;
};
};
};

// Add or override operations
export type operations = {
// Add a custom endpoint
"myCustomEndpoint post /custom/endpoint": {
contentType?: "application/json";
accept?: "application/json";
body: { id: string };
response: components["schemas"]["Product"];
responseCode: 200;
};
// Override an existing operation (e.g. restrict the request body)
"updateCustomerAddress patch /account/address/{addressId}": {
contentType?: "application/json";
accept?: "application/json";
body: { city: string };
response: components["schemas"]["CustomerAddress"];
responseCode: 200;
};
};
```

> [!IMPORTANT]
> Overriding a schema or operation requires a **full object definition** — partial overrides are not supported in TypeScript overlay files.

Then point `shopware.d.ts` to the overrides file instead of the generated one:

```typescript
// shopware.d.ts
declare module "#shopware" {
import type { createAPIClient } from "@shopware/api-client";

export type operations = import("./api-types/storeApiTypes.overrides").operations;
export type Schemas = import("./api-types/storeApiTypes.overrides").components["schemas"];
export type ApiClient = ReturnType<typeof createAPIClient<operations>>;
}
```

Your `apiClient.ts` already imports from `#shopware`, so no change is needed there — the overridden types flow through automatically.

### JSON patch overrides (partial schema fixes)

For fine-grained, field-level corrections to the JSON schema (e.g. marking a field as `required`, fixing a wrong type), use patch files. These are applied before TypeScript generation and support partial changes.

Create a `storeApiTypes.overrides.json` patch file:

```json
{
"components": {
"Cart": {
"required": ["price", "errors"]
}
}
}
```

Reference it in `api-gen.config.json`:

```json
{
"$schema": "./node_modules/@shopware/api-gen/api-gen.schema.json",
"store-api": {
"patches": [
"storeApiSchema.overrides.json",
"./api-types/myCustomPatches.json"
]
}
}
```

See the [@shopware/api-gen documentation](https://www.npmjs.com/package/@shopware/api-gen) for the full patching reference and available configuration options.

## Basic usage

Take a look at [example project using API Client](https://stackblitz.com/github/shopware/frontends/tree/main/examples/new-api-client).
Expand Down
Loading