# API Client Generator

## Description

Generates API clients from OpenAPI (formerly Swagger) specification YAML files.

Generated content includes:

- Axios-based API client
- fetch-based API client
- TypeScript types
- Zod schemas

Todo:

- [SWR](https://swr.vercel.app/) (state-while-revalidate)
- [Tanstack Query](https://tanstack.com/query/latest) (aka React Query)
- [MSW](https://mswjs.io/) (Mock Service Worker)

## Installation

1. Install dependencies

   ```bash
   $ npm install
   ```

## Setup

1. Copy `.env.shadow` to `.env`

   ```bash
   $ cp .env.shadow .env
   ```

1. Configure your .env file

   ```.env
   INPUT_FILE=./ows_abacus_event-1.0.0.yaml
   ```

## Generation

1. Generate content into the `gen/` directory

   ```bash
   $ npm start
   ```

   And that's it!

## Updating an Existing API Client Library

1. Delete any existing `gen/` directory in your project

1. Copy the generated `gen/` directory to your project

1. Rebuild your project

   ```bash
   $ npm run build
   ```

## Creating an API Client Library

1. Delete any existing `gen/` directory in your project

1. Copy the generated `gen/` directory to your project

1. Include the `gen/` directory in your `tsconfig.json` file

   ```json
   // tsconfig.json

   {
     "compilerOptions": {
       // Optional: Simplify paths to the `gen/` directory
       "paths": {
         // ...
         "gen/*": ["./gen/*"]
       }
       // ...
     },
     "include": ["src", "gen"]
   }
   ```

1. Update your lint settings to ignore the `gen/` directory

   ```js
   // eslint.config.js

   export default defineConfig([
     {
       // Define global ignores. Must be used without
       // any other keys in the configuration object.
       ignores: [, /*...*/ "gen"],
     },
     // ...
   ]);
   ```

1. Install `Axios` and `Zod` as peer dependencies
   - First install as dev dependencies

     ```bash
     $ npm install -D axios zod
     ```

   - Then move the entries from `devDependencies` to `peerDependencies`. For example:

     ```json
     // package.json

     {
       // ...
       "peerDependencies": {
         // ...
         "axios": "^1.10.0",
         "zod": "^3.25.67"
       }
     }
     ```

1. Add your package exports

   ```json
   // package.json

   {
     // ...
     "exports": {
       ".": {
         "types": "./dist/cjs/index.d.cts",
         "require": "./dist/cjs/index.cjs",
         "import": "./dist/esm/index.js"
       },
       "./axios": {
         "types": "./dist/cjs/axios.d.cts",
         "require": "./dist/cjs/axios.cjs",
         "import": "./dist/esm/axios.js"
       },
       "./fetch": {
         "types": "./dist/cjs/fetch.d.cts",
         "require": "./dist/cjs/fetch.cjs",
         "import": "./dist/esm/fetch.js"
       },
       "./zod": {
         "types": "./dist/cjs/zod.d.cts",
         "require": "./dist/cjs/zod.cjs",
         "import": "./dist/esm/zod.js"
       }
     }
     // ...
   }
   ```

1. Update your build setup

   ```ts
   // tsup.config.ts

   {
      // ...
      entryPoints: [
         "gen/index.ts",
         "gen/axios.ts",
         "gen/fetch.ts",
         "gen/zod.ts"
      ],
      external: ["axios", "zod"],
      // ...
   }
   ```

1. Build your project

   ```bash
   $ npm run build
   ```

## Basic Usage

### Axios

Requires [Axios](https://www.npmjs.com/package/axios)

```ts
import { OwsAbacusEventClient } from "@abacus/api-event-client/axios";

async main() => {
    console.log(`Pinging API ows-abacus-event...`);
    const eventClient = new OwsAbacusEventClient();
    const { data: health } = await eventClient.getHealth();
    console.log(`\tAPI status: ${health.status}`); // ok
}
```

### Fetch

```ts
import { OwsAbacusEventClient } from "@abacus/api-event-client/fetch";

async main() => {
    console.log(`Pinging API ows-abacus-event...`);
    const eventClient = new OwsAbacusEventClient();
    const { data: health } = await eventClient.getHealth();
    console.log(`\tAPI status: ${health.status}`); // ok
}
```

### Types

```ts
import { type ContractId } from "@abacus/api-event-client";

const contractId: ContractId;
```

### Zod

Requires [Zod](https://www.npmjs.com/package/zod)

```ts
import * as schemas from "@abacus/api-event-client/zod";

const rawContractId = 12345;
const contractId = schemas.contractId.parse(contractId);
```
