Create a typescript client library for the server
This commit is contained in:
parent
79af050f53
commit
182020e136
2
visions/client/.gitignore
vendored
Normal file
2
visions/client/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
gen/
|
||||
dist/
|
12
visions/client/Taskfile.yml
Normal file
12
visions/client/Taskfile.yml
Normal file
@ -0,0 +1,12 @@
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
fmt:
|
||||
cmds:
|
||||
- npx prettier -w package.json src
|
||||
|
||||
build:
|
||||
cmds:
|
||||
- npm install typescript
|
||||
- typeshare --lang typescript --output-file gen/types.ts ../server/src
|
||||
- npx tsc
|
29
visions/client/eslint.config.js
Normal file
29
visions/client/eslint.config.js
Normal file
@ -0,0 +1,29 @@
|
||||
import js from "@eslint/js";
|
||||
import globals from "globals";
|
||||
import reactHooks from "eslint-plugin-react-hooks";
|
||||
import reactRefresh from "eslint-plugin-react-refresh";
|
||||
import tseslint from "typescript-eslint";
|
||||
import eslintConfigPrettier from "eslint-config-prettier";
|
||||
|
||||
export default tseslint.config(
|
||||
{ ignores: ["dist"] },
|
||||
{
|
||||
extends: [js.configs.recommended, ...tseslint.configs.recommended, eslintConfigPrettier],
|
||||
files: ["**/*.{ts,tsx}"],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2020,
|
||||
globals: globals.browser,
|
||||
},
|
||||
plugins: {
|
||||
"react-hooks": reactHooks,
|
||||
"react-refresh": reactRefresh,
|
||||
},
|
||||
rules: {
|
||||
...reactHooks.configs.recommended.rules,
|
||||
"react-refresh/only-export-components": [
|
||||
"warn",
|
||||
{ allowConstantExport: true },
|
||||
],
|
||||
},
|
||||
},
|
||||
);
|
3813
visions/client/package-lock.json
generated
Normal file
3813
visions/client/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
21
visions/client/package.json
Normal file
21
visions/client/package.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "visions-client",
|
||||
"version": "0.0.1",
|
||||
"description": "Shared data types for Visions",
|
||||
"main": "visions.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"prettier": {
|
||||
"singleQuote": true,
|
||||
"semi": false,
|
||||
"tabWidth": 4
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^3.5.1",
|
||||
"ts-jest": "^29.2.5",
|
||||
"typescript": "^5.7.3"
|
||||
}
|
||||
}
|
42
visions/client/src/client.ts
Normal file
42
visions/client/src/client.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { VResponse, SessionId } from '../gen/types'
|
||||
|
||||
export interface Client {
|
||||
auth: (
|
||||
username: string,
|
||||
password: string,
|
||||
) => Promise<ClientResponse<SessionId>>
|
||||
}
|
||||
|
||||
export type ClientResponse<A> =
|
||||
| { status: 'ok'; content: VResponse<A> }
|
||||
| { status: 'unauthorized' }
|
||||
| { status: 'unexpected'; code: number }
|
||||
|
||||
export class Connection implements Client {
|
||||
private base: URL
|
||||
// private sessionId: string | undefined;
|
||||
|
||||
constructor(baseUrl: URL) {
|
||||
this.base = baseUrl
|
||||
}
|
||||
|
||||
async auth(
|
||||
username: string,
|
||||
password: string,
|
||||
): Promise<ClientResponse<SessionId>> {
|
||||
const url = new URL(this.base)
|
||||
url.pathname = `/api/v1/auth`
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: [['Content-Type', 'application/json']],
|
||||
body: JSON.stringify({ username: username, password: password }),
|
||||
})
|
||||
if (response.ok) {
|
||||
return await response.json()
|
||||
} else if (response.status == 401) {
|
||||
return { status: 'unauthorized' }
|
||||
} else {
|
||||
return { status: 'unexpected', code: response.status }
|
||||
}
|
||||
}
|
||||
}
|
@ -11,5 +11,5 @@
|
||||
"strict": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["./visions.ts"]
|
||||
"include": ["gen", "src"]
|
||||
}
|
15
visions/client/visions.ts
Normal file
15
visions/client/visions.ts
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
Generated by typeshare 1.13.0
|
||||
*/
|
||||
|
||||
export type SessionId = string;
|
||||
|
||||
export interface AuthRequest {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export type AuthResponse =
|
||||
| { type: "Success", content: SessionId }
|
||||
| { type: "PasswordReset", content: SessionId };
|
||||
|
@ -38,19 +38,20 @@ impl From<String> for SessionId {
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[serde(tag = "type", content = "content")]
|
||||
#[typeshare]
|
||||
enum AuthResponse {
|
||||
Success(SessionId),
|
||||
PasswordReset(SessionId),
|
||||
enum VResponse<A> {
|
||||
Success(A),
|
||||
PasswordReset(A),
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
async fn check_password(request: Json<AuthRequest>) -> (StatusCode, Json<Option<AuthResponse>>) {
|
||||
async fn check_password(request: Json<AuthRequest>) -> (StatusCode, Json<Option<VResponse<SessionId>>>) {
|
||||
let Json(request) = request;
|
||||
if request.username == "vakarian" && request.password == "aoeu" {
|
||||
(StatusCode::OK, Json(Some(AuthResponse::Success("vakarian-session-id".into()))))
|
||||
(StatusCode::OK, Json(Some(VResponse::Success("vakarian-session-id".into()))))
|
||||
} else if request.username == "shephard" && request.password == "aoeu" {
|
||||
(StatusCode::OK, Json(Some(AuthResponse::PasswordReset("shephard-session-id".into()))))
|
||||
(StatusCode::OK, Json(Some(VResponse::PasswordReset("shephard-session-id".into()))))
|
||||
} else {
|
||||
(StatusCode::UNAUTHORIZED, Json(None))
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
build:
|
||||
cmds:
|
||||
- npm install typescript
|
||||
- typeshare --lang typescript --output-file visions.ts ../server/src
|
||||
- npx tsc
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"name": "visions-types",
|
||||
"version": "0.0.1",
|
||||
"description": "Shared data types for Visions",
|
||||
"main": "visions.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"typescript": "^5.7.3"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user