npm package: @llelievr.dev/openapi-solid-query-codegen
Description: OpenAPI Solidjs Query Codegen
Author: Lucas Lelievre
Latest version: 0.0.3

# OpenAPI Solid Query Codegen

> This library is a fork based on [openapi-react-query-codegen](https://github.com/7nohe/openapi-react-query-codegen)
> The code is pretty much the same aside from a few tweaks to work with solidjs
> Things like useSuspense could not be ported as they do not exist inside solid-query

> Node.js library that generates [Solid Query (also called TanStack Query)](https://tanstack.com/query) hooks based on an OpenAPI specification file.

[![npm version](https://badge.fury.io/js/@llelievr.dev%2Fopenapi-solid-query-codegen.svg)](https://badge.fury.io/js/@llelievr.dev%2Fopenapi-solid-query-codegen)

## Features

- Generates custom solidjs hooks that use Solid Query's `createQuery`, and `createMutation` hooks
- Generates query keys and functions for query caching
- Generates pure TypeScript clients generated by [@hey-api/openapi-ts](https://github.com/hey-api/openapi-ts)

## Installation

```
$ npm install -D @llelievr.dev/openapi-solid-query-codegen
```

Register the command to the `scripts` property in your package.json file.

```json
{
  "scripts": {
    "codegen": "openapi-sq -i ./petstore.yaml -c axios"
  }
}
```

You can also run the command without installing it in your project using the npx command.

```bash
$ npx --package @llelievr.dev/openapi-solid-query-codegen openapi-sq -i ./petstore.yaml -c axios
```

## Usage

```
$ openapi-sq --help

Usage: openapi-sq [options]

Generate Solid Query code based on OpenAPI

Options:
  -V, --version              output the version number
  -i, --input <value>        OpenAPI specification, can be a path, url or string content (required)
  -o, --output <value>       Output directory (default: "openapi")
  -c, --client <value>       HTTP client to generate [fetch, xhr, node, axios, angular] (default: "fetch")
  --request <value>          Path to custom request file
  --format <value>           Process output folder with formatter? ['biome', 'prettier']
  --lint   <value>           Process output folder with linter? ['eslint', 'biome']
  --operationId              Use operation ID to generate operation names?
  --serviceResponse <value>  Define shape of returned value from service calls ['body', 'response'] (default: "body")
  --base <value>             Manually set base in OpenAPI config instead of inferring from server value
  --enums <value>            Generate JavaScript objects from enum definitions? ['javascript', 'typescript']
  --useDateType              Use Date type instead of string for date types for models, this will not convert the data to a Date object
  --debug                    Enable debug mode
  --noSchemas                Disable generating schemas for request and response objects
  --schemaTypes <value>      Define the type of schema generation ['form', 'json'] (default: "json")
  -h, --help                 display help for command
```

### Example Usage

#### Command

```
$ openapi-sq -i ./petstore.yaml
```

#### Output directory structure

```
- openapi
  - queries
    - index.ts <- main file that exports common types, variables, and queries. Does not export prefetch hooks
    - common.ts <- common types
    - queries.ts <- generated query hooks
    - prefetch.ts <- generated prefetch hooks learn more about prefetching in in link below
  - requests <- output code generated by @hey-api/openapi-ts
```

- [Prefetching docs](https://tanstack.com/query/latest/docs/reference/QueryClient/#queryclientprefetchquery)

#### In your app

##### Using the generated hooks

```tsx
// App.tsx
import { Component, createSignal, For } from "solid-js";
import {
  createPetServiceFindPetsByStatus,
  createStoreServicePlaceOrder,
} from "../openapi/queries";
import { Pet } from "../openapi/requests";

function App() {
  const [status, setStatus] = createSignal<Pet["status"]>("available");
  const data = createPetServiceFindPetsByStatus(() => ({
    data: {
      status: status(),
    },
  }));

  return (
    <>
      <h1>Pet List</h1>
      <ul>
        <For each={data.data} fallback={<>LOADING</>}>
          {(pet) => <li>{pet.name}</li>}
        </For>
      </ul>
    </>
  );
}

export default App;
```

##### Using Mutation hooks

```tsx
// App.tsx
import { usePetServiceAddPet } from "../openapi/queries";

function App() {
  const { mutate } = createStoreServicePlaceOrder();

  const handlePlaceOrder = () => {
    mutate({
      requestBody: { petId: 198772, quantity: 10 },
    });
  };

  return (
    <div className="App">
      <h1>Order a pet</h1>
      <button onClick={handlePlaceOrder}>Order Pet</button>
    </div>
  );
}

export default App;
```

##### Invalidating queries after mutation

Invalidating queries after a mutation is important to ensure the cache is updated with the new data. This is done by calling the `queryClient.invalidateQueries` function with the query key used by the query hook.

Learn more about invalidating queries [here](https://tanstack.com/query/latest/docs/reference/QueryClient/#queryclientinvalidatequeries).

To ensure the query key is created the same way as the query hook, you can use the query key function exported by the generated query hooks.

##### Runtime Configuration

You can modify the default values used by the generated service calls by modifying the OpenAPI configuration singleton object.

It's default location is `openapi/requests/core/OpenAPI.ts` and it is also exported from `openapi/index.ts`

Import the constant into your runtime and modify it before setting up the solidjs app.

```typescript
/** index.tsx */
import { OpenAPI as OpenAPIConfig } from './openapi/requests/core/OpenAPI';
...
OpenAPIConfig.BASE = 'www.domain.com/api';
OpenAPIConfig.HEADERS = {
  'x-header-1': 'value-1',
  'x-header-2': 'value-2',
};
...
render(
  () => (
    <QueryClientProvider client={queryClient}>
      <App />
    </QueryClientProvider>
  ),
  root!
);


```

## Development

### Install dependencies

```bash
pnpm install
```

### Run tests

```bash
pnpm test
```

### Run linter

```bash
pnpm lint
```

### Run linter and fix

```bash
pnpm lint:fix
```

### Update snapshots

```bash
pnpm snapshot
```

### Build example and validate generated code

```bash
npm run build && pnpm --filter @llelievr.dev/solid-app generate:api && pnpm --filter @llelievr.dev/solid-app test:generated
```

## License

MIT