-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
15 additions
and
323 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,175 +0,0 @@ | ||
export interface Get< | ||
PathParams = { [key: string]: unknown }, | ||
QueryParams = { [key: string]: unknown }, | ||
Output = { [key: string]: unknown } | ||
> { | ||
parameters: { | ||
path?: PathParams; | ||
query: QueryParams; | ||
}; | ||
responses: { | ||
200: Output; | ||
}; | ||
} | ||
|
||
export interface Post< | ||
PathParams = { [key: string]: unknown }, | ||
RequestBody = { [key: string]: unknown }, | ||
QueryParams = { [key: string]: unknown }, | ||
Output = { [key: string]: unknown } | ||
> { | ||
parameters: { | ||
path?: PathParams; | ||
body: RequestBody; | ||
query?: QueryParams; | ||
}; | ||
responses: { | ||
200: Output; | ||
}; | ||
} | ||
|
||
export interface Put< | ||
PathParams = { [key: string]: unknown }, | ||
RequestBody = { [key: string]: unknown }, | ||
QueryParams = { [key: string]: unknown }, | ||
Output = { [key: string]: unknown } | ||
> { | ||
parameters: { | ||
path?: PathParams; | ||
body: RequestBody; | ||
query?: QueryParams; | ||
}; | ||
responses: { | ||
200: Output; | ||
}; | ||
} | ||
|
||
export interface Delete< | ||
PathParams = { [key: string]: unknown }, | ||
QueryParams = { [key: string]: unknown }, | ||
Output = { [key: string]: unknown } | ||
> { | ||
parameters: { | ||
path?: PathParams; | ||
query: QueryParams; | ||
}; | ||
responses: { | ||
200: Output; | ||
}; | ||
} | ||
|
||
export interface Patch< | ||
PathParams = { [key: string]: unknown }, | ||
RequestBody = { [key: string]: unknown }, | ||
QueryParams = { [key: string]: unknown }, | ||
Output = { [key: string]: unknown } | ||
> { | ||
parameters: { | ||
path?: PathParams; | ||
body: RequestBody; | ||
query?: QueryParams; | ||
}; | ||
responses: { | ||
200: Output; | ||
}; | ||
} | ||
|
||
export type RecursiveJSONSchema = { | ||
description?: string; | ||
type: string; | ||
const?: string; | ||
format?: string; | ||
properties?: { | ||
[key: string]: RecursiveJSONSchema; | ||
}; | ||
items?: RecursiveJSONSchema; | ||
required?: string[]; | ||
}; | ||
import type { Prisma } from "/root/dev/svetch/node_modules/.prisma/client/index"; | ||
|
||
export interface APIPaths { | ||
"api.prisma.:id": { | ||
POST: { | ||
parameters: { | ||
body: { | ||
id?: string; | ||
email: string; | ||
name?: string; | ||
password: string; | ||
createdAt?: string | Date; | ||
updatedAt?: string | Date; | ||
posts?: Prisma.PostCreateNestedManyWithoutAuthorInput; | ||
}; | ||
path: { id: string }; | ||
}; | ||
responses: { | ||
200: { | ||
posts: Array<{ | ||
id: string; | ||
title: string; | ||
content: string; | ||
createdAt: Date; | ||
updatedAt: Date; | ||
authorId: string; | ||
}>; | ||
id: string; | ||
email: string; | ||
name: string; | ||
password: string; | ||
createdAt: Date; | ||
updatedAt: Date; | ||
uwu: { uwu: { uwu: { uwu: "owo" } } }; | ||
}; | ||
}; | ||
errors?: never; | ||
}; | ||
PATCH: { | ||
parameters: { | ||
body: { | ||
id?: string | { set?: string }; | ||
email?: string | { set?: string }; | ||
name?: string | { set?: string }; | ||
password?: string | { set?: string }; | ||
createdAt?: string | Date | { set?: string | Date }; | ||
updatedAt?: string | Date | { set?: string | Date }; | ||
posts?: Prisma.PostUpdateManyWithoutAuthorNestedInput; | ||
}; | ||
path: { id: string }; | ||
query: { query: string; number: number }; | ||
}; | ||
responses: { | ||
200: { | ||
author: { | ||
id: string; | ||
email: string; | ||
name: string; | ||
password: string; | ||
createdAt: Date; | ||
updatedAt: Date; | ||
}; | ||
id: string; | ||
title: string; | ||
content: string; | ||
createdAt: Date; | ||
updatedAt: Date; | ||
authorId: string; | ||
uwu: { uwu: { uwu: { uwu: "owo" } } }; | ||
}; | ||
}; | ||
errors: { | ||
400: [ | ||
{ | ||
message: "Bad Request"; | ||
} | ||
]; | ||
500: [ | ||
{ | ||
message: "Internal Server Error"; | ||
} | ||
]; | ||
}; | ||
}; | ||
}; | ||
} | ||
|
||
export interface ActionPaths {} | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,141 +0,0 @@ | ||
import type { APIPaths } from './api' | ||
import type { APIPaths } from './api' | ||
|
||
export type Fetch = (input: string | RequestInfo | URL, init?: RequestInit) => Promise<Response> | ||
|
||
type EndpointMethod<EP extends keyof APIPaths, M extends keyof APIPaths[EP]> = APIPaths[EP][M] | ||
|
||
type Params<M extends EndpointMethod<any, any>> = M extends { parameters: infer P } | ||
? { [K in keyof P]: undefined extends P[K] ? P[K] | undefined : P[K] } | ||
: never | ||
|
||
type SuccessResponse<M extends EndpointMethod<any, any>> = M extends { responses: { 200: infer S } } | ||
? S | ||
: never | ||
|
||
type ErrorResponse<M extends EndpointMethod<any, any>> = M extends { errors: infer E } ? E : never | ||
|
||
type ExtendedResponse<EP extends keyof APIPaths, M extends keyof APIPaths[EP]> = Response & { | ||
data?: SuccessResponse<APIPaths[EP][M]> | ||
error?: ErrorResponse<APIPaths[EP][M]> | ||
} | ||
|
||
type EndpointsSupportingMethod<M extends keyof any, API extends Record<string, any>> = { | ||
[K in keyof API]: M extends keyof API[K] ? K : never | ||
}[keyof API] | ||
|
||
export class Svetch { | ||
private baseURL: string | ||
private fetch: Fetch | ||
private validate: boolean | ||
|
||
constructor(baseURL: string = '', fetchInstance?: Fetch, validate: boolean = true) { | ||
this.baseURL = baseURL | ||
this.fetch = fetchInstance || (fetch as Fetch) | ||
this.validate = false | ||
} | ||
|
||
error(status: number, message: string) { | ||
const err = new Error(message) | ||
// @ts-ignore | ||
err.sta | ||
} | ||
|
||
async request<EP extends keyof APIPaths, M extends keyof APIPaths[EP]>( | ||
endpoint: EP, | ||
method: M, | ||
options: Params<EndpointMethod<EP, M>> | ||
): Promise<ExtendedResponse<EP, M>> { | ||
const { path, query, body } = options | ||
let updatedEndpoint = endpoint as string | ||
|
||
if (path) { | ||
for (const [key, value] of Object.entries(path)) { | ||
updatedEndpoint = updatedEndpoint.replace(`:${key}`, value as string) | ||
} | ||
} | ||
|
||
let queryStr = '' | ||
if (query) { | ||
queryStr = | ||
'?' + | ||
Object.entries(query) | ||
.map(([key, value]) => `${key}=${value.toString()}`) | ||
.join('&') | ||
} | ||
|
||
if (this.validate && body) { | ||
try { | ||
schema.shape[endpoint]?.shape[method]?.shape.parameters.shape.body.parse(body) | ||
} catch (err) { | ||
console.log(`Request body is invalid`, err) | ||
throw err | ||
} | ||
} | ||
|
||
const response: ExtendedResponse<EP, M> = (await this.fetch( | ||
`${this.baseURL}/${updatedEndpoint + queryStr}`, | ||
{ | ||
body: JSON.stringify(body), | ||
method: method as string | ||
} | ||
)) as ExtendedResponse<EP, M> | ||
|
||
if (!response.ok) { | ||
const errorResponse = await response.json() | ||
response.error = errorResponse as ErrorResponse<APIPaths[EP][M]> | ||
return response | ||
} | ||
|
||
const responseData = await response.json() | ||
|
||
if (this.validate && responseData) { | ||
try { | ||
schema.shape[endpoint]?.shape[method]?.shape.responses.shape[response.status].parse( | ||
responseData | ||
) | ||
} catch (err) { | ||
console.log(`Response data is invalid`, err) | ||
} | ||
} | ||
response.data = responseData as SuccessResponse<APIPaths[EP][M]> | ||
return response | ||
} | ||
|
||
get<EP extends EndpointsSupportingMethod<'GET', APIPaths>, M extends 'GET' & keyof APIPaths[EP]>( | ||
endpoint: EP, | ||
parameters: Params<EndpointMethod<EP, M>> | ||
) { | ||
return this.request(endpoint, 'GET', parameters) | ||
} | ||
|
||
post< | ||
EP extends EndpointsSupportingMethod<'POST', APIPaths>, | ||
M extends 'POST' & keyof APIPaths[EP] | ||
>(endpoint: EP, parameters: Params<EndpointMethod<EP, M>>) { | ||
return this.request(endpoint, 'POST', parameters) | ||
} | ||
|
||
put<EP extends EndpointsSupportingMethod<'PUT', APIPaths>, M extends 'PUT' & keyof APIPaths[EP]>( | ||
endpoint: EP, | ||
parameters: Params<EndpointMethod<EP, M>> | ||
) { | ||
return this.request(endpoint, 'PUT', parameters) | ||
} | ||
|
||
patch< | ||
EP extends EndpointsSupportingMethod<'PATCH', APIPaths>, | ||
M extends 'PATCH' & keyof APIPaths[EP] | ||
>(endpoint: EP, parameters: Params<EndpointMethod<EP, M>>) { | ||
return this.request(endpoint, 'PATCH', parameters) | ||
} | ||
|
||
delete< | ||
EP extends EndpointsSupportingMethod<'DELETE', APIPaths>, | ||
M extends 'DELETE' & keyof APIPaths[EP] | ||
>(endpoint: EP, parameters: Params<EndpointMethod<EP, M>>) { | ||
return this.request(endpoint, 'DELETE', parameters) | ||
} | ||
} | ||
|
||
export const SvelteClient = new Svetch() | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters