Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9e0a541

Browse files
committed
fest: add new action api tests
1 parente770bbc commit9e0a541

File tree

1 file changed

+270
-0
lines changed

1 file changed

+270
-0
lines changed

‎packages/action/src/action.ts‎

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
/* eslint-disable no-unused-vars */
2+
import{
3+
z,
4+
// infer as _infer,
5+
ZodObject,
6+
ZodRawShape,
7+
ZodSchema,
8+
ZodTypeAny,
9+
ZodType,
10+
}from'zod';
11+
import{Simplify,zInfer}from'./utils/type-utils';
12+
13+
// Generic type for resolver functions
14+
exporttypeResolver<
15+
TInputSchemaextendsZodTypeAny|undefined,
16+
TOutputSchemaextendsZodTypeAny|undefined|unknown,
17+
TContextextendsRecord<string,any>|unknown=unknown,
18+
>=(opts:{
19+
input:TInputSchemaextendsZodTypeAny ?zInfer<TInputSchema> :null;
20+
ctx:Simplify<TContext>;
21+
})=>Promise<TOutputSchemaextendsZodTypeAny ?zInfer<TOutputSchema> :void>;
22+
23+
// Define the builder interface capturing generic types for input and output
24+
25+
exporttypeZodSchemaOrRawShape=ZodSchema<any>|ZodRawShape;
26+
exporttypeInferZodSchemaOrRawShape<TextendsZodSchemaOrRawShape>=
27+
TextendsZodRawShape ?ZodObject<T> :T;
28+
29+
exporttypeMiddleware<
30+
TContextextendsRecord<string,any>|unknown,
31+
TNewContextextendsunknown=unknown,
32+
>=(opts:{
33+
ctx:TContext;
34+
next:(ctx?:TNewContext)=>Promise<TNewContext>;
35+
})=>Promise<TNewContext>;
36+
37+
exporttypeActionDef<
38+
TResolverextendsResolver<any,any,any>,
39+
TInputSchemaextendsZodTypeAny|undefined,
40+
TOutputSchemaextendsZodTypeAny|undefined|unknown,
41+
TTypeextends'mutation'|'query'|undefined,
42+
TContextextendsRecord<string,any>|unknown=unknown,
43+
>={
44+
inputSchema:TInputSchema;
45+
outputSchema:TOutputSchema;
46+
resolver:TResolver;
47+
type:TType;
48+
middleware:Middleware<TContext,TContext>[];
49+
};
50+
51+
constinitialDef={
52+
inputSchema:undefined,
53+
outputSchema:undefined,
54+
resolver:undefined,
55+
type:undefined,
56+
middleware:[]asMiddleware<any,any>[],
57+
};
58+
59+
exportfunctionaction<
60+
TContextextendsRecord<string,any>|unknown=unknown,
61+
>(){
62+
functioncreateBuilder<
63+
TInputSchemaextendsZodTypeAny|undefined,
64+
TOutputSchemaextendsZodTypeAny|undefined,
65+
TTypeextends'mutation'|'query'|undefined,
66+
TContextOverrideextendsRecord<string,any>|unknown=unknown,
67+
>(
68+
def:ActionDef<any,TInputSchema,TOutputSchema,TType,TContextOverride>
69+
):ActionBuilder<TInputSchema,TOutputSchema,TType,TContextOverride>{
70+
return{
71+
input<TNewInputSchemaextendsZodSchemaOrRawShape>(
72+
schema:TNewInputSchema
73+
){
74+
constinputSchema=
75+
schemainstanceofZodSchema ?schema :z.object(schema);
76+
returncreateBuilder({
77+
...def,
78+
inputSchema:inputSchemaasInferZodSchemaOrRawShape<TNewInputSchema>,// handle zod object or raw shape
79+
});
80+
},
81+
output<TNewOutputextendsZodTypeAny>(schema:TNewOutput){
82+
returncreateBuilder({
83+
...def,
84+
outputSchema:schema,
85+
});
86+
},
87+
88+
use<TNewContextextendsTContextOverride>(
89+
middleware:Middleware<TContextOverride,TNewContext>
90+
){
91+
returncreateBuilder({
92+
...def,
93+
//@ts-expect-error
94+
middleware:[...def.middleware,middleware],
95+
})asunknownasActionBuilder<
96+
TInputSchema,
97+
TOutputSchema,
98+
TType,
99+
TNewContext
100+
>;
101+
},
102+
mutation<
103+
TResolverextendsResolver<
104+
TInputSchema,
105+
TOutputSchema,
106+
TContextOverride
107+
>,
108+
>(resolver:TResolver){
109+
constnewDef:ActionDef<
110+
TResolver,
111+
TInputSchema,
112+
TOutputSchema,
113+
'mutation',
114+
TContextOverride
115+
>={
116+
...def,
117+
resolver,
118+
type:'mutation',
119+
};
120+
returncreateResolver(newDef)asunknownasAction<
121+
TResolver,
122+
TInputSchema,
123+
TOutputSchema,
124+
'mutation',
125+
TContextOverride
126+
>;
127+
},
128+
query<
129+
TResolverextendsResolver<
130+
TInputSchema,
131+
TOutputSchema,
132+
TContextOverride
133+
>,
134+
>(resolver:TResolver){
135+
constnewDef:ActionDef<
136+
TResolver,
137+
TInputSchema,
138+
TOutputSchema,
139+
'query',
140+
TContextOverride
141+
>={
142+
...def,
143+
resolver,
144+
type:'query',
145+
};
146+
returncreateResolver(newDef)asunknownasAction<
147+
TResolver,
148+
TInputSchema,
149+
TOutputSchema,
150+
'query',
151+
TContextOverride
152+
>;
153+
},
154+
};
155+
}
156+
157+
returncreateBuilder<undefined,any,any,TContext>({
158+
...initialDef,
159+
});
160+
}
161+
exportinterfaceActionBuilder<
162+
TInputSchemaextendsZodTypeAny|undefined,
163+
TOutputSchemaextendsZodTypeAny|undefined,
164+
TTypeextends'mutation'|'query'|undefined,
165+
TContextextendsRecord<string,any>|unknown=unknown,
166+
>{
167+
input:<TNewInputSchemaextendsZodSchemaOrRawShape>(
168+
schema:TNewInputSchema
169+
)=>ActionBuilder<
170+
InferZodSchemaOrRawShape<TNewInputSchema>,
171+
TOutputSchema,
172+
TType,
173+
TContext
174+
>;
175+
output:<TNewOutputextendsZodTypeAny>(
176+
schema:TNewOutput
177+
)=>ActionBuilder<TInputSchema,TNewOutput,TType,TContext>;
178+
use:<TNewContextextendsTContext>(
179+
middleware:Middleware<TContext,TNewContext>
180+
)=>ActionBuilder<TInputSchema,TOutputSchema,TType,TNewContext>;
181+
182+
mutation:<TResolverextendsResolver<TInputSchema,TOutputSchema,TContext>>(
183+
resolver:TResolver
184+
)=>Action<TResolver,TInputSchema,TOutputSchema,'mutation',TContext>;
185+
query:<TResolverextendsResolver<TInputSchema,TOutputSchema,TContext>>(
186+
resolver:TResolver
187+
)=>Action<TResolver,TInputSchema,TOutputSchema,'query',TContext>;
188+
}
189+
190+
exporttypeAction<
191+
TResolverextendsResolver<any,any,any>,
192+
TInputSchemaextendsZodTypeAny|undefined,
193+
TOutputSchemaextendsZodTypeAny|undefined|unknown,
194+
TTypeextends'mutation'|'query'|undefined,
195+
TContextextendsRecord<string,any>|unknown=unknown,
196+
>=ActionDef<TResolver,TInputSchema,TOutputSchema,TType,TContext>&{
197+
callerWithoutParser:(
198+
ctx:TContext,
199+
input:TInputSchemaextendsZodTypeAny ?zInfer<TInputSchema> :void
200+
)=>ReturnType<TResolver>;
201+
}&{
202+
(
203+
ctx:TContext,
204+
input:TInputSchemaextendsZodTypeAny ?zInfer<TInputSchema> :void
205+
):ReturnType<TResolver>;
206+
};
207+
exportfunctioncreateResolver<
208+
TResolverextendsResolver<any,any,any>,
209+
TInputSchemaextendsZodTypeAny|undefined,
210+
TOutputSchemaextendsZodTypeAny|undefined,
211+
TTypeextends'mutation'|'query',
212+
TContextextendsRecord<string,any>|unknown,
213+
>(def:ActionDef<TResolver,TInputSchema,TOutputSchema,TType,TContext>){
214+
/**
215+
* Invokes the resolver with middleware logic
216+
*/
217+
constcallerWithMiddleware=async(
218+
ctx:TContext,
219+
input:TInputSchemaextendsZodTypeAny ?zInfer<TInputSchema> :null,
220+
middlewares:Middleware<TContext,TContext>[]=def.middleware
221+
)=>{
222+
letcurrentCtx=ctx;
223+
224+
constexecuteMiddleware=async(index:number):Promise<any>=>{
225+
if(index>=middlewares.length){
226+
returndef.resolver({ input,ctx:currentCtx});
227+
}else{
228+
constcurrentMiddleware=middlewares[index];
229+
returnawaitcurrentMiddleware({
230+
ctx:currentCtx,
231+
next:async(newCtx?:TContext)=>{
232+
currentCtx=newCtx||currentCtx;
233+
returnexecuteMiddleware(index+1);
234+
},
235+
});
236+
}
237+
};
238+
239+
returnexecuteMiddleware(0);
240+
};
241+
242+
/**
243+
* Calls the resolver function without parsing input/output
244+
* Useful for calling the resolver when the input/output is already parsed
245+
*/
246+
constcallerWithoutParser=async(
247+
ctx:TContext,
248+
input:TInputSchemaextendsZodTypeAny ?zInfer<TInputSchema> :null
249+
)=>{
250+
returncallerWithMiddleware(ctx,input);
251+
};
252+
253+
/**
254+
* Invokes the resolver with parsing input/output and middleware logic
255+
* Useful for safe calling the resolver directly
256+
*/
257+
constcallerWithParser=async(ctx:TContext,input:any)=>{
258+
constmaybeParsedInput=def.inputSchema
259+
?def.inputSchema.parse(input)
260+
:input;
261+
constresult=awaitcallerWithMiddleware(ctx,maybeParsedInput);
262+
263+
constmaybeParsedOutput=def.outputSchema
264+
?def.outputSchema.parse(result)
265+
:result;
266+
returnmaybeParsedOutput;
267+
};
268+
269+
returnObject.assign(callerWithParser,def,{ callerWithoutParser});
270+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp