Skip to content

Commit

Permalink
feat: add documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Julien-R44 committed Oct 15, 2024
1 parent 7f17f84 commit a2a825c
Show file tree
Hide file tree
Showing 10 changed files with 839 additions and 455 deletions.
203 changes: 3 additions & 200 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ Set of tools to create typesafe APIs using AdonisJS. The monorepo includes the f

The main goal of this project is to provide some utilities to have better typesafety when creating APIs with AdonisJS. Goals on the long term are :

- **Done (Experimental)** : Provide an RPC-like client that is fully e2e typesafe ( like tRPC, Elysia Eden, Hono etc. )
- **Done (Experimental)** : Provide a [Ziggy](https://github.com/tighten/ziggy)-like helper to generate and use routes in the frontend.
- **Done** : Provide an RPC-like client that is fully e2e typesafe ( like tRPC, Elysia Eden, Hono etc. )
- **Done** : Provide a [Ziggy](https://github.com/tighten/ziggy)-like helper to generate and use routes in the frontend.
- **Done (Experimental)** : Having an automatic OpenAPI generation + Swagger/Scalar UI viewer based on Tuyau codegen.
- **In Progress** : Provide some Inertia helpers to have better typesafety when using Inertia in your AdonisJS project. Things like typesafe `<Link />` and `useForm`.
- **Not started** : Provide a specific Controller class that will allow to have better typesafety when creating your endpoints.
- **Not started**: Having a Tanstack-Query integration for the client package. Like [tRPC](https://trpc.io/docs/client/react) or [ts-rest](https://ts-rest.com/docs/vue-query) does.

## Installation

Expand Down Expand Up @@ -455,201 +456,3 @@ export default defineConfig({
Only one of `only` or `except` can be used at the same time. Both accept either an array of strings, an array of regular expressions or a function that will receive the route name and must return a boolean.

`definitions` will filter the generated types in the `ApiDefinition` interface. `routes` will the filter the route names that are generated in the `routes` object.

## Inertia package

Tuyau also provides a set of helpers for Inertia projects. The package is called `@tuyau/inertia`. First, make sure to have generated the API definition in your AdonisJS project using `@tuyau/core` and also have configured the client in your frontend project using `@tuyau/client`.

Then, you can install the package in your frontend project :

```bash
pnpm add @tuyau/inertia
```
### React usage

To use the Inertia helpers in your React x Inertia project, you must wrap your app with the `TuyauProvider` component :

```tsx
// inertia/app/app.tsx
import { TuyauProvider } from '@tuyau/inertia/react'
import { tuyau } from './tuyau'

createInertiaApp({
// ...

setup({ el, App, props }) {
hydrateRoot(
el,
<>
<TuyauProvider client={tuyau}>
<App {...props} />
</TuyauProvider>
</>
)
},
})
```

As you can see, you must pass an instance of the Tuyau client to the `TuyauProvider` component. Also, if you are using SSR, make sure to also wrap your app with the `TuyauProvider` component in your `inertia/app/ssr.tsx` file.

#### Link

The `Link` component is a wrapper around the Inertia `Link` component with some additional typesafety. Tuyau `Link` component will accept the same props as the Inertia `Link` component except for the `href` and `method` props. They are replaced by the `route` and `params` props.

```tsx
import { Link } from '@tuyau/inertia/react'

<Link route="users.posts.show" params={{ id: 1, postId: 2 }}>Go to post</Link>
```

### Vue usage

To use the Inertia helpers in your Vue x Inertia project, you must install the Tuyau plugin :

```ts
// inertia/app/app.ts

import { TuyauPlugin } from '@tuyau/inertia/vue'
import { tuyau } from './tuyau'

createInertiaApp({
// ...

setup({ el, App, props, plugin }) {
createSSRApp({ render: () => h(App, props) })
.use(plugin)
.use(TuyauPlugin, { client: tuyau })
.mount(el)
},
})
```

As you can see, you must pass an instance of the Tuyau client to the `TuyauPlugin` plugin. Also, if you are using SSR, make sure to also install the `TuyauPlugin` plugin in your `inertia/app/ssr.ts` file.

#### Link

The `Link` component is a wrapper around the Inertia `Link` component with some additional typesafety. Tuyau `Link` component will accept the same props as the Inertia `Link` component except for the `href` and `method` props. They are replaced by the `route` and `params` props.

```vue
<script setup lang="ts">
import { Link } from '@tuyau/inertia/vue'
</script>
<template>
<Link route="users.posts.show" :params="{ id: 1, postId: 2 }">Go to post</Link>
</template>
```

## OpenAPI package

> [!WARNING]
> OpenAPI package is still experimental and may not work as expected. Please feel free to open an issue if you encounter any problem.
The `@tuyau/openapi` package allows you to generate an OpenAPI specification for your API from the Tuyau codegen. The specification is generated from the types of routes and validation schemas, using the Typescript compiler and `ts-morph`. Therefore, it has some limitations compared to manually written specifications (whether via decorators, JS doc, YAML files, or Zod schemas describing the inputs/outputs of the routes).

During development, the specification will be generated on the fly with each request, which can take a bit of time for large APIs with many routes. In production, the specification will be generated at build time into a `.yml` file and the same specification will be served for each request.

### Installation

To install the package, you will obviously need to have the `@tuyau/core` package already installed in your AdonisJS project. Then, you can install the `@tuyau/openapi` package:

```bash
node ace add @tuyau/openapi
```

### Usage

Once the package is configured, you can directly access your API's OpenAPI specification at the `/docs` address. The `/openapi` route is also available to directly access the OpenAPI specification.

### Customizing the Specification

To customize the specification, the package exposes `openapi` macros on the routes. These macros allow you to add additional information to the OpenAPI specification. For example, you can add tags, descriptions, responses, parameters, etc.

```ts
router.group(() => {
router
.get("/random", [MiscController, "index"])
.openapi({ summary: "Get a random thing" });

router
.get("/random/:id", [MiscController, "show"])
.openapi({ summary: "Get a random thing by id" });
})
.prefix("/misc")
.openapi({ tags: ["misc"] });
```

Feel free to use your editor's autocomplete to see all available options.

Also, from the `config/tuyau.ts` file, you have the ability to customize the OpenAPI specification with the `openapi.documentation` property:

```ts
const tuyauConfig = defineConfig({
openapi: {
documentation: {
info: { title: 'My API!', version: '1.0.0', description: 'My super API' },
tags: [
{ name: 'subscriptions', description: 'Operations about subscriptions' },
],
},
},
});
```

### Configuration

The package configuration is done via the `config/tuyau.ts` file, under the `openapi` key. The available options are as follows:

#### `provider`

The OpenAPI viewer to use. Two providers are available: `swagger-ui` and `scalar`. By default, the `scalar` provider is used.

#### `exclude`

Paths to exclude from the OpenAPI specification. By default, no paths are excluded. You can pass an array of strings or regex.

Example:

```ts
const tuyauConfig = defineConfig({
openapi: {
exclude: ['/health', /admin/]
}
});
```

#### `endpoints`

The endpoints where the OpenAPI specification and documentation will be available. By default, the OpenAPI specification will be available at `/openapi` and the documentation at `/docs`.

Example:

```ts
const tuyauConfig = defineConfig({
openapi: {
endpoints: {
spec: '/my-super-spec',
ui: '/my-super-doc'
}
}
});
```

#### `scalar`

The options to pass to the `scalar` provider when used. More details [here](https://github.com/scalar/scalar?tab=readme-ov-file#configuration).

#### `swagger-ui`

The options to pass to the `swagger-ui` provider when used. More details [here](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/).

## Sponsors

![](https://github.com/julien-r44/static/blob/main/sponsorkit/sponsors.png?raw=true)

## Credits

- Tuyau was inspired a lot by [Elysia](https://elysiajs.com/eden/treaty/overview), [tRPC](https://trpc.io/) and [Hono](https://hono.dev/) for the RPC client.
- Route helpers were inspired by [Ziggy](https://github.com/tighten/ziggy)

Thanks to the authors of these projects for the inspiration !
Binary file added docs/assets/images/banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 6 additions & 15 deletions docs/content/config.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
{
"links": {
"home": {
"title": "Your project name",
"title": "Tuyau",
"href": "/"
},
"github": {
"title": "Your project on Github",
"href": "https://github.com/dimerapp"
"title": "Tuyau on GitHub",
"href": "https://github.com/Julien-R44/tuyau"
}
},
"sponsors_sources": [
],
"sponsors_sources": ["julien-r44"],
"search": {
},
"advertising_sponsors": [
{
"link": "",
"logo": "",
"logo_dark": "",
"logo_styles": ""
}
],
"fileEditBaseUrl": "https://github.com/dimerapp/docs-boilerplate/blob/develop",
"copyright": "Your project legal name"
"fileEditBaseUrl": "https://github.com/tuyau/tree/main/docs",
"copyright": "Tuyau"
}
Loading

0 comments on commit a2a825c

Please sign in to comment.