Skip to content

Commit

Permalink
👷🏻 Auto-generate frontend client (#1320)
Browse files Browse the repository at this point in the history
  • Loading branch information
alejsdev authored Aug 29, 2024
1 parent e8c73ff commit bbad34a
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 31 deletions.
49 changes: 49 additions & 0 deletions .github/workflows/generate-client.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Generate Client

on:
pull_request:
types:
- opened
- synchronize

jobs:
generate-client:
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
token: ${{ secrets.FULL_STACK_FASTAPI_TEMPLATE_REPO_TOKEN }}
- uses: actions/setup-node@v4
with:
node-version: lts/*
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install dependencies
run: npm ci
working-directory: frontend
- run: pip install ./backend
- run: bash scripts/generate-client.sh
- name: Commit changes
run: |
git config --local user.email "[email protected]"
git config --local user.name "github-actions"
git add frontend/src/client
git diff --staged --quiet || git commit -m "✨ Autogenerate frontend client"
git push
# https://github.com/marketplace/actions/alls-green#why
generate-client-alls-green: # This job does nothing and is only used for the branch protection
if: always()
needs:
- generate-client
runs-on: ubuntu-latest
steps:
- name: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@release/v1
with:
jobs: ${{ toJSON(needs) }}

17 changes: 15 additions & 2 deletions frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The frontend is built with [Vite](https://vitejs.dev/), [React](https://reactjs.

## Frontend development

Before you begin, ensure that you have either the Node Version Manager (nvm) or Fast Node Manager (fnm) installed on your system.
Before you begin, ensure that you have either the Node Version Manager (nvm) or Fast Node Manager (fnm) installed on your system.

* To install fnm follow the [official fnm guide](https://github.com/Schniz/fnm#installation). If you prefer nvm, you can install it using the [official nvm guide](https://github.com/nvm-sh/nvm#installing-and-updating).

Expand All @@ -27,7 +27,7 @@ nvm install

```bash
# If using fnm
fnm use
fnm use

# If using nvm
nvm use
Expand Down Expand Up @@ -74,6 +74,19 @@ But it would be only to clean them up, leaving them won't really have any effect

## Generate Client

### Automatically

* Activate the backend virtual environment.
* From the top level project directory, run the script:

```bash
./scripts/generate-frontend-client.sh
```

* Commit the changes.

### Manually

* Start the Docker Compose stack.

* Download the OpenAPI JSON file from `http://localhost/api/v1/openapi.json` and copy it to a new file `openapi.json` at the root of the `frontend` directory.
Expand Down
1 change: 0 additions & 1 deletion frontend/biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"files": {
"ignore": [
"node_modules",
"src/client/",
"src/routeTree.gen.ts",
"playwright.config.ts",
"playwright-report"
Expand Down
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"build": "tsc && vite build",
"lint": "biome check --apply-unsafe --no-errors-on-unmatched --files-ignore-unknown=true ./",
"preview": "vite preview",
"generate-client": "openapi-ts --input ./openapi.json --output ./src/client --client axios --exportSchemas true && biome format --write ./src/client"
"generate-client": "openapi-ts --input ./openapi.json --output ./src/client --client axios --exportSchemas true"
},
"dependencies": {
"@chakra-ui/icons": "2.1.1",
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/client/core/request.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import axios from "axios"
import type {
AxiosError,
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
AxiosInstance,
} from "axios"

import { ApiError } from "./ApiError"
Expand Down Expand Up @@ -151,12 +151,12 @@ export const getHeaders = async (
)

if (isStringWithValue(token)) {
headers.Authorization = `Bearer ${token}`
headers["Authorization"] = `Bearer ${token}`
}

if (isStringWithValue(username) && isStringWithValue(password)) {
const credentials = base64(`${username}:${password}`)
headers.Authorization = `Basic ${credentials}`
headers["Authorization"] = `Basic ${credentials}`
}

if (options.body !== undefined) {
Expand Down
48 changes: 24 additions & 24 deletions frontend/src/client/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@ import { request as __request } from "./core/request"

import type {
Body_login_login_access_token,
ItemCreate,
ItemPublic,
ItemUpdate,
ItemsPublic,
Message,
NewPassword,
Token,
UserPublic,
UpdatePassword,
UserCreate,
UserPublic,
UserRegister,
UsersPublic,
UserUpdate,
UserUpdateMe,
UsersPublic,
ItemCreate,
ItemPublic,
ItemsPublic,
ItemUpdate,
} from "./models"

export type TDataLoginAccessToken = {
Expand Down Expand Up @@ -50,7 +50,7 @@ export class LoginService {
formData: formData,
mediaType: "application/x-www-form-urlencoded",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand Down Expand Up @@ -85,7 +85,7 @@ export class LoginService {
email,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand All @@ -106,7 +106,7 @@ export class LoginService {
body: requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand All @@ -128,7 +128,7 @@ export class LoginService {
email,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand Down Expand Up @@ -180,7 +180,7 @@ export class UsersService {
limit,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand All @@ -201,7 +201,7 @@ export class UsersService {
body: requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand Down Expand Up @@ -248,7 +248,7 @@ export class UsersService {
body: requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand All @@ -269,7 +269,7 @@ export class UsersService {
body: requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand All @@ -290,7 +290,7 @@ export class UsersService {
body: requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand All @@ -312,7 +312,7 @@ export class UsersService {
user_id: userId,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand All @@ -336,7 +336,7 @@ export class UsersService {
body: requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand All @@ -356,7 +356,7 @@ export class UsersService {
user_id: userId,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand All @@ -382,7 +382,7 @@ export class UtilsService {
email_to: emailTo,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand Down Expand Up @@ -425,7 +425,7 @@ export class ItemsService {
limit,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand All @@ -446,7 +446,7 @@ export class ItemsService {
body: requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand All @@ -466,7 +466,7 @@ export class ItemsService {
id,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand All @@ -490,7 +490,7 @@ export class ItemsService {
body: requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand All @@ -510,7 +510,7 @@ export class ItemsService {
id,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
Expand Down
8 changes: 8 additions & 0 deletions scripts/generate-client.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#! /usr/bin/env bash

PYTHONPATH=backend python -c "import app.main; import json; print(json.dumps(app.main.app.openapi()))" > openapi.json
node frontend/modify-openapi-operationids.js
mv openapi.json frontend/
cd frontend
npm run generate-client
npx biome format --write ./src/client

0 comments on commit bbad34a

Please sign in to comment.