framework: support providing api at namespace

This commit is contained in:
undefined committed 2025-08-20 17:08:11 +08:00
1 parent 5e72aee41b
commit 5e85f9c753
2 files changed
+9 -7

No files matched your search

+8 -6
View File
@@ -11,7 +11,7 @@ const REDIRECT = Symbol.for('hydro.api.response.redirect');
type MaybePromise<T> = T | Promise<T>; type MaybePromise<T> = T | Promise<T>;
export type ApiType = 'Query' | 'Mutation' | 'Subscription'; export type ApiType = 'Query' | 'Mutation' | 'Subscription';
export interface ApiCall<Type extends ApiType, Arg, Res, Progress = never> { export interface ApiCall<Type extends ApiType, Arg, Res, Progress = void> {
readonly type: Type; readonly type: Type;
readonly input: Schema<Arg>; readonly input: Schema<Arg>;
readonly func: (Type extends 'Subscription' readonly func: (Type extends 'Subscription'
@@ -20,10 +20,10 @@ export interface ApiCall<Type extends ApiType, Arg, Res, Progress = never> {
readonly hooks: ApiCall<'Query', Arg, void>[]; readonly hooks: ApiCall<'Query', Arg, void>[];
} }
export const _get = <Type extends ApiType>(type: Type) => <Arg, Res, Progress>( export const _get = <Type extends ApiType>(type: Type) => <Arg, Res, Progress = void>(
schema: Schema<Arg>, schema: Schema<Arg>,
func: ApiCall<Type, Arg, Res, Progress>['func'], func: ApiCall<Type, Arg, Res, Progress>['func'],
hooks: ApiCall<'Query', Arg, void, never>[] = [], hooks: ApiCall<'Query', Arg, void, void>[] = [],
): ApiCall<Type, Arg, Res, Progress> => ({ input: schema, func, hooks, type } as const); ): ApiCall<Type, Arg, Res, Progress> => ({ input: schema, func, hooks, type } as const);
export const Query = _get('Query'); export const Query = _get('Query');
@@ -115,14 +115,16 @@ export class ApiService extends Service {
super(ctx, 'api'); super(ctx, 'api');
} }
provide(calls: Partial<FlattenedApis>) { provide(calls: Partial<FlattenedApis>, atNameSpace = '') {
this.ctx.effect(() => { this.ctx.effect(() => {
for (const key in calls) { for (const key in calls) {
APIS[key] = calls[key]; const target = `${atNameSpace ? `${atNameSpace}.` : ''}${key}`;
if (APIS[target]) console.warn(`API ${target} already exists, will be overridden`);
APIS[target] = calls[key];
} }
return () => { return () => {
for (const key in calls) { for (const key in calls) {
delete APIS[key]; delete APIS[`${atNameSpace ? `${atNameSpace}.` : ''}${key}`];
} }
}; };
}); });
+1 -1
View File
@@ -95,7 +95,7 @@ function schemaToSettings(schema: Schema<any>) {
if (s.meta?.role === 'password') flag |= FLAG_SECRET; if (s.meta?.role === 'password') flag |= FLAG_SECRET;
const options = {}; const options = {};
for (const item of actualList || []) { for (const item of actualList || []) {
if (item.type !== 'const') throw new Error('List item must be a constant'); if (item.type !== 'const') throw new Error(`List item must be a constant, got ${item.type}`);
options[item.value] = item.meta?.description || item.value; options[item.value] = item.meta?.description || item.value;
} }
return { return {