Files
BewlyBewly/src/composables/api.ts
Hakadao dd24072f02 Refactor/rpc (#700)
* refactor(rpc): improve type, and type safe (#673)

* refactor(rpc): improve type, and type safe

* revert `pnpm-lock.yaml` file

* improve api merge

* fix: type annotation in background/index.ts

* fix: type annotation in background/index.ts

---------

Co-authored-by: star knight <64941905+starknt@users.noreply.github.com>
2024-05-02 02:45:59 +08:00

54 lines
1.6 KiB
TypeScript

import type { API_COLLECTION } from '~/background/messageListeners'
type CamelCase<S extends string> = S extends `${infer P1}_${infer P2}${infer P3}`
? `${Lowercase<P1>}${Uppercase<P2>}${CamelCase<P3>}`
: Lowercase<S>
type APIFunction<T = typeof API_COLLECTION> = {
[K in keyof T as CamelCase<string & K>]: {
// @ts-expect-error allow params
[P in keyof T[K]]: T[K][P] extends Function ? T[K][P] : Lowercase<T[K][P]['_fetch']['method']> extends 'get' ? (options?: Partial<T[K][P]['params']>) => Promise<any> : (options?: Partial<T[K][P]['params'] & T[K][P]['_fetch']['body']>) => Promise<any>
}
}
// eslint-disable-next-line ts/no-unsafe-declaration-merging
export interface APIClient extends APIFunction<typeof API_COLLECTION> {
}
// eslint-disable-next-line ts/no-unsafe-declaration-merging
export class APIClient {
private readonly cache = new Map<string | symbol, any>()
constructor() {
// @ts-expect-error ignore
return new Proxy({}, {
get: (_, namespace) => { // namespace
if (this.cache.has(namespace)) {
return this.cache.get(namespace)
}
else {
const api = new Proxy({}, {
get(_, p) {
return (options?: object) => {
return browser.runtime.sendMessage({
contentScriptQuery: p,
...options,
})
}
},
})
this.cache.set(namespace, api)
return api
}
},
})
}
}
const api = new APIClient()
export function useApiClient() {
return api
}