👷🏻 Auto-generate frontend client (#1320)

This commit is contained in:
Alejandra
2024-08-29 20:10:49 +02:00
committed by GitHub
parent e8c73ff614
commit bbad34aa8d
7 changed files with 100 additions and 31 deletions

49
.github/workflows/generate-client.yml vendored Normal file
View File

@@ -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 "github-actions@github.com"
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) }}

View File

@@ -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).
@@ -27,7 +27,7 @@ nvm install
```bash
# If using fnm
fnm use
fnm use
# If using nvm
nvm use
@@ -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.

View File

@@ -6,7 +6,6 @@
"files": {
"ignore": [
"node_modules",
"src/client/",
"src/routeTree.gen.ts",
"playwright.config.ts",
"playwright-report"

View File

@@ -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",

View File

@@ -1,9 +1,9 @@
import axios from "axios"
import type {
AxiosError,
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
AxiosInstance,
} from "axios"
import { ApiError } from "./ApiError"
@@ -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) {

View File

@@ -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 = {
@@ -50,7 +50,7 @@ export class LoginService {
formData: formData,
mediaType: "application/x-www-form-urlencoded",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
@@ -85,7 +85,7 @@ export class LoginService {
email,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
@@ -106,7 +106,7 @@ export class LoginService {
body: requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
@@ -128,7 +128,7 @@ export class LoginService {
email,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
@@ -180,7 +180,7 @@ export class UsersService {
limit,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
@@ -201,7 +201,7 @@ export class UsersService {
body: requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
@@ -248,7 +248,7 @@ export class UsersService {
body: requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
@@ -269,7 +269,7 @@ export class UsersService {
body: requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
@@ -290,7 +290,7 @@ export class UsersService {
body: requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
@@ -312,7 +312,7 @@ export class UsersService {
user_id: userId,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
@@ -336,7 +336,7 @@ export class UsersService {
body: requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
@@ -356,7 +356,7 @@ export class UsersService {
user_id: userId,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
@@ -382,7 +382,7 @@ export class UtilsService {
email_to: emailTo,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
@@ -425,7 +425,7 @@ export class ItemsService {
limit,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
@@ -446,7 +446,7 @@ export class ItemsService {
body: requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
@@ -466,7 +466,7 @@ export class ItemsService {
id,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
@@ -490,7 +490,7 @@ export class ItemsService {
body: requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}
@@ -510,7 +510,7 @@ export class ItemsService {
id,
},
errors: {
422: "Validation Error",
422: `Validation Error`,
},
})
}

View File

@@ -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