⬆️ Upgrade Biome to the latest version (#1861)
This commit is contained in:
@@ -28,10 +28,10 @@ repos:
|
|||||||
hooks:
|
hooks:
|
||||||
- id: local-biome-check
|
- id: local-biome-check
|
||||||
name: biome check
|
name: biome check
|
||||||
entry: npx biome check --write --files-ignore-unknown=true --no-errors-on-unmatched
|
entry: bash -c 'cd frontend && npm run lint'
|
||||||
language: system
|
language: system
|
||||||
types: [text]
|
types: [text]
|
||||||
files: "\\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?|css|svelte|vue|astro|graphql|gql)$"
|
files: ^frontend/
|
||||||
|
|
||||||
ci:
|
ci:
|
||||||
autofix_commit_msg: 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
|
autofix_commit_msg: 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://biomejs.dev/schemas/1.6.1/schema.json",
|
"$schema": "https://biomejs.dev/schemas/2.2.3/schema.json",
|
||||||
"organizeImports": {
|
"assist": { "actions": { "source": { "organizeImports": "on" } } },
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
"files": {
|
"files": {
|
||||||
"ignore": [
|
"includes": [
|
||||||
"node_modules",
|
"**",
|
||||||
"src/routeTree.gen.ts",
|
"!**/dist/**/*",
|
||||||
"playwright.config.ts",
|
"!**/node_modules/**/*",
|
||||||
"playwright-report"
|
"!**/src/routeTree.gen.ts",
|
||||||
|
"!**/src/client/**/*",
|
||||||
|
"!**/src/components/ui/**/*",
|
||||||
|
"!**/playwright-report",
|
||||||
|
"!**/playwright.config.ts"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"linter": {
|
"linter": {
|
||||||
@@ -20,7 +22,10 @@
|
|||||||
"noArrayIndexKey": "off"
|
"noArrayIndexKey": "off"
|
||||||
},
|
},
|
||||||
"style": {
|
"style": {
|
||||||
"noNonNullAssertion": "off"
|
"noNonNullAssertion": "off",
|
||||||
|
"noParameterAssign": "error",
|
||||||
|
"useSelfClosingElements": "error",
|
||||||
|
"noUselessElse": "error"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ export default defineConfig({
|
|||||||
operationId: true,
|
operationId: true,
|
||||||
classNameBuilder: "{{name}}Service",
|
classNameBuilder: "{{name}}Service",
|
||||||
methodNameBuilder: (operation) => {
|
methodNameBuilder: (operation) => {
|
||||||
// @ts-ignore
|
// @ts-expect-error
|
||||||
let name: string = operation.name
|
let name: string = operation.name
|
||||||
// @ts-ignore
|
// @ts-expect-error
|
||||||
const service: string = operation.service
|
const service: string = operation.service
|
||||||
|
|
||||||
if (service && name.toLowerCase().startsWith(service.toLowerCase())) {
|
if (service && name.toLowerCase().startsWith(service.toLowerCase())) {
|
||||||
@@ -30,4 +30,4 @@ export default defineConfig({
|
|||||||
type: "json",
|
type: "json",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|||||||
143
frontend/package-lock.json
generated
143
frontend/package-lock.json
generated
@@ -23,7 +23,7 @@
|
|||||||
"react-icons": "^5.5.0"
|
"react-icons": "^5.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "1.9.4",
|
"@biomejs/biome": "^2.2.3",
|
||||||
"@hey-api/openapi-ts": "0.73.0",
|
"@hey-api/openapi-ts": "0.73.0",
|
||||||
"@playwright/test": "^1.55.0",
|
"@playwright/test": "^1.55.0",
|
||||||
"@tanstack/router-devtools": "^1.131.36",
|
"@tanstack/router-devtools": "^1.131.36",
|
||||||
@@ -552,11 +552,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/biome": {
|
"node_modules/@biomejs/biome": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.2.3.tgz",
|
||||||
"integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==",
|
"integrity": "sha512-9w0uMTvPrIdvUrxazZ42Ib7t8Y2yoGLKLdNne93RLICmaHw7mcLv4PPb5LvZLJF3141gQHiCColOh/v6VWlWmg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"hasInstallScript": true,
|
|
||||||
"license": "MIT OR Apache-2.0",
|
"license": "MIT OR Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
"biome": "bin/biome"
|
"biome": "bin/biome"
|
||||||
@@ -569,20 +568,20 @@
|
|||||||
"url": "https://opencollective.com/biome"
|
"url": "https://opencollective.com/biome"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@biomejs/cli-darwin-arm64": "1.9.4",
|
"@biomejs/cli-darwin-arm64": "2.2.3",
|
||||||
"@biomejs/cli-darwin-x64": "1.9.4",
|
"@biomejs/cli-darwin-x64": "2.2.3",
|
||||||
"@biomejs/cli-linux-arm64": "1.9.4",
|
"@biomejs/cli-linux-arm64": "2.2.3",
|
||||||
"@biomejs/cli-linux-arm64-musl": "1.9.4",
|
"@biomejs/cli-linux-arm64-musl": "2.2.3",
|
||||||
"@biomejs/cli-linux-x64": "1.9.4",
|
"@biomejs/cli-linux-x64": "2.2.3",
|
||||||
"@biomejs/cli-linux-x64-musl": "1.9.4",
|
"@biomejs/cli-linux-x64-musl": "2.2.3",
|
||||||
"@biomejs/cli-win32-arm64": "1.9.4",
|
"@biomejs/cli-win32-arm64": "2.2.3",
|
||||||
"@biomejs/cli-win32-x64": "1.9.4"
|
"@biomejs/cli-win32-x64": "2.2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/cli-darwin-arm64": {
|
"node_modules/@biomejs/cli-darwin-arm64": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.2.3.tgz",
|
||||||
"integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==",
|
"integrity": "sha512-OrqQVBpadB5eqzinXN4+Q6honBz+tTlKVCsbEuEpljK8ASSItzIRZUA02mTikl3H/1nO2BMPFiJ0nkEZNy3B1w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -597,9 +596,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/cli-darwin-x64": {
|
"node_modules/@biomejs/cli-darwin-x64": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.2.3.tgz",
|
||||||
"integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==",
|
"integrity": "sha512-OCdBpb1TmyfsTgBAM1kPMXyYKTohQ48WpiN9tkt9xvU6gKVKHY4oVwteBebiOqyfyzCNaSiuKIPjmHjUZ2ZNMg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -614,9 +613,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/cli-linux-arm64": {
|
"node_modules/@biomejs/cli-linux-arm64": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.2.3.tgz",
|
||||||
"integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==",
|
"integrity": "sha512-g/Uta2DqYpECxG+vUmTAmUKlVhnGEcY7DXWgKP8ruLRa8Si1QHsWknPY3B/wCo0KgYiFIOAZ9hjsHfNb9L85+g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -631,9 +630,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/cli-linux-arm64-musl": {
|
"node_modules/@biomejs/cli-linux-arm64-musl": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.2.3.tgz",
|
||||||
"integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==",
|
"integrity": "sha512-q3w9jJ6JFPZPeqyvwwPeaiS/6NEszZ+pXKF+IczNo8Xj6fsii45a4gEEicKyKIytalV+s829ACZujQlXAiVLBQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -648,9 +647,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/cli-linux-x64": {
|
"node_modules/@biomejs/cli-linux-x64": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.2.3.tgz",
|
||||||
"integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==",
|
"integrity": "sha512-LEtyYL1fJsvw35CxrbQ0gZoxOG3oZsAjzfRdvRBRHxOpQ91Q5doRVjvWW/wepgSdgk5hlaNzfeqpyGmfSD0Eyw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -665,9 +664,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/cli-linux-x64-musl": {
|
"node_modules/@biomejs/cli-linux-x64-musl": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.2.3.tgz",
|
||||||
"integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==",
|
"integrity": "sha512-y76Dn4vkP1sMRGPFlNc+OTETBhGPJ90jY3il6jAfur8XWrYBQV3swZ1Jo0R2g+JpOeeoA0cOwM7mJG6svDz79w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -682,9 +681,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/cli-win32-arm64": {
|
"node_modules/@biomejs/cli-win32-arm64": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.2.3.tgz",
|
||||||
"integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==",
|
"integrity": "sha512-Ms9zFYzjcJK7LV+AOMYnjN3pV3xL8Prxf9aWdDVL74onLn5kcvZ1ZMQswE5XHtnd/r/0bnUd928Rpbs14BzVmA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -699,9 +698,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@biomejs/cli-win32-x64": {
|
"node_modules/@biomejs/cli-win32-x64": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.2.3.tgz",
|
||||||
"integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==",
|
"integrity": "sha512-gvCpewE7mBwBIpqk1YrUqNR4mCiyJm6UI3YWQQXkedSSEwzRdodRpaKhbdbHw1/hmTWOVXQ+Eih5Qctf4TCVOQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -5973,74 +5972,74 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@biomejs/biome": {
|
"@biomejs/biome": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.2.3.tgz",
|
||||||
"integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==",
|
"integrity": "sha512-9w0uMTvPrIdvUrxazZ42Ib7t8Y2yoGLKLdNne93RLICmaHw7mcLv4PPb5LvZLJF3141gQHiCColOh/v6VWlWmg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@biomejs/cli-darwin-arm64": "1.9.4",
|
"@biomejs/cli-darwin-arm64": "2.2.3",
|
||||||
"@biomejs/cli-darwin-x64": "1.9.4",
|
"@biomejs/cli-darwin-x64": "2.2.3",
|
||||||
"@biomejs/cli-linux-arm64": "1.9.4",
|
"@biomejs/cli-linux-arm64": "2.2.3",
|
||||||
"@biomejs/cli-linux-arm64-musl": "1.9.4",
|
"@biomejs/cli-linux-arm64-musl": "2.2.3",
|
||||||
"@biomejs/cli-linux-x64": "1.9.4",
|
"@biomejs/cli-linux-x64": "2.2.3",
|
||||||
"@biomejs/cli-linux-x64-musl": "1.9.4",
|
"@biomejs/cli-linux-x64-musl": "2.2.3",
|
||||||
"@biomejs/cli-win32-arm64": "1.9.4",
|
"@biomejs/cli-win32-arm64": "2.2.3",
|
||||||
"@biomejs/cli-win32-x64": "1.9.4"
|
"@biomejs/cli-win32-x64": "2.2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@biomejs/cli-darwin-arm64": {
|
"@biomejs/cli-darwin-arm64": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.2.3.tgz",
|
||||||
"integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==",
|
"integrity": "sha512-OrqQVBpadB5eqzinXN4+Q6honBz+tTlKVCsbEuEpljK8ASSItzIRZUA02mTikl3H/1nO2BMPFiJ0nkEZNy3B1w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@biomejs/cli-darwin-x64": {
|
"@biomejs/cli-darwin-x64": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.2.3.tgz",
|
||||||
"integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==",
|
"integrity": "sha512-OCdBpb1TmyfsTgBAM1kPMXyYKTohQ48WpiN9tkt9xvU6gKVKHY4oVwteBebiOqyfyzCNaSiuKIPjmHjUZ2ZNMg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@biomejs/cli-linux-arm64": {
|
"@biomejs/cli-linux-arm64": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.2.3.tgz",
|
||||||
"integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==",
|
"integrity": "sha512-g/Uta2DqYpECxG+vUmTAmUKlVhnGEcY7DXWgKP8ruLRa8Si1QHsWknPY3B/wCo0KgYiFIOAZ9hjsHfNb9L85+g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@biomejs/cli-linux-arm64-musl": {
|
"@biomejs/cli-linux-arm64-musl": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.2.3.tgz",
|
||||||
"integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==",
|
"integrity": "sha512-q3w9jJ6JFPZPeqyvwwPeaiS/6NEszZ+pXKF+IczNo8Xj6fsii45a4gEEicKyKIytalV+s829ACZujQlXAiVLBQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@biomejs/cli-linux-x64": {
|
"@biomejs/cli-linux-x64": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.2.3.tgz",
|
||||||
"integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==",
|
"integrity": "sha512-LEtyYL1fJsvw35CxrbQ0gZoxOG3oZsAjzfRdvRBRHxOpQ91Q5doRVjvWW/wepgSdgk5hlaNzfeqpyGmfSD0Eyw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@biomejs/cli-linux-x64-musl": {
|
"@biomejs/cli-linux-x64-musl": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.2.3.tgz",
|
||||||
"integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==",
|
"integrity": "sha512-y76Dn4vkP1sMRGPFlNc+OTETBhGPJ90jY3il6jAfur8XWrYBQV3swZ1Jo0R2g+JpOeeoA0cOwM7mJG6svDz79w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@biomejs/cli-win32-arm64": {
|
"@biomejs/cli-win32-arm64": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.2.3.tgz",
|
||||||
"integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==",
|
"integrity": "sha512-Ms9zFYzjcJK7LV+AOMYnjN3pV3xL8Prxf9aWdDVL74onLn5kcvZ1ZMQswE5XHtnd/r/0bnUd928Rpbs14BzVmA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@biomejs/cli-win32-x64": {
|
"@biomejs/cli-win32-x64": {
|
||||||
"version": "1.9.4",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.2.3.tgz",
|
||||||
"integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==",
|
"integrity": "sha512-gvCpewE7mBwBIpqk1YrUqNR4mCiyJm6UI3YWQQXkedSSEwzRdodRpaKhbdbHw1/hmTWOVXQ+Eih5Qctf4TCVOQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "tsc -p tsconfig.build.json && vite build",
|
"build": "tsc -p tsconfig.build.json && vite build",
|
||||||
"lint": "biome check --apply-unsafe --no-errors-on-unmatched --files-ignore-unknown=true ./",
|
"lint": "biome check --write --unsafe --no-errors-on-unmatched --files-ignore-unknown=true ./",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"generate-client": "openapi-ts"
|
"generate-client": "openapi-ts"
|
||||||
},
|
},
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
"react-icons": "^5.5.0"
|
"react-icons": "^5.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "1.9.4",
|
"@biomejs/biome": "^2.2.3",
|
||||||
"@hey-api/openapi-ts": "0.73.0",
|
"@hey-api/openapi-ts": "0.73.0",
|
||||||
"@playwright/test": "^1.55.0",
|
"@playwright/test": "^1.55.0",
|
||||||
"@tanstack/router-devtools": "^1.131.36",
|
"@tanstack/router-devtools": "^1.131.36",
|
||||||
|
|||||||
@@ -1,25 +1,21 @@
|
|||||||
import type { ApiRequestOptions } from "./ApiRequestOptions"
|
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||||
import type { ApiResult } from "./ApiResult"
|
import type { ApiResult } from './ApiResult';
|
||||||
|
|
||||||
export class ApiError extends Error {
|
export class ApiError extends Error {
|
||||||
public readonly url: string
|
public readonly url: string;
|
||||||
public readonly status: number
|
public readonly status: number;
|
||||||
public readonly statusText: string
|
public readonly statusText: string;
|
||||||
public readonly body: unknown
|
public readonly body: unknown;
|
||||||
public readonly request: ApiRequestOptions
|
public readonly request: ApiRequestOptions;
|
||||||
|
|
||||||
constructor(
|
constructor(request: ApiRequestOptions, response: ApiResult, message: string) {
|
||||||
request: ApiRequestOptions,
|
super(message);
|
||||||
response: ApiResult,
|
|
||||||
message: string,
|
|
||||||
) {
|
|
||||||
super(message)
|
|
||||||
|
|
||||||
this.name = "ApiError"
|
this.name = 'ApiError';
|
||||||
this.url = response.url
|
this.url = response.url;
|
||||||
this.status = response.status
|
this.status = response.status;
|
||||||
this.statusText = response.statusText
|
this.statusText = response.statusText;
|
||||||
this.body = response.body
|
this.body = response.body;
|
||||||
this.request = request
|
this.request = request;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,21 @@
|
|||||||
export type ApiRequestOptions<T = unknown> = {
|
export type ApiRequestOptions<T = unknown> = {
|
||||||
readonly body?: any
|
readonly body?: any;
|
||||||
readonly cookies?: Record<string, unknown>
|
readonly cookies?: Record<string, unknown>;
|
||||||
readonly errors?: Record<number | string, string>
|
readonly errors?: Record<number | string, string>;
|
||||||
readonly formData?: Record<string, unknown> | any[] | Blob | File
|
readonly formData?: Record<string, unknown> | any[] | Blob | File;
|
||||||
readonly headers?: Record<string, unknown>
|
readonly headers?: Record<string, unknown>;
|
||||||
readonly mediaType?: string
|
readonly mediaType?: string;
|
||||||
readonly method:
|
readonly method:
|
||||||
| "DELETE"
|
| 'DELETE'
|
||||||
| "GET"
|
| 'GET'
|
||||||
| "HEAD"
|
| 'HEAD'
|
||||||
| "OPTIONS"
|
| 'OPTIONS'
|
||||||
| "PATCH"
|
| 'PATCH'
|
||||||
| "POST"
|
| 'POST'
|
||||||
| "PUT"
|
| 'PUT';
|
||||||
readonly path?: Record<string, unknown>
|
readonly path?: Record<string, unknown>;
|
||||||
readonly query?: Record<string, unknown>
|
readonly query?: Record<string, unknown>;
|
||||||
readonly responseHeader?: string
|
readonly responseHeader?: string;
|
||||||
readonly responseTransformer?: (data: unknown) => Promise<T>
|
readonly responseTransformer?: (data: unknown) => Promise<T>;
|
||||||
readonly url: string
|
readonly url: string;
|
||||||
}
|
};
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
export type ApiResult<TData = any> = {
|
export type ApiResult<TData = any> = {
|
||||||
readonly body: TData
|
readonly body: TData;
|
||||||
readonly ok: boolean
|
readonly ok: boolean;
|
||||||
readonly status: number
|
readonly status: number;
|
||||||
readonly statusText: string
|
readonly statusText: string;
|
||||||
readonly url: string
|
readonly url: string;
|
||||||
}
|
};
|
||||||
@@ -1,126 +1,126 @@
|
|||||||
export class CancelError extends Error {
|
export class CancelError extends Error {
|
||||||
constructor(message: string) {
|
constructor(message: string) {
|
||||||
super(message)
|
super(message);
|
||||||
this.name = "CancelError"
|
this.name = 'CancelError';
|
||||||
}
|
}
|
||||||
|
|
||||||
public get isCancelled(): boolean {
|
public get isCancelled(): boolean {
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OnCancel {
|
export interface OnCancel {
|
||||||
readonly isResolved: boolean
|
readonly isResolved: boolean;
|
||||||
readonly isRejected: boolean
|
readonly isRejected: boolean;
|
||||||
readonly isCancelled: boolean
|
readonly isCancelled: boolean;
|
||||||
|
|
||||||
(cancelHandler: () => void): void
|
(cancelHandler: () => void): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CancelablePromise<T> implements Promise<T> {
|
export class CancelablePromise<T> implements Promise<T> {
|
||||||
private _isResolved: boolean
|
private _isResolved: boolean;
|
||||||
private _isRejected: boolean
|
private _isRejected: boolean;
|
||||||
private _isCancelled: boolean
|
private _isCancelled: boolean;
|
||||||
readonly cancelHandlers: (() => void)[]
|
readonly cancelHandlers: (() => void)[];
|
||||||
readonly promise: Promise<T>
|
readonly promise: Promise<T>;
|
||||||
private _resolve?: (value: T | PromiseLike<T>) => void
|
private _resolve?: (value: T | PromiseLike<T>) => void;
|
||||||
private _reject?: (reason?: unknown) => void
|
private _reject?: (reason?: unknown) => void;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
executor: (
|
executor: (
|
||||||
resolve: (value: T | PromiseLike<T>) => void,
|
resolve: (value: T | PromiseLike<T>) => void,
|
||||||
reject: (reason?: unknown) => void,
|
reject: (reason?: unknown) => void,
|
||||||
onCancel: OnCancel,
|
onCancel: OnCancel
|
||||||
) => void,
|
) => void
|
||||||
) {
|
) {
|
||||||
this._isResolved = false
|
this._isResolved = false;
|
||||||
this._isRejected = false
|
this._isRejected = false;
|
||||||
this._isCancelled = false
|
this._isCancelled = false;
|
||||||
this.cancelHandlers = []
|
this.cancelHandlers = [];
|
||||||
this.promise = new Promise<T>((resolve, reject) => {
|
this.promise = new Promise<T>((resolve, reject) => {
|
||||||
this._resolve = resolve
|
this._resolve = resolve;
|
||||||
this._reject = reject
|
this._reject = reject;
|
||||||
|
|
||||||
const onResolve = (value: T | PromiseLike<T>): void => {
|
const onResolve = (value: T | PromiseLike<T>): void => {
|
||||||
if (this._isResolved || this._isRejected || this._isCancelled) {
|
if (this._isResolved || this._isRejected || this._isCancelled) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this._isResolved = true
|
this._isResolved = true;
|
||||||
if (this._resolve) this._resolve(value)
|
if (this._resolve) this._resolve(value);
|
||||||
}
|
};
|
||||||
|
|
||||||
const onReject = (reason?: unknown): void => {
|
const onReject = (reason?: unknown): void => {
|
||||||
if (this._isResolved || this._isRejected || this._isCancelled) {
|
if (this._isResolved || this._isRejected || this._isCancelled) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this._isRejected = true
|
this._isRejected = true;
|
||||||
if (this._reject) this._reject(reason)
|
if (this._reject) this._reject(reason);
|
||||||
}
|
};
|
||||||
|
|
||||||
const onCancel = (cancelHandler: () => void): void => {
|
const onCancel = (cancelHandler: () => void): void => {
|
||||||
if (this._isResolved || this._isRejected || this._isCancelled) {
|
if (this._isResolved || this._isRejected || this._isCancelled) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this.cancelHandlers.push(cancelHandler)
|
this.cancelHandlers.push(cancelHandler);
|
||||||
}
|
};
|
||||||
|
|
||||||
Object.defineProperty(onCancel, "isResolved", {
|
Object.defineProperty(onCancel, 'isResolved', {
|
||||||
get: (): boolean => this._isResolved,
|
get: (): boolean => this._isResolved,
|
||||||
})
|
});
|
||||||
|
|
||||||
Object.defineProperty(onCancel, "isRejected", {
|
Object.defineProperty(onCancel, 'isRejected', {
|
||||||
get: (): boolean => this._isRejected,
|
get: (): boolean => this._isRejected,
|
||||||
})
|
});
|
||||||
|
|
||||||
Object.defineProperty(onCancel, "isCancelled", {
|
Object.defineProperty(onCancel, 'isCancelled', {
|
||||||
get: (): boolean => this._isCancelled,
|
get: (): boolean => this._isCancelled,
|
||||||
})
|
});
|
||||||
|
|
||||||
return executor(onResolve, onReject, onCancel as OnCancel)
|
return executor(onResolve, onReject, onCancel as OnCancel);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get [Symbol.toStringTag]() {
|
get [Symbol.toStringTag]() {
|
||||||
return "Cancellable Promise"
|
return "Cancellable Promise";
|
||||||
}
|
}
|
||||||
|
|
||||||
public then<TResult1 = T, TResult2 = never>(
|
public then<TResult1 = T, TResult2 = never>(
|
||||||
onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
|
onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
|
||||||
onRejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,
|
onRejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null
|
||||||
): Promise<TResult1 | TResult2> {
|
): Promise<TResult1 | TResult2> {
|
||||||
return this.promise.then(onFulfilled, onRejected)
|
return this.promise.then(onFulfilled, onRejected);
|
||||||
}
|
}
|
||||||
|
|
||||||
public catch<TResult = never>(
|
public catch<TResult = never>(
|
||||||
onRejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null,
|
onRejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null
|
||||||
): Promise<T | TResult> {
|
): Promise<T | TResult> {
|
||||||
return this.promise.catch(onRejected)
|
return this.promise.catch(onRejected);
|
||||||
}
|
}
|
||||||
|
|
||||||
public finally(onFinally?: (() => void) | null): Promise<T> {
|
public finally(onFinally?: (() => void) | null): Promise<T> {
|
||||||
return this.promise.finally(onFinally)
|
return this.promise.finally(onFinally);
|
||||||
}
|
}
|
||||||
|
|
||||||
public cancel(): void {
|
public cancel(): void {
|
||||||
if (this._isResolved || this._isRejected || this._isCancelled) {
|
if (this._isResolved || this._isRejected || this._isCancelled) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
this._isCancelled = true
|
this._isCancelled = true;
|
||||||
if (this.cancelHandlers.length) {
|
if (this.cancelHandlers.length) {
|
||||||
try {
|
try {
|
||||||
for (const cancelHandler of this.cancelHandlers) {
|
for (const cancelHandler of this.cancelHandlers) {
|
||||||
cancelHandler()
|
cancelHandler();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn("Cancellation threw an error", error)
|
console.warn('Cancellation threw an error', error);
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.cancelHandlers.length = 0
|
this.cancelHandlers.length = 0;
|
||||||
if (this._reject) this._reject(new CancelError("Request aborted"))
|
if (this._reject) this._reject(new CancelError('Request aborted'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public get isCancelled(): boolean {
|
public get isCancelled(): boolean {
|
||||||
return this._isCancelled
|
return this._isCancelled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,57 +1,57 @@
|
|||||||
import type { AxiosRequestConfig, AxiosResponse } from "axios"
|
import type { AxiosRequestConfig, AxiosResponse } from 'axios';
|
||||||
import type { ApiRequestOptions } from "./ApiRequestOptions"
|
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||||
|
|
||||||
type Headers = Record<string, string>
|
type Headers = Record<string, string>;
|
||||||
type Middleware<T> = (value: T) => T | Promise<T>
|
type Middleware<T> = (value: T) => T | Promise<T>;
|
||||||
type Resolver<T> = (options: ApiRequestOptions<T>) => Promise<T>
|
type Resolver<T> = (options: ApiRequestOptions<T>) => Promise<T>;
|
||||||
|
|
||||||
export class Interceptors<T> {
|
export class Interceptors<T> {
|
||||||
_fns: Middleware<T>[]
|
_fns: Middleware<T>[];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this._fns = []
|
this._fns = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
eject(fn: Middleware<T>): void {
|
eject(fn: Middleware<T>): void {
|
||||||
const index = this._fns.indexOf(fn)
|
const index = this._fns.indexOf(fn);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
this._fns = [...this._fns.slice(0, index), ...this._fns.slice(index + 1)]
|
this._fns = [...this._fns.slice(0, index), ...this._fns.slice(index + 1)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use(fn: Middleware<T>): void {
|
use(fn: Middleware<T>): void {
|
||||||
this._fns = [...this._fns, fn]
|
this._fns = [...this._fns, fn];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type OpenAPIConfig = {
|
export type OpenAPIConfig = {
|
||||||
BASE: string
|
BASE: string;
|
||||||
CREDENTIALS: "include" | "omit" | "same-origin"
|
CREDENTIALS: 'include' | 'omit' | 'same-origin';
|
||||||
ENCODE_PATH?: ((path: string) => string) | undefined
|
ENCODE_PATH?: ((path: string) => string) | undefined;
|
||||||
HEADERS?: Headers | Resolver<Headers> | undefined
|
HEADERS?: Headers | Resolver<Headers> | undefined;
|
||||||
PASSWORD?: string | Resolver<string> | undefined
|
PASSWORD?: string | Resolver<string> | undefined;
|
||||||
TOKEN?: string | Resolver<string> | undefined
|
TOKEN?: string | Resolver<string> | undefined;
|
||||||
USERNAME?: string | Resolver<string> | undefined
|
USERNAME?: string | Resolver<string> | undefined;
|
||||||
VERSION: string
|
VERSION: string;
|
||||||
WITH_CREDENTIALS: boolean
|
WITH_CREDENTIALS: boolean;
|
||||||
interceptors: {
|
interceptors: {
|
||||||
request: Interceptors<AxiosRequestConfig>
|
request: Interceptors<AxiosRequestConfig>;
|
||||||
response: Interceptors<AxiosResponse>
|
response: Interceptors<AxiosResponse>;
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
export const OpenAPI: OpenAPIConfig = {
|
export const OpenAPI: OpenAPIConfig = {
|
||||||
BASE: "",
|
BASE: '',
|
||||||
CREDENTIALS: "include",
|
CREDENTIALS: 'include',
|
||||||
ENCODE_PATH: undefined,
|
ENCODE_PATH: undefined,
|
||||||
HEADERS: undefined,
|
HEADERS: undefined,
|
||||||
PASSWORD: undefined,
|
PASSWORD: undefined,
|
||||||
TOKEN: undefined,
|
TOKEN: undefined,
|
||||||
USERNAME: undefined,
|
USERNAME: undefined,
|
||||||
VERSION: "0.1.0",
|
VERSION: '0.1.0',
|
||||||
WITH_CREDENTIALS: false,
|
WITH_CREDENTIALS: false,
|
||||||
interceptors: {
|
interceptors: {
|
||||||
request: new Interceptors(),
|
request: new Interceptors(),
|
||||||
response: new Interceptors(),
|
response: new Interceptors(),
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
@@ -1,325 +1,301 @@
|
|||||||
import axios from "axios"
|
import axios from 'axios';
|
||||||
import type {
|
import type { AxiosError, AxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios';
|
||||||
AxiosError,
|
|
||||||
AxiosRequestConfig,
|
|
||||||
AxiosResponse,
|
|
||||||
AxiosInstance,
|
|
||||||
} from "axios"
|
|
||||||
|
|
||||||
import { ApiError } from "./ApiError"
|
import { ApiError } from './ApiError';
|
||||||
import type { ApiRequestOptions } from "./ApiRequestOptions"
|
import type { ApiRequestOptions } from './ApiRequestOptions';
|
||||||
import type { ApiResult } from "./ApiResult"
|
import type { ApiResult } from './ApiResult';
|
||||||
import { CancelablePromise } from "./CancelablePromise"
|
import { CancelablePromise } from './CancelablePromise';
|
||||||
import type { OnCancel } from "./CancelablePromise"
|
import type { OnCancel } from './CancelablePromise';
|
||||||
import type { OpenAPIConfig } from "./OpenAPI"
|
import type { OpenAPIConfig } from './OpenAPI';
|
||||||
|
|
||||||
export const isString = (value: unknown): value is string => {
|
export const isString = (value: unknown): value is string => {
|
||||||
return typeof value === "string"
|
return typeof value === 'string';
|
||||||
}
|
};
|
||||||
|
|
||||||
export const isStringWithValue = (value: unknown): value is string => {
|
export const isStringWithValue = (value: unknown): value is string => {
|
||||||
return isString(value) && value !== ""
|
return isString(value) && value !== '';
|
||||||
}
|
};
|
||||||
|
|
||||||
export const isBlob = (value: any): value is Blob => {
|
export const isBlob = (value: any): value is Blob => {
|
||||||
return value instanceof Blob
|
return value instanceof Blob;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const isFormData = (value: unknown): value is FormData => {
|
export const isFormData = (value: unknown): value is FormData => {
|
||||||
return value instanceof FormData
|
return value instanceof FormData;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const isSuccess = (status: number): boolean => {
|
export const isSuccess = (status: number): boolean => {
|
||||||
return status >= 200 && status < 300
|
return status >= 200 && status < 300;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const base64 = (str: string): string => {
|
export const base64 = (str: string): string => {
|
||||||
try {
|
try {
|
||||||
return btoa(str)
|
return btoa(str);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return Buffer.from(str).toString("base64")
|
return Buffer.from(str).toString('base64');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getQueryString = (params: Record<string, unknown>): string => {
|
export const getQueryString = (params: Record<string, unknown>): string => {
|
||||||
const qs: string[] = []
|
const qs: string[] = [];
|
||||||
|
|
||||||
const append = (key: string, value: unknown) => {
|
const append = (key: string, value: unknown) => {
|
||||||
qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)
|
qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
|
||||||
}
|
};
|
||||||
|
|
||||||
const encodePair = (key: string, value: unknown) => {
|
const encodePair = (key: string, value: unknown) => {
|
||||||
if (value === undefined || value === null) {
|
if (value === undefined || value === null) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value instanceof Date) {
|
if (value instanceof Date) {
|
||||||
append(key, value.toISOString())
|
append(key, value.toISOString());
|
||||||
} else if (Array.isArray(value)) {
|
} else if (Array.isArray(value)) {
|
||||||
value.forEach((v) => encodePair(key, v))
|
value.forEach(v => encodePair(key, v));
|
||||||
} else if (typeof value === "object") {
|
} else if (typeof value === 'object') {
|
||||||
Object.entries(value).forEach(([k, v]) => encodePair(`${key}[${k}]`, v))
|
Object.entries(value).forEach(([k, v]) => encodePair(`${key}[${k}]`, v));
|
||||||
} else {
|
} else {
|
||||||
append(key, value)
|
append(key, value);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Object.entries(params).forEach(([key, value]) => encodePair(key, value))
|
Object.entries(params).forEach(([key, value]) => encodePair(key, value));
|
||||||
|
|
||||||
return qs.length ? `?${qs.join("&")}` : ""
|
return qs.length ? `?${qs.join('&')}` : '';
|
||||||
}
|
};
|
||||||
|
|
||||||
const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => {
|
const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => {
|
||||||
const encoder = config.ENCODE_PATH || encodeURI
|
const encoder = config.ENCODE_PATH || encodeURI;
|
||||||
|
|
||||||
const path = options.url
|
const path = options.url
|
||||||
.replace("{api-version}", config.VERSION)
|
.replace('{api-version}', config.VERSION)
|
||||||
.replace(/{(.*?)}/g, (substring: string, group: string) => {
|
.replace(/{(.*?)}/g, (substring: string, group: string) => {
|
||||||
if (options.path?.hasOwnProperty(group)) {
|
if (options.path?.hasOwnProperty(group)) {
|
||||||
return encoder(String(options.path[group]))
|
return encoder(String(options.path[group]));
|
||||||
}
|
}
|
||||||
return substring
|
return substring;
|
||||||
})
|
});
|
||||||
|
|
||||||
const url = config.BASE + path
|
const url = config.BASE + path;
|
||||||
return options.query ? url + getQueryString(options.query) : url
|
return options.query ? url + getQueryString(options.query) : url;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getFormData = (
|
export const getFormData = (options: ApiRequestOptions): FormData | undefined => {
|
||||||
options: ApiRequestOptions,
|
if (options.formData) {
|
||||||
): FormData | undefined => {
|
const formData = new FormData();
|
||||||
if (options.formData) {
|
|
||||||
const formData = new FormData()
|
|
||||||
|
|
||||||
const process = (key: string, value: unknown) => {
|
const process = (key: string, value: unknown) => {
|
||||||
if (isString(value) || isBlob(value)) {
|
if (isString(value) || isBlob(value)) {
|
||||||
formData.append(key, value)
|
formData.append(key, value);
|
||||||
} else {
|
} else {
|
||||||
formData.append(key, JSON.stringify(value))
|
formData.append(key, JSON.stringify(value));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Object.entries(options.formData)
|
Object.entries(options.formData)
|
||||||
.filter(([, value]) => value !== undefined && value !== null)
|
.filter(([, value]) => value !== undefined && value !== null)
|
||||||
.forEach(([key, value]) => {
|
.forEach(([key, value]) => {
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
value.forEach((v) => process(key, v))
|
value.forEach(v => process(key, v));
|
||||||
} else {
|
} else {
|
||||||
process(key, value)
|
process(key, value);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
return formData
|
return formData;
|
||||||
}
|
}
|
||||||
return undefined
|
return undefined;
|
||||||
}
|
};
|
||||||
|
|
||||||
type Resolver<T> = (options: ApiRequestOptions<T>) => Promise<T>
|
type Resolver<T> = (options: ApiRequestOptions<T>) => Promise<T>;
|
||||||
|
|
||||||
export const resolve = async <T>(
|
export const resolve = async <T>(options: ApiRequestOptions<T>, resolver?: T | Resolver<T>): Promise<T | undefined> => {
|
||||||
options: ApiRequestOptions<T>,
|
if (typeof resolver === 'function') {
|
||||||
resolver?: T | Resolver<T>,
|
return (resolver as Resolver<T>)(options);
|
||||||
): Promise<T | undefined> => {
|
}
|
||||||
if (typeof resolver === "function") {
|
return resolver;
|
||||||
return (resolver as Resolver<T>)(options)
|
};
|
||||||
}
|
|
||||||
return resolver
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getHeaders = async <T>(
|
export const getHeaders = async <T>(config: OpenAPIConfig, options: ApiRequestOptions<T>): Promise<Record<string, string>> => {
|
||||||
config: OpenAPIConfig,
|
const [token, username, password, additionalHeaders] = await Promise.all([
|
||||||
options: ApiRequestOptions<T>,
|
// @ts-ignore
|
||||||
): Promise<Record<string, string>> => {
|
resolve(options, config.TOKEN),
|
||||||
const [token, username, password, additionalHeaders] = await Promise.all([
|
// @ts-ignore
|
||||||
// @ts-ignore
|
resolve(options, config.USERNAME),
|
||||||
resolve(options, config.TOKEN),
|
// @ts-ignore
|
||||||
// @ts-ignore
|
resolve(options, config.PASSWORD),
|
||||||
resolve(options, config.USERNAME),
|
// @ts-ignore
|
||||||
// @ts-ignore
|
resolve(options, config.HEADERS),
|
||||||
resolve(options, config.PASSWORD),
|
]);
|
||||||
// @ts-ignore
|
|
||||||
resolve(options, config.HEADERS),
|
|
||||||
])
|
|
||||||
|
|
||||||
const headers = Object.entries({
|
const headers = Object.entries({
|
||||||
Accept: "application/json",
|
Accept: 'application/json',
|
||||||
...additionalHeaders,
|
...additionalHeaders,
|
||||||
...options.headers,
|
...options.headers,
|
||||||
})
|
})
|
||||||
.filter(([, value]) => value !== undefined && value !== null)
|
.filter(([, value]) => value !== undefined && value !== null)
|
||||||
.reduce(
|
.reduce((headers, [key, value]) => ({
|
||||||
(headers, [key, value]) => ({
|
...headers,
|
||||||
...headers,
|
[key]: String(value),
|
||||||
[key]: String(value),
|
}), {} as Record<string, string>);
|
||||||
}),
|
|
||||||
{} as Record<string, string>,
|
|
||||||
)
|
|
||||||
|
|
||||||
if (isStringWithValue(token)) {
|
if (isStringWithValue(token)) {
|
||||||
headers["Authorization"] = `Bearer ${token}`
|
headers['Authorization'] = `Bearer ${token}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isStringWithValue(username) && isStringWithValue(password)) {
|
if (isStringWithValue(username) && isStringWithValue(password)) {
|
||||||
const credentials = base64(`${username}:${password}`)
|
const credentials = base64(`${username}:${password}`);
|
||||||
headers["Authorization"] = `Basic ${credentials}`
|
headers['Authorization'] = `Basic ${credentials}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.body !== undefined) {
|
if (options.body !== undefined) {
|
||||||
if (options.mediaType) {
|
if (options.mediaType) {
|
||||||
headers["Content-Type"] = options.mediaType
|
headers['Content-Type'] = options.mediaType;
|
||||||
} else if (isBlob(options.body)) {
|
} else if (isBlob(options.body)) {
|
||||||
headers["Content-Type"] = options.body.type || "application/octet-stream"
|
headers['Content-Type'] = options.body.type || 'application/octet-stream';
|
||||||
} else if (isString(options.body)) {
|
} else if (isString(options.body)) {
|
||||||
headers["Content-Type"] = "text/plain"
|
headers['Content-Type'] = 'text/plain';
|
||||||
} else if (!isFormData(options.body)) {
|
} else if (!isFormData(options.body)) {
|
||||||
headers["Content-Type"] = "application/json"
|
headers['Content-Type'] = 'application/json';
|
||||||
}
|
}
|
||||||
} else if (options.formData !== undefined) {
|
} else if (options.formData !== undefined) {
|
||||||
if (options.mediaType) {
|
if (options.mediaType) {
|
||||||
headers["Content-Type"] = options.mediaType
|
headers['Content-Type'] = options.mediaType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return headers
|
return headers;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getRequestBody = (options: ApiRequestOptions): unknown => {
|
export const getRequestBody = (options: ApiRequestOptions): unknown => {
|
||||||
if (options.body) {
|
if (options.body) {
|
||||||
return options.body
|
return options.body;
|
||||||
}
|
}
|
||||||
return undefined
|
return undefined;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const sendRequest = async <T>(
|
export const sendRequest = async <T>(
|
||||||
config: OpenAPIConfig,
|
config: OpenAPIConfig,
|
||||||
options: ApiRequestOptions<T>,
|
options: ApiRequestOptions<T>,
|
||||||
url: string,
|
url: string,
|
||||||
body: unknown,
|
body: unknown,
|
||||||
formData: FormData | undefined,
|
formData: FormData | undefined,
|
||||||
headers: Record<string, string>,
|
headers: Record<string, string>,
|
||||||
onCancel: OnCancel,
|
onCancel: OnCancel,
|
||||||
axiosClient: AxiosInstance,
|
axiosClient: AxiosInstance
|
||||||
): Promise<AxiosResponse<T>> => {
|
): Promise<AxiosResponse<T>> => {
|
||||||
const controller = new AbortController()
|
const controller = new AbortController();
|
||||||
|
|
||||||
let requestConfig: AxiosRequestConfig = {
|
let requestConfig: AxiosRequestConfig = {
|
||||||
data: body ?? formData,
|
data: body ?? formData,
|
||||||
headers,
|
headers,
|
||||||
method: options.method,
|
method: options.method,
|
||||||
signal: controller.signal,
|
signal: controller.signal,
|
||||||
url,
|
url,
|
||||||
withCredentials: config.WITH_CREDENTIALS,
|
withCredentials: config.WITH_CREDENTIALS,
|
||||||
}
|
};
|
||||||
|
|
||||||
onCancel(() => controller.abort())
|
onCancel(() => controller.abort());
|
||||||
|
|
||||||
for (const fn of config.interceptors.request._fns) {
|
for (const fn of config.interceptors.request._fns) {
|
||||||
requestConfig = await fn(requestConfig)
|
requestConfig = await fn(requestConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await axiosClient.request(requestConfig)
|
return await axiosClient.request(requestConfig);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const axiosError = error as AxiosError<T>
|
const axiosError = error as AxiosError<T>;
|
||||||
if (axiosError.response) {
|
if (axiosError.response) {
|
||||||
return axiosError.response
|
return axiosError.response;
|
||||||
}
|
}
|
||||||
throw error
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getResponseHeader = (
|
export const getResponseHeader = (response: AxiosResponse<unknown>, responseHeader?: string): string | undefined => {
|
||||||
response: AxiosResponse<unknown>,
|
if (responseHeader) {
|
||||||
responseHeader?: string,
|
const content = response.headers[responseHeader];
|
||||||
): string | undefined => {
|
if (isString(content)) {
|
||||||
if (responseHeader) {
|
return content;
|
||||||
const content = response.headers[responseHeader]
|
}
|
||||||
if (isString(content)) {
|
}
|
||||||
return content
|
return undefined;
|
||||||
}
|
};
|
||||||
}
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getResponseBody = (response: AxiosResponse<unknown>): unknown => {
|
export const getResponseBody = (response: AxiosResponse<unknown>): unknown => {
|
||||||
if (response.status !== 204) {
|
if (response.status !== 204) {
|
||||||
return response.data
|
return response.data;
|
||||||
}
|
}
|
||||||
return undefined
|
return undefined;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const catchErrorCodes = (
|
export const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => {
|
||||||
options: ApiRequestOptions,
|
const errors: Record<number, string> = {
|
||||||
result: ApiResult,
|
400: 'Bad Request',
|
||||||
): void => {
|
401: 'Unauthorized',
|
||||||
const errors: Record<number, string> = {
|
402: 'Payment Required',
|
||||||
400: "Bad Request",
|
403: 'Forbidden',
|
||||||
401: "Unauthorized",
|
404: 'Not Found',
|
||||||
402: "Payment Required",
|
405: 'Method Not Allowed',
|
||||||
403: "Forbidden",
|
406: 'Not Acceptable',
|
||||||
404: "Not Found",
|
407: 'Proxy Authentication Required',
|
||||||
405: "Method Not Allowed",
|
408: 'Request Timeout',
|
||||||
406: "Not Acceptable",
|
409: 'Conflict',
|
||||||
407: "Proxy Authentication Required",
|
410: 'Gone',
|
||||||
408: "Request Timeout",
|
411: 'Length Required',
|
||||||
409: "Conflict",
|
412: 'Precondition Failed',
|
||||||
410: "Gone",
|
413: 'Payload Too Large',
|
||||||
411: "Length Required",
|
414: 'URI Too Long',
|
||||||
412: "Precondition Failed",
|
415: 'Unsupported Media Type',
|
||||||
413: "Payload Too Large",
|
416: 'Range Not Satisfiable',
|
||||||
414: "URI Too Long",
|
417: 'Expectation Failed',
|
||||||
415: "Unsupported Media Type",
|
418: 'Im a teapot',
|
||||||
416: "Range Not Satisfiable",
|
421: 'Misdirected Request',
|
||||||
417: "Expectation Failed",
|
422: 'Unprocessable Content',
|
||||||
418: "Im a teapot",
|
423: 'Locked',
|
||||||
421: "Misdirected Request",
|
424: 'Failed Dependency',
|
||||||
422: "Unprocessable Content",
|
425: 'Too Early',
|
||||||
423: "Locked",
|
426: 'Upgrade Required',
|
||||||
424: "Failed Dependency",
|
428: 'Precondition Required',
|
||||||
425: "Too Early",
|
429: 'Too Many Requests',
|
||||||
426: "Upgrade Required",
|
431: 'Request Header Fields Too Large',
|
||||||
428: "Precondition Required",
|
451: 'Unavailable For Legal Reasons',
|
||||||
429: "Too Many Requests",
|
500: 'Internal Server Error',
|
||||||
431: "Request Header Fields Too Large",
|
501: 'Not Implemented',
|
||||||
451: "Unavailable For Legal Reasons",
|
502: 'Bad Gateway',
|
||||||
500: "Internal Server Error",
|
503: 'Service Unavailable',
|
||||||
501: "Not Implemented",
|
504: 'Gateway Timeout',
|
||||||
502: "Bad Gateway",
|
505: 'HTTP Version Not Supported',
|
||||||
503: "Service Unavailable",
|
506: 'Variant Also Negotiates',
|
||||||
504: "Gateway Timeout",
|
507: 'Insufficient Storage',
|
||||||
505: "HTTP Version Not Supported",
|
508: 'Loop Detected',
|
||||||
506: "Variant Also Negotiates",
|
510: 'Not Extended',
|
||||||
507: "Insufficient Storage",
|
511: 'Network Authentication Required',
|
||||||
508: "Loop Detected",
|
...options.errors,
|
||||||
510: "Not Extended",
|
}
|
||||||
511: "Network Authentication Required",
|
|
||||||
...options.errors,
|
|
||||||
}
|
|
||||||
|
|
||||||
const error = errors[result.status]
|
const error = errors[result.status];
|
||||||
if (error) {
|
if (error) {
|
||||||
throw new ApiError(options, result, error)
|
throw new ApiError(options, result, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result.ok) {
|
if (!result.ok) {
|
||||||
const errorStatus = result.status ?? "unknown"
|
const errorStatus = result.status ?? 'unknown';
|
||||||
const errorStatusText = result.statusText ?? "unknown"
|
const errorStatusText = result.statusText ?? 'unknown';
|
||||||
const errorBody = (() => {
|
const errorBody = (() => {
|
||||||
try {
|
try {
|
||||||
return JSON.stringify(result.body, null, 2)
|
return JSON.stringify(result.body, null, 2);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return undefined
|
return undefined;
|
||||||
}
|
}
|
||||||
})()
|
})();
|
||||||
|
|
||||||
throw new ApiError(
|
throw new ApiError(options, result,
|
||||||
options,
|
`Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`
|
||||||
result,
|
);
|
||||||
`Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`,
|
}
|
||||||
)
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request method
|
* Request method
|
||||||
@@ -329,59 +305,43 @@ export const catchErrorCodes = (
|
|||||||
* @returns CancelablePromise<T>
|
* @returns CancelablePromise<T>
|
||||||
* @throws ApiError
|
* @throws ApiError
|
||||||
*/
|
*/
|
||||||
export const request = <T>(
|
export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions<T>, axiosClient: AxiosInstance = axios): CancelablePromise<T> => {
|
||||||
config: OpenAPIConfig,
|
return new CancelablePromise(async (resolve, reject, onCancel) => {
|
||||||
options: ApiRequestOptions<T>,
|
try {
|
||||||
axiosClient: AxiosInstance = axios,
|
const url = getUrl(config, options);
|
||||||
): CancelablePromise<T> => {
|
const formData = getFormData(options);
|
||||||
return new CancelablePromise(async (resolve, reject, onCancel) => {
|
const body = getRequestBody(options);
|
||||||
try {
|
const headers = await getHeaders(config, options);
|
||||||
const url = getUrl(config, options)
|
|
||||||
const formData = getFormData(options)
|
|
||||||
const body = getRequestBody(options)
|
|
||||||
const headers = await getHeaders(config, options)
|
|
||||||
|
|
||||||
if (!onCancel.isCancelled) {
|
if (!onCancel.isCancelled) {
|
||||||
let response = await sendRequest<T>(
|
let response = await sendRequest<T>(config, options, url, body, formData, headers, onCancel, axiosClient);
|
||||||
config,
|
|
||||||
options,
|
|
||||||
url,
|
|
||||||
body,
|
|
||||||
formData,
|
|
||||||
headers,
|
|
||||||
onCancel,
|
|
||||||
axiosClient,
|
|
||||||
)
|
|
||||||
|
|
||||||
for (const fn of config.interceptors.response._fns) {
|
for (const fn of config.interceptors.response._fns) {
|
||||||
response = await fn(response)
|
response = await fn(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
const responseBody = getResponseBody(response)
|
const responseBody = getResponseBody(response);
|
||||||
const responseHeader = getResponseHeader(
|
const responseHeader = getResponseHeader(response, options.responseHeader);
|
||||||
response,
|
|
||||||
options.responseHeader,
|
|
||||||
)
|
|
||||||
|
|
||||||
let transformedBody = responseBody
|
let transformedBody = responseBody;
|
||||||
if (options.responseTransformer && isSuccess(response.status)) {
|
if (options.responseTransformer && isSuccess(response.status)) {
|
||||||
transformedBody = await options.responseTransformer(responseBody)
|
transformedBody = await options.responseTransformer(responseBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
const result: ApiResult = {
|
const result: ApiResult = {
|
||||||
url,
|
url,
|
||||||
ok: isSuccess(response.status),
|
ok: isSuccess(response.status),
|
||||||
status: response.status,
|
status: response.status,
|
||||||
statusText: response.statusText,
|
statusText: response.statusText,
|
||||||
body: responseHeader ?? transformedBody,
|
body: responseHeader ?? transformedBody,
|
||||||
}
|
};
|
||||||
|
|
||||||
catchErrorCodes(options, result)
|
catchErrorCodes(options, result);
|
||||||
|
|
||||||
resolve(result.body)
|
resolve(result.body);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
reject(error)
|
reject(error);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
// This file is auto-generated by @hey-api/openapi-ts
|
// This file is auto-generated by @hey-api/openapi-ts
|
||||||
export { ApiError } from "./core/ApiError"
|
export { ApiError } from './core/ApiError';
|
||||||
export { CancelablePromise, CancelError } from "./core/CancelablePromise"
|
export { CancelablePromise, CancelError } from './core/CancelablePromise';
|
||||||
export { OpenAPI, type OpenAPIConfig } from "./core/OpenAPI"
|
export { OpenAPI, type OpenAPIConfig } from './core/OpenAPI';
|
||||||
export * from "./sdk.gen"
|
export * from './sdk.gen';
|
||||||
export * from "./types.gen"
|
export * from './types.gen';
|
||||||
@@ -1,526 +1,526 @@
|
|||||||
// This file is auto-generated by @hey-api/openapi-ts
|
// This file is auto-generated by @hey-api/openapi-ts
|
||||||
|
|
||||||
export const Body_login_login_access_tokenSchema = {
|
export const Body_login_login_access_tokenSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
grant_type: {
|
grant_type: {
|
||||||
anyOf: [
|
anyOf: [
|
||||||
{
|
{
|
||||||
type: "string",
|
type: 'string',
|
||||||
pattern: "password",
|
pattern: 'password'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'null'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: 'Grant Type'
|
||||||
},
|
},
|
||||||
{
|
username: {
|
||||||
type: "null",
|
type: 'string',
|
||||||
|
title: 'Username'
|
||||||
},
|
},
|
||||||
],
|
password: {
|
||||||
title: "Grant Type",
|
type: 'string',
|
||||||
},
|
title: 'Password'
|
||||||
username: {
|
|
||||||
type: "string",
|
|
||||||
title: "Username",
|
|
||||||
},
|
|
||||||
password: {
|
|
||||||
type: "string",
|
|
||||||
title: "Password",
|
|
||||||
},
|
|
||||||
scope: {
|
|
||||||
type: "string",
|
|
||||||
title: "Scope",
|
|
||||||
default: "",
|
|
||||||
},
|
|
||||||
client_id: {
|
|
||||||
anyOf: [
|
|
||||||
{
|
|
||||||
type: "string",
|
|
||||||
},
|
},
|
||||||
{
|
scope: {
|
||||||
type: "null",
|
type: 'string',
|
||||||
|
title: 'Scope',
|
||||||
|
default: ''
|
||||||
},
|
},
|
||||||
],
|
client_id: {
|
||||||
title: "Client Id",
|
anyOf: [
|
||||||
|
{
|
||||||
|
type: 'string'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'null'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: 'Client Id'
|
||||||
|
},
|
||||||
|
client_secret: {
|
||||||
|
anyOf: [
|
||||||
|
{
|
||||||
|
type: 'string'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'null'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: 'Client Secret'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
client_secret: {
|
type: 'object',
|
||||||
anyOf: [
|
required: ['username', 'password'],
|
||||||
{
|
title: 'Body_login-login_access_token'
|
||||||
type: "string",
|
} as const;
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "null",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
title: "Client Secret",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "object",
|
|
||||||
required: ["username", "password"],
|
|
||||||
title: "Body_login-login_access_token",
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export const HTTPValidationErrorSchema = {
|
export const HTTPValidationErrorSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
detail: {
|
detail: {
|
||||||
items: {
|
items: {
|
||||||
$ref: "#/components/schemas/ValidationError",
|
'$ref': '#/components/schemas/ValidationError'
|
||||||
},
|
},
|
||||||
type: "array",
|
type: 'array',
|
||||||
title: "Detail",
|
title: 'Detail'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
type: 'object',
|
||||||
type: "object",
|
title: 'HTTPValidationError'
|
||||||
title: "HTTPValidationError",
|
} as const;
|
||||||
} as const
|
|
||||||
|
|
||||||
export const ItemCreateSchema = {
|
export const ItemCreateSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
title: {
|
title: {
|
||||||
type: "string",
|
type: 'string',
|
||||||
maxLength: 255,
|
maxLength: 255,
|
||||||
minLength: 1,
|
minLength: 1,
|
||||||
title: "Title",
|
title: 'Title'
|
||||||
},
|
|
||||||
description: {
|
|
||||||
anyOf: [
|
|
||||||
{
|
|
||||||
type: "string",
|
|
||||||
maxLength: 255,
|
|
||||||
},
|
},
|
||||||
{
|
description: {
|
||||||
type: "null",
|
anyOf: [
|
||||||
},
|
{
|
||||||
],
|
type: 'string',
|
||||||
title: "Description",
|
maxLength: 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'null'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: 'Description'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
type: 'object',
|
||||||
type: "object",
|
required: ['title'],
|
||||||
required: ["title"],
|
title: 'ItemCreate'
|
||||||
title: "ItemCreate",
|
} as const;
|
||||||
} as const
|
|
||||||
|
|
||||||
export const ItemPublicSchema = {
|
export const ItemPublicSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
title: {
|
title: {
|
||||||
type: "string",
|
type: 'string',
|
||||||
maxLength: 255,
|
maxLength: 255,
|
||||||
minLength: 1,
|
minLength: 1,
|
||||||
title: "Title",
|
title: 'Title'
|
||||||
},
|
|
||||||
description: {
|
|
||||||
anyOf: [
|
|
||||||
{
|
|
||||||
type: "string",
|
|
||||||
maxLength: 255,
|
|
||||||
},
|
},
|
||||||
{
|
description: {
|
||||||
type: "null",
|
anyOf: [
|
||||||
|
{
|
||||||
|
type: 'string',
|
||||||
|
maxLength: 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'null'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: 'Description'
|
||||||
},
|
},
|
||||||
],
|
id: {
|
||||||
title: "Description",
|
type: 'string',
|
||||||
|
format: 'uuid',
|
||||||
|
title: 'Id'
|
||||||
|
},
|
||||||
|
owner_id: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'uuid',
|
||||||
|
title: 'Owner Id'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
id: {
|
type: 'object',
|
||||||
type: "string",
|
required: ['title', 'id', 'owner_id'],
|
||||||
format: "uuid",
|
title: 'ItemPublic'
|
||||||
title: "Id",
|
} as const;
|
||||||
},
|
|
||||||
owner_id: {
|
|
||||||
type: "string",
|
|
||||||
format: "uuid",
|
|
||||||
title: "Owner Id",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "object",
|
|
||||||
required: ["title", "id", "owner_id"],
|
|
||||||
title: "ItemPublic",
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export const ItemUpdateSchema = {
|
export const ItemUpdateSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
title: {
|
title: {
|
||||||
anyOf: [
|
anyOf: [
|
||||||
{
|
{
|
||||||
type: "string",
|
type: 'string',
|
||||||
maxLength: 255,
|
maxLength: 255,
|
||||||
minLength: 1,
|
minLength: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'null'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: 'Title'
|
||||||
},
|
},
|
||||||
{
|
description: {
|
||||||
type: "null",
|
anyOf: [
|
||||||
},
|
{
|
||||||
],
|
type: 'string',
|
||||||
title: "Title",
|
maxLength: 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'null'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: 'Description'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
description: {
|
type: 'object',
|
||||||
anyOf: [
|
title: 'ItemUpdate'
|
||||||
{
|
} as const;
|
||||||
type: "string",
|
|
||||||
maxLength: 255,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "null",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
title: "Description",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "object",
|
|
||||||
title: "ItemUpdate",
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export const ItemsPublicSchema = {
|
export const ItemsPublicSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
data: {
|
data: {
|
||||||
items: {
|
items: {
|
||||||
$ref: "#/components/schemas/ItemPublic",
|
'$ref': '#/components/schemas/ItemPublic'
|
||||||
},
|
},
|
||||||
type: "array",
|
type: 'array',
|
||||||
title: "Data",
|
title: 'Data'
|
||||||
|
},
|
||||||
|
count: {
|
||||||
|
type: 'integer',
|
||||||
|
title: 'Count'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
count: {
|
type: 'object',
|
||||||
type: "integer",
|
required: ['data', 'count'],
|
||||||
title: "Count",
|
title: 'ItemsPublic'
|
||||||
},
|
} as const;
|
||||||
},
|
|
||||||
type: "object",
|
|
||||||
required: ["data", "count"],
|
|
||||||
title: "ItemsPublic",
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export const MessageSchema = {
|
export const MessageSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
message: {
|
message: {
|
||||||
type: "string",
|
type: 'string',
|
||||||
title: "Message",
|
title: 'Message'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
type: 'object',
|
||||||
type: "object",
|
required: ['message'],
|
||||||
required: ["message"],
|
title: 'Message'
|
||||||
title: "Message",
|
} as const;
|
||||||
} as const
|
|
||||||
|
|
||||||
export const NewPasswordSchema = {
|
export const NewPasswordSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
token: {
|
token: {
|
||||||
type: "string",
|
type: 'string',
|
||||||
title: "Token",
|
title: 'Token'
|
||||||
|
},
|
||||||
|
new_password: {
|
||||||
|
type: 'string',
|
||||||
|
maxLength: 40,
|
||||||
|
minLength: 8,
|
||||||
|
title: 'New Password'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
new_password: {
|
type: 'object',
|
||||||
type: "string",
|
required: ['token', 'new_password'],
|
||||||
maxLength: 40,
|
title: 'NewPassword'
|
||||||
minLength: 8,
|
} as const;
|
||||||
title: "New Password",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "object",
|
|
||||||
required: ["token", "new_password"],
|
|
||||||
title: "NewPassword",
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export const PrivateUserCreateSchema = {
|
export const PrivateUserCreateSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
email: {
|
email: {
|
||||||
type: "string",
|
type: 'string',
|
||||||
title: "Email",
|
title: 'Email'
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
type: 'string',
|
||||||
|
title: 'Password'
|
||||||
|
},
|
||||||
|
full_name: {
|
||||||
|
type: 'string',
|
||||||
|
title: 'Full Name'
|
||||||
|
},
|
||||||
|
is_verified: {
|
||||||
|
type: 'boolean',
|
||||||
|
title: 'Is Verified',
|
||||||
|
default: false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
password: {
|
type: 'object',
|
||||||
type: "string",
|
required: ['email', 'password', 'full_name'],
|
||||||
title: "Password",
|
title: 'PrivateUserCreate'
|
||||||
},
|
} as const;
|
||||||
full_name: {
|
|
||||||
type: "string",
|
|
||||||
title: "Full Name",
|
|
||||||
},
|
|
||||||
is_verified: {
|
|
||||||
type: "boolean",
|
|
||||||
title: "Is Verified",
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "object",
|
|
||||||
required: ["email", "password", "full_name"],
|
|
||||||
title: "PrivateUserCreate",
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export const TokenSchema = {
|
export const TokenSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
access_token: {
|
access_token: {
|
||||||
type: "string",
|
type: 'string',
|
||||||
title: "Access Token",
|
title: 'Access Token'
|
||||||
|
},
|
||||||
|
token_type: {
|
||||||
|
type: 'string',
|
||||||
|
title: 'Token Type',
|
||||||
|
default: 'bearer'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
token_type: {
|
type: 'object',
|
||||||
type: "string",
|
required: ['access_token'],
|
||||||
title: "Token Type",
|
title: 'Token'
|
||||||
default: "bearer",
|
} as const;
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "object",
|
|
||||||
required: ["access_token"],
|
|
||||||
title: "Token",
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export const UpdatePasswordSchema = {
|
export const UpdatePasswordSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
current_password: {
|
current_password: {
|
||||||
type: "string",
|
type: 'string',
|
||||||
maxLength: 40,
|
maxLength: 40,
|
||||||
minLength: 8,
|
minLength: 8,
|
||||||
title: "Current Password",
|
title: 'Current Password'
|
||||||
|
},
|
||||||
|
new_password: {
|
||||||
|
type: 'string',
|
||||||
|
maxLength: 40,
|
||||||
|
minLength: 8,
|
||||||
|
title: 'New Password'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
new_password: {
|
type: 'object',
|
||||||
type: "string",
|
required: ['current_password', 'new_password'],
|
||||||
maxLength: 40,
|
title: 'UpdatePassword'
|
||||||
minLength: 8,
|
} as const;
|
||||||
title: "New Password",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "object",
|
|
||||||
required: ["current_password", "new_password"],
|
|
||||||
title: "UpdatePassword",
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export const UserCreateSchema = {
|
export const UserCreateSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
email: {
|
email: {
|
||||||
type: "string",
|
type: 'string',
|
||||||
maxLength: 255,
|
maxLength: 255,
|
||||||
format: "email",
|
format: 'email',
|
||||||
title: "Email",
|
title: 'Email'
|
||||||
},
|
|
||||||
is_active: {
|
|
||||||
type: "boolean",
|
|
||||||
title: "Is Active",
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
is_superuser: {
|
|
||||||
type: "boolean",
|
|
||||||
title: "Is Superuser",
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
full_name: {
|
|
||||||
anyOf: [
|
|
||||||
{
|
|
||||||
type: "string",
|
|
||||||
maxLength: 255,
|
|
||||||
},
|
},
|
||||||
{
|
is_active: {
|
||||||
type: "null",
|
type: 'boolean',
|
||||||
|
title: 'Is Active',
|
||||||
|
default: true
|
||||||
},
|
},
|
||||||
],
|
is_superuser: {
|
||||||
title: "Full Name",
|
type: 'boolean',
|
||||||
|
title: 'Is Superuser',
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
full_name: {
|
||||||
|
anyOf: [
|
||||||
|
{
|
||||||
|
type: 'string',
|
||||||
|
maxLength: 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'null'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: 'Full Name'
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
type: 'string',
|
||||||
|
maxLength: 40,
|
||||||
|
minLength: 8,
|
||||||
|
title: 'Password'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
password: {
|
type: 'object',
|
||||||
type: "string",
|
required: ['email', 'password'],
|
||||||
maxLength: 40,
|
title: 'UserCreate'
|
||||||
minLength: 8,
|
} as const;
|
||||||
title: "Password",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "object",
|
|
||||||
required: ["email", "password"],
|
|
||||||
title: "UserCreate",
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export const UserPublicSchema = {
|
export const UserPublicSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
email: {
|
email: {
|
||||||
type: "string",
|
type: 'string',
|
||||||
maxLength: 255,
|
maxLength: 255,
|
||||||
format: "email",
|
format: 'email',
|
||||||
title: "Email",
|
title: 'Email'
|
||||||
},
|
|
||||||
is_active: {
|
|
||||||
type: "boolean",
|
|
||||||
title: "Is Active",
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
is_superuser: {
|
|
||||||
type: "boolean",
|
|
||||||
title: "Is Superuser",
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
full_name: {
|
|
||||||
anyOf: [
|
|
||||||
{
|
|
||||||
type: "string",
|
|
||||||
maxLength: 255,
|
|
||||||
},
|
},
|
||||||
{
|
is_active: {
|
||||||
type: "null",
|
type: 'boolean',
|
||||||
|
title: 'Is Active',
|
||||||
|
default: true
|
||||||
},
|
},
|
||||||
],
|
is_superuser: {
|
||||||
title: "Full Name",
|
type: 'boolean',
|
||||||
|
title: 'Is Superuser',
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
full_name: {
|
||||||
|
anyOf: [
|
||||||
|
{
|
||||||
|
type: 'string',
|
||||||
|
maxLength: 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'null'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: 'Full Name'
|
||||||
|
},
|
||||||
|
id: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'uuid',
|
||||||
|
title: 'Id'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
id: {
|
type: 'object',
|
||||||
type: "string",
|
required: ['email', 'id'],
|
||||||
format: "uuid",
|
title: 'UserPublic'
|
||||||
title: "Id",
|
} as const;
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "object",
|
|
||||||
required: ["email", "id"],
|
|
||||||
title: "UserPublic",
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export const UserRegisterSchema = {
|
export const UserRegisterSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
email: {
|
email: {
|
||||||
type: "string",
|
type: 'string',
|
||||||
maxLength: 255,
|
maxLength: 255,
|
||||||
format: "email",
|
format: 'email',
|
||||||
title: "Email",
|
title: 'Email'
|
||||||
},
|
|
||||||
password: {
|
|
||||||
type: "string",
|
|
||||||
maxLength: 40,
|
|
||||||
minLength: 8,
|
|
||||||
title: "Password",
|
|
||||||
},
|
|
||||||
full_name: {
|
|
||||||
anyOf: [
|
|
||||||
{
|
|
||||||
type: "string",
|
|
||||||
maxLength: 255,
|
|
||||||
},
|
},
|
||||||
{
|
password: {
|
||||||
type: "null",
|
type: 'string',
|
||||||
|
maxLength: 40,
|
||||||
|
minLength: 8,
|
||||||
|
title: 'Password'
|
||||||
},
|
},
|
||||||
],
|
full_name: {
|
||||||
title: "Full Name",
|
anyOf: [
|
||||||
|
{
|
||||||
|
type: 'string',
|
||||||
|
maxLength: 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'null'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: 'Full Name'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
type: 'object',
|
||||||
type: "object",
|
required: ['email', 'password'],
|
||||||
required: ["email", "password"],
|
title: 'UserRegister'
|
||||||
title: "UserRegister",
|
} as const;
|
||||||
} as const
|
|
||||||
|
|
||||||
export const UserUpdateSchema = {
|
export const UserUpdateSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
email: {
|
email: {
|
||||||
anyOf: [
|
anyOf: [
|
||||||
{
|
{
|
||||||
type: "string",
|
type: 'string',
|
||||||
maxLength: 255,
|
maxLength: 255,
|
||||||
format: "email",
|
format: 'email'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'null'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: 'Email'
|
||||||
},
|
},
|
||||||
{
|
is_active: {
|
||||||
type: "null",
|
type: 'boolean',
|
||||||
|
title: 'Is Active',
|
||||||
|
default: true
|
||||||
},
|
},
|
||||||
],
|
is_superuser: {
|
||||||
title: "Email",
|
type: 'boolean',
|
||||||
|
title: 'Is Superuser',
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
full_name: {
|
||||||
|
anyOf: [
|
||||||
|
{
|
||||||
|
type: 'string',
|
||||||
|
maxLength: 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'null'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: 'Full Name'
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
anyOf: [
|
||||||
|
{
|
||||||
|
type: 'string',
|
||||||
|
maxLength: 40,
|
||||||
|
minLength: 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'null'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: 'Password'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
is_active: {
|
type: 'object',
|
||||||
type: "boolean",
|
title: 'UserUpdate'
|
||||||
title: "Is Active",
|
} as const;
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
is_superuser: {
|
|
||||||
type: "boolean",
|
|
||||||
title: "Is Superuser",
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
full_name: {
|
|
||||||
anyOf: [
|
|
||||||
{
|
|
||||||
type: "string",
|
|
||||||
maxLength: 255,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "null",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
title: "Full Name",
|
|
||||||
},
|
|
||||||
password: {
|
|
||||||
anyOf: [
|
|
||||||
{
|
|
||||||
type: "string",
|
|
||||||
maxLength: 40,
|
|
||||||
minLength: 8,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "null",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
title: "Password",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "object",
|
|
||||||
title: "UserUpdate",
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export const UserUpdateMeSchema = {
|
export const UserUpdateMeSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
full_name: {
|
full_name: {
|
||||||
anyOf: [
|
anyOf: [
|
||||||
{
|
{
|
||||||
type: "string",
|
type: 'string',
|
||||||
maxLength: 255,
|
maxLength: 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'null'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: 'Full Name'
|
||||||
},
|
},
|
||||||
{
|
email: {
|
||||||
type: "null",
|
anyOf: [
|
||||||
},
|
{
|
||||||
],
|
type: 'string',
|
||||||
title: "Full Name",
|
maxLength: 255,
|
||||||
|
format: 'email'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'null'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: 'Email'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
email: {
|
type: 'object',
|
||||||
anyOf: [
|
title: 'UserUpdateMe'
|
||||||
{
|
} as const;
|
||||||
type: "string",
|
|
||||||
maxLength: 255,
|
|
||||||
format: "email",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "null",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
title: "Email",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "object",
|
|
||||||
title: "UserUpdateMe",
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export const UsersPublicSchema = {
|
export const UsersPublicSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
data: {
|
data: {
|
||||||
items: {
|
items: {
|
||||||
$ref: "#/components/schemas/UserPublic",
|
'$ref': '#/components/schemas/UserPublic'
|
||||||
},
|
},
|
||||||
type: "array",
|
type: 'array',
|
||||||
title: "Data",
|
title: 'Data'
|
||||||
|
},
|
||||||
|
count: {
|
||||||
|
type: 'integer',
|
||||||
|
title: 'Count'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
count: {
|
type: 'object',
|
||||||
type: "integer",
|
required: ['data', 'count'],
|
||||||
title: "Count",
|
title: 'UsersPublic'
|
||||||
},
|
} as const;
|
||||||
},
|
|
||||||
type: "object",
|
|
||||||
required: ["data", "count"],
|
|
||||||
title: "UsersPublic",
|
|
||||||
} as const
|
|
||||||
|
|
||||||
export const ValidationErrorSchema = {
|
export const ValidationErrorSchema = {
|
||||||
properties: {
|
properties: {
|
||||||
loc: {
|
loc: {
|
||||||
items: {
|
items: {
|
||||||
anyOf: [
|
anyOf: [
|
||||||
{
|
{
|
||||||
type: "string",
|
type: 'string'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "integer",
|
type: 'integer'
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
},
|
},
|
||||||
type: "array",
|
type: 'array',
|
||||||
title: "Location",
|
title: 'Location'
|
||||||
|
},
|
||||||
|
msg: {
|
||||||
|
type: 'string',
|
||||||
|
title: 'Message'
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: 'string',
|
||||||
|
title: 'Error Type'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
msg: {
|
type: 'object',
|
||||||
type: "string",
|
required: ['loc', 'msg', 'type'],
|
||||||
title: "Message",
|
title: 'ValidationError'
|
||||||
},
|
} as const;
|
||||||
type: {
|
|
||||||
type: "string",
|
|
||||||
title: "Error Type",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: "object",
|
|
||||||
required: ["loc", "msg", "type"],
|
|
||||||
title: "ValidationError",
|
|
||||||
} as const
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,234 +1,234 @@
|
|||||||
// This file is auto-generated by @hey-api/openapi-ts
|
// This file is auto-generated by @hey-api/openapi-ts
|
||||||
|
|
||||||
export type Body_login_login_access_token = {
|
export type Body_login_login_access_token = {
|
||||||
grant_type?: string | null
|
grant_type?: (string | null);
|
||||||
username: string
|
username: string;
|
||||||
password: string
|
password: string;
|
||||||
scope?: string
|
scope?: string;
|
||||||
client_id?: string | null
|
client_id?: (string | null);
|
||||||
client_secret?: string | null
|
client_secret?: (string | null);
|
||||||
}
|
};
|
||||||
|
|
||||||
export type HTTPValidationError = {
|
export type HTTPValidationError = {
|
||||||
detail?: Array<ValidationError>
|
detail?: Array<ValidationError>;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type ItemCreate = {
|
export type ItemCreate = {
|
||||||
title: string
|
title: string;
|
||||||
description?: string | null
|
description?: (string | null);
|
||||||
}
|
};
|
||||||
|
|
||||||
export type ItemPublic = {
|
export type ItemPublic = {
|
||||||
title: string
|
title: string;
|
||||||
description?: string | null
|
description?: (string | null);
|
||||||
id: string
|
id: string;
|
||||||
owner_id: string
|
owner_id: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type ItemsPublic = {
|
export type ItemsPublic = {
|
||||||
data: Array<ItemPublic>
|
data: Array<ItemPublic>;
|
||||||
count: number
|
count: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type ItemUpdate = {
|
export type ItemUpdate = {
|
||||||
title?: string | null
|
title?: (string | null);
|
||||||
description?: string | null
|
description?: (string | null);
|
||||||
}
|
};
|
||||||
|
|
||||||
export type Message = {
|
export type Message = {
|
||||||
message: string
|
message: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type NewPassword = {
|
export type NewPassword = {
|
||||||
token: string
|
token: string;
|
||||||
new_password: string
|
new_password: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type PrivateUserCreate = {
|
export type PrivateUserCreate = {
|
||||||
email: string
|
email: string;
|
||||||
password: string
|
password: string;
|
||||||
full_name: string
|
full_name: string;
|
||||||
is_verified?: boolean
|
is_verified?: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type Token = {
|
export type Token = {
|
||||||
access_token: string
|
access_token: string;
|
||||||
token_type?: string
|
token_type?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type UpdatePassword = {
|
export type UpdatePassword = {
|
||||||
current_password: string
|
current_password: string;
|
||||||
new_password: string
|
new_password: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type UserCreate = {
|
export type UserCreate = {
|
||||||
email: string
|
email: string;
|
||||||
is_active?: boolean
|
is_active?: boolean;
|
||||||
is_superuser?: boolean
|
is_superuser?: boolean;
|
||||||
full_name?: string | null
|
full_name?: (string | null);
|
||||||
password: string
|
password: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type UserPublic = {
|
export type UserPublic = {
|
||||||
email: string
|
email: string;
|
||||||
is_active?: boolean
|
is_active?: boolean;
|
||||||
is_superuser?: boolean
|
is_superuser?: boolean;
|
||||||
full_name?: string | null
|
full_name?: (string | null);
|
||||||
id: string
|
id: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type UserRegister = {
|
export type UserRegister = {
|
||||||
email: string
|
email: string;
|
||||||
password: string
|
password: string;
|
||||||
full_name?: string | null
|
full_name?: (string | null);
|
||||||
}
|
};
|
||||||
|
|
||||||
export type UsersPublic = {
|
export type UsersPublic = {
|
||||||
data: Array<UserPublic>
|
data: Array<UserPublic>;
|
||||||
count: number
|
count: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type UserUpdate = {
|
export type UserUpdate = {
|
||||||
email?: string | null
|
email?: (string | null);
|
||||||
is_active?: boolean
|
is_active?: boolean;
|
||||||
is_superuser?: boolean
|
is_superuser?: boolean;
|
||||||
full_name?: string | null
|
full_name?: (string | null);
|
||||||
password?: string | null
|
password?: (string | null);
|
||||||
}
|
};
|
||||||
|
|
||||||
export type UserUpdateMe = {
|
export type UserUpdateMe = {
|
||||||
full_name?: string | null
|
full_name?: (string | null);
|
||||||
email?: string | null
|
email?: (string | null);
|
||||||
}
|
};
|
||||||
|
|
||||||
export type ValidationError = {
|
export type ValidationError = {
|
||||||
loc: Array<string | number>
|
loc: Array<(string | number)>;
|
||||||
msg: string
|
msg: string;
|
||||||
type: string
|
type: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type ItemsReadItemsData = {
|
export type ItemsReadItemsData = {
|
||||||
limit?: number
|
limit?: number;
|
||||||
skip?: number
|
skip?: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type ItemsReadItemsResponse = ItemsPublic
|
export type ItemsReadItemsResponse = (ItemsPublic);
|
||||||
|
|
||||||
export type ItemsCreateItemData = {
|
export type ItemsCreateItemData = {
|
||||||
requestBody: ItemCreate
|
requestBody: ItemCreate;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type ItemsCreateItemResponse = ItemPublic
|
export type ItemsCreateItemResponse = (ItemPublic);
|
||||||
|
|
||||||
export type ItemsReadItemData = {
|
export type ItemsReadItemData = {
|
||||||
id: string
|
id: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type ItemsReadItemResponse = ItemPublic
|
export type ItemsReadItemResponse = (ItemPublic);
|
||||||
|
|
||||||
export type ItemsUpdateItemData = {
|
export type ItemsUpdateItemData = {
|
||||||
id: string
|
id: string;
|
||||||
requestBody: ItemUpdate
|
requestBody: ItemUpdate;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type ItemsUpdateItemResponse = ItemPublic
|
export type ItemsUpdateItemResponse = (ItemPublic);
|
||||||
|
|
||||||
export type ItemsDeleteItemData = {
|
export type ItemsDeleteItemData = {
|
||||||
id: string
|
id: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type ItemsDeleteItemResponse = Message
|
export type ItemsDeleteItemResponse = (Message);
|
||||||
|
|
||||||
export type LoginLoginAccessTokenData = {
|
export type LoginLoginAccessTokenData = {
|
||||||
formData: Body_login_login_access_token
|
formData: Body_login_login_access_token;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type LoginLoginAccessTokenResponse = Token
|
export type LoginLoginAccessTokenResponse = (Token);
|
||||||
|
|
||||||
export type LoginTestTokenResponse = UserPublic
|
export type LoginTestTokenResponse = (UserPublic);
|
||||||
|
|
||||||
export type LoginRecoverPasswordData = {
|
export type LoginRecoverPasswordData = {
|
||||||
email: string
|
email: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type LoginRecoverPasswordResponse = Message
|
export type LoginRecoverPasswordResponse = (Message);
|
||||||
|
|
||||||
export type LoginResetPasswordData = {
|
export type LoginResetPasswordData = {
|
||||||
requestBody: NewPassword
|
requestBody: NewPassword;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type LoginResetPasswordResponse = Message
|
export type LoginResetPasswordResponse = (Message);
|
||||||
|
|
||||||
export type LoginRecoverPasswordHtmlContentData = {
|
export type LoginRecoverPasswordHtmlContentData = {
|
||||||
email: string
|
email: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type LoginRecoverPasswordHtmlContentResponse = string
|
export type LoginRecoverPasswordHtmlContentResponse = (string);
|
||||||
|
|
||||||
export type PrivateCreateUserData = {
|
export type PrivateCreateUserData = {
|
||||||
requestBody: PrivateUserCreate
|
requestBody: PrivateUserCreate;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type PrivateCreateUserResponse = UserPublic
|
export type PrivateCreateUserResponse = (UserPublic);
|
||||||
|
|
||||||
export type UsersReadUsersData = {
|
export type UsersReadUsersData = {
|
||||||
limit?: number
|
limit?: number;
|
||||||
skip?: number
|
skip?: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type UsersReadUsersResponse = UsersPublic
|
export type UsersReadUsersResponse = (UsersPublic);
|
||||||
|
|
||||||
export type UsersCreateUserData = {
|
export type UsersCreateUserData = {
|
||||||
requestBody: UserCreate
|
requestBody: UserCreate;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type UsersCreateUserResponse = UserPublic
|
export type UsersCreateUserResponse = (UserPublic);
|
||||||
|
|
||||||
export type UsersReadUserMeResponse = UserPublic
|
export type UsersReadUserMeResponse = (UserPublic);
|
||||||
|
|
||||||
export type UsersDeleteUserMeResponse = Message
|
export type UsersDeleteUserMeResponse = (Message);
|
||||||
|
|
||||||
export type UsersUpdateUserMeData = {
|
export type UsersUpdateUserMeData = {
|
||||||
requestBody: UserUpdateMe
|
requestBody: UserUpdateMe;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type UsersUpdateUserMeResponse = UserPublic
|
export type UsersUpdateUserMeResponse = (UserPublic);
|
||||||
|
|
||||||
export type UsersUpdatePasswordMeData = {
|
export type UsersUpdatePasswordMeData = {
|
||||||
requestBody: UpdatePassword
|
requestBody: UpdatePassword;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type UsersUpdatePasswordMeResponse = Message
|
export type UsersUpdatePasswordMeResponse = (Message);
|
||||||
|
|
||||||
export type UsersRegisterUserData = {
|
export type UsersRegisterUserData = {
|
||||||
requestBody: UserRegister
|
requestBody: UserRegister;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type UsersRegisterUserResponse = UserPublic
|
export type UsersRegisterUserResponse = (UserPublic);
|
||||||
|
|
||||||
export type UsersReadUserByIdData = {
|
export type UsersReadUserByIdData = {
|
||||||
userId: string
|
userId: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type UsersReadUserByIdResponse = UserPublic
|
export type UsersReadUserByIdResponse = (UserPublic);
|
||||||
|
|
||||||
export type UsersUpdateUserData = {
|
export type UsersUpdateUserData = {
|
||||||
requestBody: UserUpdate
|
requestBody: UserUpdate;
|
||||||
userId: string
|
userId: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type UsersUpdateUserResponse = UserPublic
|
export type UsersUpdateUserResponse = (UserPublic);
|
||||||
|
|
||||||
export type UsersDeleteUserData = {
|
export type UsersDeleteUserData = {
|
||||||
userId: string
|
userId: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type UsersDeleteUserResponse = Message
|
export type UsersDeleteUserResponse = (Message);
|
||||||
|
|
||||||
export type UtilsTestEmailData = {
|
export type UtilsTestEmailData = {
|
||||||
emailTo: string
|
emailTo: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type UtilsTestEmailResponse = Message
|
export type UtilsTestEmailResponse = (Message);
|
||||||
|
|
||||||
export type UtilsHealthCheckResponse = boolean
|
export type UtilsHealthCheckResponse = (boolean);
|
||||||
@@ -1,10 +1,3 @@
|
|||||||
import { useMutation, useQueryClient } from "@tanstack/react-query"
|
|
||||||
import { Controller, type SubmitHandler, useForm } from "react-hook-form"
|
|
||||||
|
|
||||||
import { type UserCreate, UsersService } from "@/client"
|
|
||||||
import type { ApiError } from "@/client/core/ApiError"
|
|
||||||
import useCustomToast from "@/hooks/useCustomToast"
|
|
||||||
import { emailPattern, handleError } from "@/utils"
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
DialogActionTrigger,
|
DialogActionTrigger,
|
||||||
@@ -14,8 +7,14 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
VStack,
|
VStack,
|
||||||
} from "@chakra-ui/react"
|
} from "@chakra-ui/react"
|
||||||
|
import { useMutation, useQueryClient } from "@tanstack/react-query"
|
||||||
import { useState } from "react"
|
import { useState } from "react"
|
||||||
|
import { Controller, type SubmitHandler, useForm } from "react-hook-form"
|
||||||
import { FaPlus } from "react-icons/fa"
|
import { FaPlus } from "react-icons/fa"
|
||||||
|
import { type UserCreate, UsersService } from "@/client"
|
||||||
|
import type { ApiError } from "@/client/core/ApiError"
|
||||||
|
import useCustomToast from "@/hooks/useCustomToast"
|
||||||
|
import { emailPattern, handleError } from "@/utils"
|
||||||
import { Checkbox } from "../ui/checkbox"
|
import { Checkbox } from "../ui/checkbox"
|
||||||
import {
|
import {
|
||||||
DialogBody,
|
DialogBody,
|
||||||
@@ -106,7 +105,6 @@ const AddUser = () => {
|
|||||||
label="Email"
|
label="Email"
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
id="email"
|
|
||||||
{...register("email", {
|
{...register("email", {
|
||||||
required: "Email is required",
|
required: "Email is required",
|
||||||
pattern: emailPattern,
|
pattern: emailPattern,
|
||||||
@@ -122,7 +120,6 @@ const AddUser = () => {
|
|||||||
label="Full Name"
|
label="Full Name"
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
id="name"
|
|
||||||
{...register("full_name")}
|
{...register("full_name")}
|
||||||
placeholder="Full name"
|
placeholder="Full name"
|
||||||
type="text"
|
type="text"
|
||||||
@@ -136,7 +133,6 @@ const AddUser = () => {
|
|||||||
label="Set Password"
|
label="Set Password"
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
id="password"
|
|
||||||
{...register("password", {
|
{...register("password", {
|
||||||
required: "Password is required",
|
required: "Password is required",
|
||||||
minLength: {
|
minLength: {
|
||||||
@@ -156,7 +152,6 @@ const AddUser = () => {
|
|||||||
label="Confirm Password"
|
label="Confirm Password"
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
id="confirm_password"
|
|
||||||
{...register("confirm_password", {
|
{...register("confirm_password", {
|
||||||
required: "Please confirm your password",
|
required: "Please confirm your password",
|
||||||
validate: (value) =>
|
validate: (value) =>
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
import { useMutation, useQueryClient } from "@tanstack/react-query"
|
|
||||||
import { Controller, type SubmitHandler, useForm } from "react-hook-form"
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
DialogActionTrigger,
|
DialogActionTrigger,
|
||||||
@@ -11,10 +8,12 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
VStack,
|
VStack,
|
||||||
} from "@chakra-ui/react"
|
} from "@chakra-ui/react"
|
||||||
|
import { useMutation, useQueryClient } from "@tanstack/react-query"
|
||||||
import { useState } from "react"
|
import { useState } from "react"
|
||||||
|
import { Controller, type SubmitHandler, useForm } from "react-hook-form"
|
||||||
import { FaExchangeAlt } from "react-icons/fa"
|
import { FaExchangeAlt } from "react-icons/fa"
|
||||||
|
|
||||||
import { type UserPublic, type UserUpdate, UsersService } from "@/client"
|
import { type UserPublic, UsersService, type UserUpdate } from "@/client"
|
||||||
import type { ApiError } from "@/client/core/ApiError"
|
import type { ApiError } from "@/client/core/ApiError"
|
||||||
import useCustomToast from "@/hooks/useCustomToast"
|
import useCustomToast from "@/hooks/useCustomToast"
|
||||||
import { emailPattern, handleError } from "@/utils"
|
import { emailPattern, handleError } from "@/utils"
|
||||||
@@ -105,7 +104,6 @@ const EditUser = ({ user }: EditUserProps) => {
|
|||||||
label="Email"
|
label="Email"
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
id="email"
|
|
||||||
{...register("email", {
|
{...register("email", {
|
||||||
required: "Email is required",
|
required: "Email is required",
|
||||||
pattern: emailPattern,
|
pattern: emailPattern,
|
||||||
@@ -121,7 +119,6 @@ const EditUser = ({ user }: EditUserProps) => {
|
|||||||
label="Full Name"
|
label="Full Name"
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
id="name"
|
|
||||||
{...register("full_name")}
|
{...register("full_name")}
|
||||||
placeholder="Full name"
|
placeholder="Full name"
|
||||||
type="text"
|
type="text"
|
||||||
@@ -134,7 +131,6 @@ const EditUser = ({ user }: EditUserProps) => {
|
|||||||
label="Set Password"
|
label="Set Password"
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
id="password"
|
|
||||||
{...register("password", {
|
{...register("password", {
|
||||||
minLength: {
|
minLength: {
|
||||||
value: 8,
|
value: 8,
|
||||||
@@ -152,7 +148,6 @@ const EditUser = ({ user }: EditUserProps) => {
|
|||||||
label="Confirm Password"
|
label="Confirm Password"
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
id="confirm_password"
|
|
||||||
{...register("confirm_password", {
|
{...register("confirm_password", {
|
||||||
validate: (value) =>
|
validate: (value) =>
|
||||||
value === getValues().password ||
|
value === getValues().password ||
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { IconButton } from "@chakra-ui/react"
|
import { IconButton } from "@chakra-ui/react"
|
||||||
import { BsThreeDotsVertical } from "react-icons/bs"
|
import { BsThreeDotsVertical } from "react-icons/bs"
|
||||||
import { MenuContent, MenuRoot, MenuTrigger } from "../ui/menu"
|
|
||||||
|
|
||||||
import type { ItemPublic } from "@/client"
|
import type { ItemPublic } from "@/client"
|
||||||
import DeleteItem from "../Items/DeleteItem"
|
import DeleteItem from "../Items/DeleteItem"
|
||||||
import EditItem from "../Items/EditItem"
|
import EditItem from "../Items/EditItem"
|
||||||
|
import { MenuContent, MenuRoot, MenuTrigger } from "../ui/menu"
|
||||||
|
|
||||||
interface ItemActionsMenuProps {
|
interface ItemActionsMenuProps {
|
||||||
item: ItemPublic
|
item: ItemPublic
|
||||||
|
|||||||
@@ -3,54 +3,41 @@ import { Link } from "@tanstack/react-router"
|
|||||||
|
|
||||||
const NotFound = () => {
|
const NotFound = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<Flex
|
||||||
<Flex
|
height="100vh"
|
||||||
height="100vh"
|
align="center"
|
||||||
align="center"
|
justify="center"
|
||||||
justify="center"
|
flexDir="column"
|
||||||
flexDir="column"
|
data-testid="not-found"
|
||||||
data-testid="not-found"
|
p={4}
|
||||||
p={4}
|
>
|
||||||
>
|
<Flex alignItems="center" zIndex={1}>
|
||||||
<Flex alignItems="center" zIndex={1}>
|
<Flex flexDir="column" ml={4} align="center" justify="center" p={4}>
|
||||||
<Flex flexDir="column" ml={4} align="center" justify="center" p={4}>
|
<Text
|
||||||
<Text
|
fontSize={{ base: "6xl", md: "8xl" }}
|
||||||
fontSize={{ base: "6xl", md: "8xl" }}
|
fontWeight="bold"
|
||||||
fontWeight="bold"
|
lineHeight="1"
|
||||||
lineHeight="1"
|
mb={4}
|
||||||
mb={4}
|
>
|
||||||
>
|
404
|
||||||
404
|
</Text>
|
||||||
</Text>
|
<Text fontSize="2xl" fontWeight="bold" mb={2}>
|
||||||
<Text fontSize="2xl" fontWeight="bold" mb={2}>
|
Oops!
|
||||||
Oops!
|
</Text>
|
||||||
</Text>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Text
|
|
||||||
fontSize="lg"
|
|
||||||
color="gray.600"
|
|
||||||
mb={4}
|
|
||||||
textAlign="center"
|
|
||||||
zIndex={1}
|
|
||||||
>
|
|
||||||
The page you are looking for was not found.
|
|
||||||
</Text>
|
|
||||||
<Center zIndex={1}>
|
|
||||||
<Link to="/">
|
|
||||||
<Button
|
|
||||||
variant="solid"
|
|
||||||
colorScheme="teal"
|
|
||||||
mt={4}
|
|
||||||
alignSelf="center"
|
|
||||||
>
|
|
||||||
Go Back
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
</Center>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
</>
|
|
||||||
|
<Text fontSize="lg" color="gray.600" mb={4} textAlign="center" zIndex={1}>
|
||||||
|
The page you are looking for was not found.
|
||||||
|
</Text>
|
||||||
|
<Center zIndex={1}>
|
||||||
|
<Link to="/">
|
||||||
|
<Button variant="solid" colorScheme="teal" mt={4} alignSelf="center">
|
||||||
|
Go Back
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</Center>
|
||||||
|
</Flex>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { IconButton } from "@chakra-ui/react"
|
import { IconButton } from "@chakra-ui/react"
|
||||||
import { BsThreeDotsVertical } from "react-icons/bs"
|
import { BsThreeDotsVertical } from "react-icons/bs"
|
||||||
import { MenuContent, MenuRoot, MenuTrigger } from "../ui/menu"
|
|
||||||
|
|
||||||
import type { UserPublic } from "@/client"
|
import type { UserPublic } from "@/client"
|
||||||
import DeleteUser from "../Admin/DeleteUser"
|
import DeleteUser from "../Admin/DeleteUser"
|
||||||
import EditUser from "../Admin/EditUser"
|
import EditUser from "../Admin/EditUser"
|
||||||
|
import { MenuContent, MenuRoot, MenuTrigger } from "../ui/menu"
|
||||||
|
|
||||||
interface UserActionsMenuProps {
|
interface UserActionsMenuProps {
|
||||||
user: UserPublic
|
user: UserPublic
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
import { useMutation, useQueryClient } from "@tanstack/react-query"
|
|
||||||
import { type SubmitHandler, useForm } from "react-hook-form"
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
DialogActionTrigger,
|
DialogActionTrigger,
|
||||||
@@ -9,7 +6,9 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
VStack,
|
VStack,
|
||||||
} from "@chakra-ui/react"
|
} from "@chakra-ui/react"
|
||||||
|
import { useMutation, useQueryClient } from "@tanstack/react-query"
|
||||||
import { useState } from "react"
|
import { useState } from "react"
|
||||||
|
import { type SubmitHandler, useForm } from "react-hook-form"
|
||||||
import { FaPlus } from "react-icons/fa"
|
import { FaPlus } from "react-icons/fa"
|
||||||
|
|
||||||
import { type ItemCreate, ItemsService } from "@/client"
|
import { type ItemCreate, ItemsService } from "@/client"
|
||||||
@@ -93,7 +92,6 @@ const AddItem = () => {
|
|||||||
label="Title"
|
label="Title"
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
id="title"
|
|
||||||
{...register("title", {
|
{...register("title", {
|
||||||
required: "Title is required.",
|
required: "Title is required.",
|
||||||
})}
|
})}
|
||||||
@@ -108,7 +106,6 @@ const AddItem = () => {
|
|||||||
label="Description"
|
label="Description"
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
id="description"
|
|
||||||
{...register("description")}
|
{...register("description")}
|
||||||
placeholder="Description"
|
placeholder="Description"
|
||||||
type="text"
|
type="text"
|
||||||
|
|||||||
@@ -101,7 +101,6 @@ const EditItem = ({ item }: EditItemProps) => {
|
|||||||
label="Title"
|
label="Title"
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
id="title"
|
|
||||||
{...register("title", {
|
{...register("title", {
|
||||||
required: "Title is required",
|
required: "Title is required",
|
||||||
})}
|
})}
|
||||||
@@ -116,7 +115,6 @@ const EditItem = ({ item }: EditItemProps) => {
|
|||||||
label="Description"
|
label="Description"
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
id="description"
|
|
||||||
{...register("description")}
|
{...register("description")}
|
||||||
placeholder="Description"
|
placeholder="Description"
|
||||||
type="text"
|
type="text"
|
||||||
|
|||||||
@@ -7,25 +7,23 @@ const Appearance = () => {
|
|||||||
const { theme, setTheme } = useTheme()
|
const { theme, setTheme } = useTheme()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Container maxW="full">
|
||||||
<Container maxW="full">
|
<Heading size="sm" py={4}>
|
||||||
<Heading size="sm" py={4}>
|
Appearance
|
||||||
Appearance
|
</Heading>
|
||||||
</Heading>
|
|
||||||
|
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
onValueChange={(e) => setTheme(e.value ?? "system")}
|
onValueChange={(e) => setTheme(e.value ?? "system")}
|
||||||
value={theme}
|
value={theme}
|
||||||
colorPalette="teal"
|
colorPalette="teal"
|
||||||
>
|
>
|
||||||
<Stack>
|
<Stack>
|
||||||
<Radio value="system">System</Radio>
|
<Radio value="system">System</Radio>
|
||||||
<Radio value="light">Light Mode</Radio>
|
<Radio value="light">Light Mode</Radio>
|
||||||
<Radio value="dark">Dark Mode</Radio>
|
<Radio value="dark">Dark Mode</Radio>
|
||||||
</Stack>
|
</Stack>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</Container>
|
</Container>
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
export default Appearance
|
export default Appearance
|
||||||
|
|||||||
@@ -42,46 +42,39 @@ const ChangePassword = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Container maxW="full">
|
||||||
<Container maxW="full">
|
<Heading size="sm" py={4}>
|
||||||
<Heading size="sm" py={4}>
|
Change Password
|
||||||
Change Password
|
</Heading>
|
||||||
</Heading>
|
<Box as="form" onSubmit={handleSubmit(onSubmit)}>
|
||||||
<Box as="form" onSubmit={handleSubmit(onSubmit)}>
|
<VStack gap={4} w={{ base: "100%", md: "sm" }}>
|
||||||
<VStack gap={4} w={{ base: "100%", md: "sm" }}>
|
<PasswordInput
|
||||||
<PasswordInput
|
type="current_password"
|
||||||
type="current_password"
|
startElement={<FiLock />}
|
||||||
startElement={<FiLock />}
|
{...register("current_password", passwordRules())}
|
||||||
{...register("current_password", passwordRules())}
|
placeholder="Current Password"
|
||||||
placeholder="Current Password"
|
errors={errors}
|
||||||
errors={errors}
|
/>
|
||||||
/>
|
<PasswordInput
|
||||||
<PasswordInput
|
type="new_password"
|
||||||
type="new_password"
|
startElement={<FiLock />}
|
||||||
startElement={<FiLock />}
|
{...register("new_password", passwordRules())}
|
||||||
{...register("new_password", passwordRules())}
|
placeholder="New Password"
|
||||||
placeholder="New Password"
|
errors={errors}
|
||||||
errors={errors}
|
/>
|
||||||
/>
|
<PasswordInput
|
||||||
<PasswordInput
|
type="confirm_password"
|
||||||
type="confirm_password"
|
startElement={<FiLock />}
|
||||||
startElement={<FiLock />}
|
{...register("confirm_password", confirmPasswordRules(getValues))}
|
||||||
{...register("confirm_password", confirmPasswordRules(getValues))}
|
placeholder="Confirm Password"
|
||||||
placeholder="Confirm Password"
|
errors={errors}
|
||||||
errors={errors}
|
/>
|
||||||
/>
|
</VStack>
|
||||||
</VStack>
|
<Button variant="solid" mt={4} type="submit" loading={isSubmitting}>
|
||||||
<Button
|
Save
|
||||||
variant="solid"
|
</Button>
|
||||||
mt={4}
|
</Box>
|
||||||
type="submit"
|
</Container>
|
||||||
loading={isSubmitting}
|
|
||||||
>
|
|
||||||
Save
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
</Container>
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
export default ChangePassword
|
export default ChangePassword
|
||||||
|
|||||||
@@ -49,60 +49,58 @@ const DeleteConfirmation = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<DialogRoot
|
||||||
<DialogRoot
|
size={{ base: "xs", md: "md" }}
|
||||||
size={{ base: "xs", md: "md" }}
|
role="alertdialog"
|
||||||
role="alertdialog"
|
placement="center"
|
||||||
placement="center"
|
open={isOpen}
|
||||||
open={isOpen}
|
onOpenChange={({ open }) => setIsOpen(open)}
|
||||||
onOpenChange={({ open }) => setIsOpen(open)}
|
>
|
||||||
>
|
<DialogTrigger asChild>
|
||||||
<DialogTrigger asChild>
|
<Button variant="solid" colorPalette="red" mt={4}>
|
||||||
<Button variant="solid" colorPalette="red" mt={4}>
|
Delete
|
||||||
Delete
|
</Button>
|
||||||
</Button>
|
</DialogTrigger>
|
||||||
</DialogTrigger>
|
|
||||||
|
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
<DialogCloseTrigger />
|
<DialogCloseTrigger />
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Confirmation Required</DialogTitle>
|
<DialogTitle>Confirmation Required</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<DialogBody>
|
<DialogBody>
|
||||||
<Text mb={4}>
|
<Text mb={4}>
|
||||||
All your account data will be{" "}
|
All your account data will be{" "}
|
||||||
<strong>permanently deleted.</strong> If you are sure, please
|
<strong>permanently deleted.</strong> If you are sure, please
|
||||||
click <strong>"Confirm"</strong> to proceed. This action cannot
|
click <strong>"Confirm"</strong> to proceed. This action cannot be
|
||||||
be undone.
|
undone.
|
||||||
</Text>
|
</Text>
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
|
|
||||||
<DialogFooter gap={2}>
|
<DialogFooter gap={2}>
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
<DialogActionTrigger asChild>
|
<DialogActionTrigger asChild>
|
||||||
<Button
|
|
||||||
variant="subtle"
|
|
||||||
colorPalette="gray"
|
|
||||||
disabled={isSubmitting}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</DialogActionTrigger>
|
|
||||||
<Button
|
<Button
|
||||||
variant="solid"
|
variant="subtle"
|
||||||
colorPalette="red"
|
colorPalette="gray"
|
||||||
type="submit"
|
disabled={isSubmitting}
|
||||||
loading={isSubmitting}
|
|
||||||
>
|
>
|
||||||
Delete
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
</ButtonGroup>
|
</DialogActionTrigger>
|
||||||
</DialogFooter>
|
<Button
|
||||||
</form>
|
variant="solid"
|
||||||
</DialogContent>
|
colorPalette="red"
|
||||||
</DialogRoot>
|
type="submit"
|
||||||
</>
|
loading={isSubmitting}
|
||||||
|
>
|
||||||
|
Delete
|
||||||
|
</Button>
|
||||||
|
</ButtonGroup>
|
||||||
|
</DialogFooter>
|
||||||
|
</form>
|
||||||
|
</DialogContent>
|
||||||
|
</DialogRoot>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import { type SubmitHandler, useForm } from "react-hook-form"
|
|||||||
import {
|
import {
|
||||||
type ApiError,
|
type ApiError,
|
||||||
type UserPublic,
|
type UserPublic,
|
||||||
type UserUpdateMe,
|
|
||||||
UsersService,
|
UsersService,
|
||||||
|
type UserUpdateMe,
|
||||||
} from "@/client"
|
} from "@/client"
|
||||||
import useAuth from "@/hooks/useAuth"
|
import useAuth from "@/hooks/useAuth"
|
||||||
import useCustomToast from "@/hooks/useCustomToast"
|
import useCustomToast from "@/hooks/useCustomToast"
|
||||||
@@ -70,80 +70,78 @@ const UserInformation = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Container maxW="full">
|
||||||
<Container maxW="full">
|
<Heading size="sm" py={4}>
|
||||||
<Heading size="sm" py={4}>
|
User Information
|
||||||
User Information
|
</Heading>
|
||||||
</Heading>
|
<Box
|
||||||
<Box
|
w={{ sm: "full", md: "sm" }}
|
||||||
w={{ sm: "full", md: "sm" }}
|
as="form"
|
||||||
as="form"
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
onSubmit={handleSubmit(onSubmit)}
|
>
|
||||||
>
|
<Field label="Full name">
|
||||||
<Field label="Full name">
|
{editMode ? (
|
||||||
{editMode ? (
|
<Input
|
||||||
<Input
|
{...register("full_name", { maxLength: 30 })}
|
||||||
{...register("full_name", { maxLength: 30 })}
|
type="text"
|
||||||
type="text"
|
size="md"
|
||||||
size="md"
|
/>
|
||||||
/>
|
) : (
|
||||||
) : (
|
<Text
|
||||||
<Text
|
fontSize="md"
|
||||||
fontSize="md"
|
py={2}
|
||||||
py={2}
|
color={!currentUser?.full_name ? "gray" : "inherit"}
|
||||||
color={!currentUser?.full_name ? "gray" : "inherit"}
|
truncate
|
||||||
truncate
|
maxW="sm"
|
||||||
maxW="sm"
|
|
||||||
>
|
|
||||||
{currentUser?.full_name || "N/A"}
|
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
</Field>
|
|
||||||
<Field
|
|
||||||
mt={4}
|
|
||||||
label="Email"
|
|
||||||
invalid={!!errors.email}
|
|
||||||
errorText={errors.email?.message}
|
|
||||||
>
|
|
||||||
{editMode ? (
|
|
||||||
<Input
|
|
||||||
{...register("email", {
|
|
||||||
required: "Email is required",
|
|
||||||
pattern: emailPattern,
|
|
||||||
})}
|
|
||||||
type="email"
|
|
||||||
size="md"
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Text fontSize="md" py={2} truncate maxW="sm">
|
|
||||||
{currentUser?.email}
|
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
</Field>
|
|
||||||
<Flex mt={4} gap={3}>
|
|
||||||
<Button
|
|
||||||
variant="solid"
|
|
||||||
onClick={toggleEditMode}
|
|
||||||
type={editMode ? "button" : "submit"}
|
|
||||||
loading={editMode ? isSubmitting : false}
|
|
||||||
disabled={editMode ? !isDirty || !getValues("email") : false}
|
|
||||||
>
|
>
|
||||||
{editMode ? "Save" : "Edit"}
|
{currentUser?.full_name || "N/A"}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</Field>
|
||||||
|
<Field
|
||||||
|
mt={4}
|
||||||
|
label="Email"
|
||||||
|
invalid={!!errors.email}
|
||||||
|
errorText={errors.email?.message}
|
||||||
|
>
|
||||||
|
{editMode ? (
|
||||||
|
<Input
|
||||||
|
{...register("email", {
|
||||||
|
required: "Email is required",
|
||||||
|
pattern: emailPattern,
|
||||||
|
})}
|
||||||
|
type="email"
|
||||||
|
size="md"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Text fontSize="md" py={2} truncate maxW="sm">
|
||||||
|
{currentUser?.email}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</Field>
|
||||||
|
<Flex mt={4} gap={3}>
|
||||||
|
<Button
|
||||||
|
variant="solid"
|
||||||
|
onClick={toggleEditMode}
|
||||||
|
type={editMode ? "button" : "submit"}
|
||||||
|
loading={editMode ? isSubmitting : false}
|
||||||
|
disabled={editMode ? !isDirty || !getValues("email") : false}
|
||||||
|
>
|
||||||
|
{editMode ? "Save" : "Edit"}
|
||||||
|
</Button>
|
||||||
|
{editMode && (
|
||||||
|
<Button
|
||||||
|
variant="subtle"
|
||||||
|
colorPalette="gray"
|
||||||
|
onClick={onCancel}
|
||||||
|
disabled={isSubmitting}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
{editMode && (
|
)}
|
||||||
<Button
|
</Flex>
|
||||||
variant="subtle"
|
</Box>
|
||||||
colorPalette="gray"
|
</Container>
|
||||||
onClick={onCancel}
|
|
||||||
disabled={isSubmitting}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</Flex>
|
|
||||||
</Box>
|
|
||||||
</Container>
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,12 @@ import {
|
|||||||
QueryClient,
|
QueryClient,
|
||||||
QueryClientProvider,
|
QueryClientProvider,
|
||||||
} from "@tanstack/react-query"
|
} from "@tanstack/react-query"
|
||||||
import { RouterProvider, createRouter } from "@tanstack/react-router"
|
import { createRouter, RouterProvider } from "@tanstack/react-router"
|
||||||
import { StrictMode } from "react"
|
import { StrictMode } from "react"
|
||||||
import ReactDOM from "react-dom/client"
|
import ReactDOM from "react-dom/client"
|
||||||
import { routeTree } from "./routeTree.gen"
|
|
||||||
|
|
||||||
import { ApiError, OpenAPI } from "./client"
|
import { ApiError, OpenAPI } from "./client"
|
||||||
import { CustomProvider } from "./components/ui/provider"
|
import { CustomProvider } from "./components/ui/provider"
|
||||||
|
import { routeTree } from "./routeTree.gen"
|
||||||
|
|
||||||
OpenAPI.BASE = import.meta.env.VITE_API_URL
|
OpenAPI.BASE = import.meta.env.VITE_API_URL
|
||||||
OpenAPI.TOKEN = async () => {
|
OpenAPI.TOKEN = async () => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Outlet, createRootRoute } from "@tanstack/react-router"
|
import { createRootRoute, Outlet } from "@tanstack/react-router"
|
||||||
import React, { Suspense } from "react"
|
import React, { Suspense } from "react"
|
||||||
|
|
||||||
import NotFound from "@/components/Common/NotFound"
|
import NotFound from "@/components/Common/NotFound"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Flex } from "@chakra-ui/react"
|
import { Flex } from "@chakra-ui/react"
|
||||||
import { Outlet, createFileRoute, redirect } from "@tanstack/react-router"
|
import { createFileRoute, Outlet, redirect } from "@tanstack/react-router"
|
||||||
|
|
||||||
import Navbar from "@/components/Common/Navbar"
|
import Navbar from "@/components/Common/Navbar"
|
||||||
import Sidebar from "@/components/Common/Sidebar"
|
import Sidebar from "@/components/Common/Sidebar"
|
||||||
|
|||||||
@@ -11,15 +11,13 @@ function Dashboard() {
|
|||||||
const { user: currentUser } = useAuth()
|
const { user: currentUser } = useAuth()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Container maxW="full">
|
||||||
<Container maxW="full">
|
<Box pt={12} m={4}>
|
||||||
<Box pt={12} m={4}>
|
<Text fontSize="2xl" truncate maxW="sm">
|
||||||
<Text fontSize="2xl" truncate maxW="sm">
|
Hi, {currentUser?.full_name || currentUser?.email} 👋🏼
|
||||||
Hi, {currentUser?.full_name || currentUser?.email} 👋🏼
|
</Text>
|
||||||
</Text>
|
<Text>Welcome back, nice to see you again!</Text>
|
||||||
<Text>Welcome back, nice to see you again!</Text>
|
</Box>
|
||||||
</Box>
|
</Container>
|
||||||
</Container>
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Container, Image, Input, Text } from "@chakra-ui/react"
|
import { Container, Image, Input, Text } from "@chakra-ui/react"
|
||||||
import {
|
import {
|
||||||
Link as RouterLink,
|
|
||||||
createFileRoute,
|
createFileRoute,
|
||||||
|
Link as RouterLink,
|
||||||
redirect,
|
redirect,
|
||||||
} from "@tanstack/react-router"
|
} from "@tanstack/react-router"
|
||||||
import { type SubmitHandler, useForm } from "react-hook-form"
|
import { type SubmitHandler, useForm } from "react-hook-form"
|
||||||
@@ -55,61 +55,58 @@ function Login() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Container
|
||||||
<Container
|
as="form"
|
||||||
as="form"
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
onSubmit={handleSubmit(onSubmit)}
|
h="100vh"
|
||||||
h="100vh"
|
maxW="sm"
|
||||||
maxW="sm"
|
alignItems="stretch"
|
||||||
alignItems="stretch"
|
justifyContent="center"
|
||||||
justifyContent="center"
|
gap={4}
|
||||||
gap={4}
|
centerContent
|
||||||
centerContent
|
>
|
||||||
|
<Image
|
||||||
|
src={Logo}
|
||||||
|
alt="FastAPI logo"
|
||||||
|
height="auto"
|
||||||
|
maxW="2xs"
|
||||||
|
alignSelf="center"
|
||||||
|
mb={4}
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
invalid={!!errors.username}
|
||||||
|
errorText={errors.username?.message || !!error}
|
||||||
>
|
>
|
||||||
<Image
|
<InputGroup w="100%" startElement={<FiMail />}>
|
||||||
src={Logo}
|
<Input
|
||||||
alt="FastAPI logo"
|
{...register("username", {
|
||||||
height="auto"
|
required: "Username is required",
|
||||||
maxW="2xs"
|
pattern: emailPattern,
|
||||||
alignSelf="center"
|
})}
|
||||||
mb={4}
|
placeholder="Email"
|
||||||
/>
|
type="email"
|
||||||
<Field
|
/>
|
||||||
invalid={!!errors.username}
|
</InputGroup>
|
||||||
errorText={errors.username?.message || !!error}
|
</Field>
|
||||||
>
|
<PasswordInput
|
||||||
<InputGroup w="100%" startElement={<FiMail />}>
|
type="password"
|
||||||
<Input
|
startElement={<FiLock />}
|
||||||
id="username"
|
{...register("password", passwordRules())}
|
||||||
{...register("username", {
|
placeholder="Password"
|
||||||
required: "Username is required",
|
errors={errors}
|
||||||
pattern: emailPattern,
|
/>
|
||||||
})}
|
<RouterLink to="/recover-password" className="main-link">
|
||||||
placeholder="Email"
|
Forgot Password?
|
||||||
type="email"
|
</RouterLink>
|
||||||
/>
|
<Button variant="solid" type="submit" loading={isSubmitting} size="md">
|
||||||
</InputGroup>
|
Log In
|
||||||
</Field>
|
</Button>
|
||||||
<PasswordInput
|
<Text>
|
||||||
type="password"
|
Don't have an account?{" "}
|
||||||
startElement={<FiLock />}
|
<RouterLink to="/signup" className="main-link">
|
||||||
{...register("password", passwordRules())}
|
Sign Up
|
||||||
placeholder="Password"
|
|
||||||
errors={errors}
|
|
||||||
/>
|
|
||||||
<RouterLink to="/recover-password" className="main-link">
|
|
||||||
Forgot Password?
|
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<Button variant="solid" type="submit" loading={isSubmitting} size="md">
|
</Text>
|
||||||
Log In
|
</Container>
|
||||||
</Button>
|
|
||||||
<Text>
|
|
||||||
Don't have an account?{" "}
|
|
||||||
<RouterLink to="/signup" className="main-link">
|
|
||||||
Sign Up
|
|
||||||
</RouterLink>
|
|
||||||
</Text>
|
|
||||||
</Container>
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ function RecoverPassword() {
|
|||||||
<Field invalid={!!errors.email} errorText={errors.email?.message}>
|
<Field invalid={!!errors.email} errorText={errors.email?.message}>
|
||||||
<InputGroup w="100%" startElement={<FiMail />}>
|
<InputGroup w="100%" startElement={<FiMail />}>
|
||||||
<Input
|
<Input
|
||||||
id="email"
|
|
||||||
{...register("email", {
|
{...register("email", {
|
||||||
required: "Email is required",
|
required: "Email is required",
|
||||||
pattern: emailPattern,
|
pattern: emailPattern,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Container, Flex, Image, Input, Text } from "@chakra-ui/react"
|
import { Container, Flex, Image, Input, Text } from "@chakra-ui/react"
|
||||||
import {
|
import {
|
||||||
Link as RouterLink,
|
|
||||||
createFileRoute,
|
createFileRoute,
|
||||||
|
Link as RouterLink,
|
||||||
redirect,
|
redirect,
|
||||||
} from "@tanstack/react-router"
|
} from "@tanstack/react-router"
|
||||||
import { type SubmitHandler, useForm } from "react-hook-form"
|
import { type SubmitHandler, useForm } from "react-hook-form"
|
||||||
@@ -54,82 +54,78 @@ function SignUp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Flex flexDir={{ base: "column", md: "row" }} justify="center" h="100vh">
|
||||||
<Flex flexDir={{ base: "column", md: "row" }} justify="center" h="100vh">
|
<Container
|
||||||
<Container
|
as="form"
|
||||||
as="form"
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
onSubmit={handleSubmit(onSubmit)}
|
h="100vh"
|
||||||
h="100vh"
|
maxW="sm"
|
||||||
maxW="sm"
|
alignItems="stretch"
|
||||||
alignItems="stretch"
|
justifyContent="center"
|
||||||
justifyContent="center"
|
gap={4}
|
||||||
gap={4}
|
centerContent
|
||||||
centerContent
|
>
|
||||||
|
<Image
|
||||||
|
src={Logo}
|
||||||
|
alt="FastAPI logo"
|
||||||
|
height="auto"
|
||||||
|
maxW="2xs"
|
||||||
|
alignSelf="center"
|
||||||
|
mb={4}
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
invalid={!!errors.full_name}
|
||||||
|
errorText={errors.full_name?.message}
|
||||||
>
|
>
|
||||||
<Image
|
<InputGroup w="100%" startElement={<FiUser />}>
|
||||||
src={Logo}
|
<Input
|
||||||
alt="FastAPI logo"
|
minLength={3}
|
||||||
height="auto"
|
{...register("full_name", {
|
||||||
maxW="2xs"
|
required: "Full Name is required",
|
||||||
alignSelf="center"
|
})}
|
||||||
mb={4}
|
placeholder="Full Name"
|
||||||
/>
|
type="text"
|
||||||
<Field
|
/>
|
||||||
invalid={!!errors.full_name}
|
</InputGroup>
|
||||||
errorText={errors.full_name?.message}
|
</Field>
|
||||||
>
|
|
||||||
<InputGroup w="100%" startElement={<FiUser />}>
|
|
||||||
<Input
|
|
||||||
id="full_name"
|
|
||||||
minLength={3}
|
|
||||||
{...register("full_name", {
|
|
||||||
required: "Full Name is required",
|
|
||||||
})}
|
|
||||||
placeholder="Full Name"
|
|
||||||
type="text"
|
|
||||||
/>
|
|
||||||
</InputGroup>
|
|
||||||
</Field>
|
|
||||||
|
|
||||||
<Field invalid={!!errors.email} errorText={errors.email?.message}>
|
<Field invalid={!!errors.email} errorText={errors.email?.message}>
|
||||||
<InputGroup w="100%" startElement={<FiUser />}>
|
<InputGroup w="100%" startElement={<FiUser />}>
|
||||||
<Input
|
<Input
|
||||||
id="email"
|
{...register("email", {
|
||||||
{...register("email", {
|
required: "Email is required",
|
||||||
required: "Email is required",
|
pattern: emailPattern,
|
||||||
pattern: emailPattern,
|
})}
|
||||||
})}
|
placeholder="Email"
|
||||||
placeholder="Email"
|
type="email"
|
||||||
type="email"
|
/>
|
||||||
/>
|
</InputGroup>
|
||||||
</InputGroup>
|
</Field>
|
||||||
</Field>
|
<PasswordInput
|
||||||
<PasswordInput
|
type="password"
|
||||||
type="password"
|
startElement={<FiLock />}
|
||||||
startElement={<FiLock />}
|
{...register("password", passwordRules())}
|
||||||
{...register("password", passwordRules())}
|
placeholder="Password"
|
||||||
placeholder="Password"
|
errors={errors}
|
||||||
errors={errors}
|
/>
|
||||||
/>
|
<PasswordInput
|
||||||
<PasswordInput
|
type="confirm_password"
|
||||||
type="confirm_password"
|
startElement={<FiLock />}
|
||||||
startElement={<FiLock />}
|
{...register("confirm_password", confirmPasswordRules(getValues))}
|
||||||
{...register("confirm_password", confirmPasswordRules(getValues))}
|
placeholder="Confirm Password"
|
||||||
placeholder="Confirm Password"
|
errors={errors}
|
||||||
errors={errors}
|
/>
|
||||||
/>
|
<Button variant="solid" type="submit" loading={isSubmitting}>
|
||||||
<Button variant="solid" type="submit" loading={isSubmitting}>
|
Sign Up
|
||||||
Sign Up
|
</Button>
|
||||||
</Button>
|
<Text>
|
||||||
<Text>
|
Already have an account?{" "}
|
||||||
Already have an account?{" "}
|
<RouterLink to="/login" className="main-link">
|
||||||
<RouterLink to="/login" className="main-link">
|
Log In
|
||||||
Log In
|
</RouterLink>
|
||||||
</RouterLink>
|
</Text>
|
||||||
</Text>
|
</Container>
|
||||||
</Container>
|
</Flex>
|
||||||
</Flex>
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { type Page, expect, test } from "@playwright/test"
|
import { expect, type Page, test } from "@playwright/test"
|
||||||
import { firstSuperuser, firstSuperuserPassword } from "./config.ts"
|
import { firstSuperuser, firstSuperuserPassword } from "./config.ts"
|
||||||
import { randomPassword } from "./utils/random.ts"
|
import { randomPassword } from "./utils/random.ts"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { type Page, expect, test } from "@playwright/test"
|
import { expect, type Page, test } from "@playwright/test"
|
||||||
|
|
||||||
import { randomEmail, randomPassword } from "./utils/random"
|
import { randomEmail, randomPassword } from "./utils/random"
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ type Email = {
|
|||||||
async function findEmail({
|
async function findEmail({
|
||||||
request,
|
request,
|
||||||
filter,
|
filter,
|
||||||
}: { request: APIRequestContext; filter?: (email: Email) => boolean }) {
|
}: {
|
||||||
|
request: APIRequestContext
|
||||||
|
filter?: (email: Email) => boolean
|
||||||
|
}) {
|
||||||
const response = await request.get(`${process.env.MAILCATCHER_HOST}/messages`)
|
const response = await request.get(`${process.env.MAILCATCHER_HOST}/messages`)
|
||||||
|
|
||||||
let emails = await response.json()
|
let emails = await response.json()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { type Page, expect } from "@playwright/test"
|
import { expect, type Page } from "@playwright/test"
|
||||||
|
|
||||||
export async function signUpNewUser(
|
export async function signUpNewUser(
|
||||||
page: Page,
|
page: Page,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import path from "node:path"
|
import path from "node:path"
|
||||||
import { tanstackRouter } from '@tanstack/router-plugin/vite'
|
import { tanstackRouter } from "@tanstack/router-plugin/vite"
|
||||||
import react from "@vitejs/plugin-react-swc"
|
import react from "@vitejs/plugin-react-swc"
|
||||||
import { defineConfig } from "vite"
|
import { defineConfig } from "vite"
|
||||||
|
|
||||||
@@ -15,5 +15,6 @@ export default defineConfig({
|
|||||||
target: "react",
|
target: "react",
|
||||||
autoCodeSplitting: true,
|
autoCodeSplitting: true,
|
||||||
}),
|
}),
|
||||||
react()],
|
react(),
|
||||||
|
],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -8,5 +8,4 @@ python -c "import app.main; import json; print(json.dumps(app.main.app.openapi()
|
|||||||
cd ..
|
cd ..
|
||||||
mv openapi.json frontend/
|
mv openapi.json frontend/
|
||||||
cd frontend
|
cd frontend
|
||||||
npm run generate-client
|
npm run generate-client
|
||||||
npx biome format --write ./src/client
|
|
||||||
Reference in New Issue
Block a user