fluent-convex 0.3.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builder.d.ts +1 -0
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js.map +1 -1
- package/dist/types.d.ts +14 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -3
- package/src/builder.test-d.ts +162 -0
- package/src/builder.ts +7 -1
- package/src/types.ts +29 -9
- package/README.md +0 -147
package/dist/builder.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare class ConvexBuilder<TDataModel extends GenericDataModel = Generic
|
|
|
14
14
|
private def;
|
|
15
15
|
constructor(def: ConvexBuilderDef<TFunctionType, TArgsValidator, TReturnsValidator, TVisibility>);
|
|
16
16
|
$context<U extends Context>(): ConvexBuilder<TDataModel, TFunctionType, U & Record<never, never>, U, TArgsValidator, TReturnsValidator, TVisibility>;
|
|
17
|
+
middleware<UInContext extends Context, UOutContext extends Context>(middleware: ConvexMiddleware<UInContext, UOutContext>): ConvexMiddleware<UInContext, UOutContext>;
|
|
17
18
|
middleware<UOutContext extends Context>(middleware: ConvexMiddleware<TInitialContext, UOutContext>): ConvexMiddleware<TInitialContext, UOutContext>;
|
|
18
19
|
use<UOutContext extends Context>(middleware: ConvexMiddleware<TCurrentContext, UOutContext>): ConvexBuilder<TDataModel, TFunctionType, TInitialContext, TCurrentContext & UOutContext, TArgsValidator, TReturnsValidator, TVisibility>;
|
|
19
20
|
query(): ConvexBuilder<TDataModel, "query", TInitialContext extends Record<never, never> ? QueryCtx<TDataModel> : TInitialContext, TCurrentContext extends Record<never, never> ? QueryCtx<TDataModel> : TCurrentContext, TArgsValidator, TReturnsValidator, TVisibility>;
|
package/dist/builder.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EAOrB,KAAK,gBAAgB,EACrB,KAAK,6BAA6B,EAClC,KAAK,gBAAgB,EACtB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,KAAK,EACV,OAAO,EACP,mBAAmB,EACnB,sBAAsB,EACtB,SAAS,EACT,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,WAAW,EACX,SAAS,EACV,MAAM,SAAS,CAAC;AACjB,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC9B,MAAM,eAAe,CAAC;AAEvB,KAAK,YAAY,CAAC,CAAC,SAAS,mBAAmB,GAAG,SAAS,IACzD,CAAC,SAAS,mBAAmB,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAEtE,UAAU,gBAAgB,CACxB,aAAa,SAAS,YAAY,GAAG,SAAS,EAC9C,cAAc,SAAS,mBAAmB,GAAG,SAAS,EACtD,iBAAiB,SAAS,sBAAsB,GAAG,SAAS,EAC5D,WAAW,SAAS,UAAU;IAE9B,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,WAAW,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC5C,aAAa,CAAC,EAAE,cAAc,CAAC;IAC/B,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;IACrC,UAAU,EAAE,WAAW,CAAC;CACzB;AAED,qBAAa,aAAa,CACxB,UAAU,SAAS,gBAAgB,GAAG,gBAAgB,EACtD,aAAa,SAAS,YAAY,GAAG,SAAS,GAAG,SAAS,EAC1D,eAAe,SAAS,OAAO,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EACtD,eAAe,SAAS,OAAO,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EACtD,cAAc,SAAS,mBAAmB,GAAG,SAAS,GAAG,SAAS,EAClE,iBAAiB,SAAS,sBAAsB,GAAG,SAAS,GAAG,SAAS,EACxE,WAAW,SAAS,UAAU,GAAG,QAAQ;IAEzC,OAAO,CAAC,GAAG,CAKT;gBAGA,GAAG,EAAE,gBAAgB,CACnB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,WAAW,CACZ;IAKH,QAAQ,CAAC,CAAC,SAAS,OAAO,KAAK,aAAa,CAC1C,UAAU,EACV,aAAa,EACb,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EACxB,CAAC,EACD,cAAc,EACd,iBAAiB,EACjB,WAAW,CACZ;IAOD,UAAU,CAAC,WAAW,SAAS,OAAO,EACpC,UAAU,EAAE,gBAAgB,CAAC,eAAe,EAAE,WAAW,CAAC,GACzD,gBAAgB,CAAC,eAAe,EAAE,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"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"}
|
package/dist/builder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,YAAY,EACZ,oBAAoB,EACpB,eAAe,EACf,uBAAuB,EACvB,aAAa,EACb,qBAAqB,GAItB,MAAM,eAAe,CAAC;AAavB,OAAO,EACL,WAAW,EACX,iBAAiB,GAKlB,MAAM,eAAe,CAAC;AAkBvB,MAAM,OAAO,aAAa;IAShB,GAAG,CAKT;IAEF,YACE,GAKC;QAED,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,QAAQ;QASN,OAAO,IAAI,aAAa,CAAC;YACvB,GAAG,IAAI,CAAC,GAAG;YACX,WAAW,EAAE,EAAE;SAChB,CAAC,CAAC;IACL,CAAC;
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -3,13 +3,25 @@ import type { GenericActionCtx, GenericMutationCtx, GenericQueryCtx, GenericData
|
|
|
3
3
|
export type Context = Record<PropertyKey, any>;
|
|
4
4
|
export type ConvexArgsValidator = PropertyValidators | GenericValidator;
|
|
5
5
|
export type ConvexReturnsValidator = GenericValidator;
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
type ValidatorType<T> = T extends GenericValidator ? T["type"] : never;
|
|
7
|
+
type OptionalKeys<T extends Record<PropertyKey, any>> = {
|
|
8
|
+
[K in keyof T]: T[K] extends GenericValidator ? T[K]["isOptional"] extends "optional" ? K : never : never;
|
|
9
|
+
}[keyof T];
|
|
10
|
+
type RequiredKeys<T extends Record<PropertyKey, any>> = {
|
|
11
|
+
[K in keyof T]: T[K] extends GenericValidator ? T[K]["isOptional"] extends "optional" ? never : K : never;
|
|
12
|
+
}[keyof T];
|
|
13
|
+
type OptionalArgs<T extends Record<PropertyKey, any>> = {
|
|
14
|
+
[K in OptionalKeys<T>]?: T[K] extends GenericValidator ? ValidatorType<T[K]> | undefined : never;
|
|
8
15
|
};
|
|
16
|
+
type RequiredArgs<T extends Record<PropertyKey, any>> = {
|
|
17
|
+
[K in RequiredKeys<T>]: ValidatorType<T[K]>;
|
|
18
|
+
};
|
|
19
|
+
export type InferArgs<T extends ConvexArgsValidator> = T extends GenericValidator ? T["type"] : RequiredArgs<T> & OptionalArgs<T>;
|
|
9
20
|
export type Promisable<T> = T | PromiseLike<T>;
|
|
10
21
|
export type QueryCtx<DataModel extends GenericDataModel = GenericDataModel> = GenericQueryCtx<DataModel>;
|
|
11
22
|
export type MutationCtx<DataModel extends GenericDataModel = GenericDataModel> = GenericMutationCtx<DataModel>;
|
|
12
23
|
export type ActionCtx<DataModel extends GenericDataModel = GenericDataModel> = GenericActionCtx<DataModel>;
|
|
13
24
|
export type FunctionType = "query" | "mutation" | "action";
|
|
14
25
|
export type Visibility = "public" | "internal";
|
|
26
|
+
export {};
|
|
15
27
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,KAAK,EACV,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EACjB,MAAM,eAAe,CAAC;AAEvB,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;AAE/C,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,GAAG,gBAAgB,CAAC;AACxE,MAAM,MAAM,sBAAsB,GAAG,gBAAgB,CAAC;AAEtD,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,KAAK,EACV,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EACjB,MAAM,eAAe,CAAC;AAEvB,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;AAE/C,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,GAAG,gBAAgB,CAAC;AACxE,MAAM,MAAM,sBAAsB,GAAG,gBAAgB,CAAC;AAEtD,KAAK,aAAa,CAAC,CAAC,IAAI,CAAC,SAAS,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;AAEvE,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,WAAW,EAAE,GAAG,CAAC,IAAI;KACrD,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,gBAAgB,GACzC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,UAAU,GACnC,CAAC,GACD,KAAK,GACP,KAAK;CACV,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,WAAW,EAAE,GAAG,CAAC,IAAI;KACrD,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,gBAAgB,GACzC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,UAAU,GACnC,KAAK,GACL,CAAC,GACH,KAAK;CACV,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,WAAW,EAAE,GAAG,CAAC,IAAI;KACrD,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,gBAAgB,GAClD,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,GAC/B,KAAK;CACV,CAAC;AAEF,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,WAAW,EAAE,GAAG,CAAC,IAAI;KACrD,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,mBAAmB,IACjD,CAAC,SAAS,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;AAE7E,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;AAE/C,MAAM,MAAM,QAAQ,CAAC,SAAS,SAAS,gBAAgB,GAAG,gBAAgB,IACxE,eAAe,CAAC,SAAS,CAAC,CAAC;AAC7B,MAAM,MAAM,WAAW,CAAC,SAAS,SAAS,gBAAgB,GAAG,gBAAgB,IAC3E,kBAAkB,CAAC,SAAS,CAAC,CAAC;AAChC,MAAM,MAAM,SAAS,CAAC,SAAS,SAAS,gBAAgB,GAAG,gBAAgB,IACzE,gBAAgB,CAAC,SAAS,CAAC,CAAC;AAE9B,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC;AAC3D,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fluent-convex",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "A fluent API builder for Convex functions with middleware support, inspired by oRPC",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
"typecheck": "tsc --noEmit",
|
|
25
25
|
"test": "vitest run --typecheck",
|
|
26
26
|
"dev:test": "vitest --typecheck",
|
|
27
|
-
"example": "cd example && npm run",
|
|
28
27
|
"prepublishOnly": "npm run build"
|
|
29
28
|
},
|
|
30
29
|
"keywords": [
|
|
@@ -50,7 +49,6 @@
|
|
|
50
49
|
"zod": "^3.0.0"
|
|
51
50
|
},
|
|
52
51
|
"dependencies": {
|
|
53
|
-
"@orpc/shared": "^1.10.2",
|
|
54
52
|
"convex-helpers": "^0.1.104"
|
|
55
53
|
},
|
|
56
54
|
"devDependencies": {
|
package/src/builder.test-d.ts
CHANGED
|
@@ -316,6 +316,168 @@ describe("ConvexBuilder Type Tests", () => {
|
|
|
316
316
|
return { success: true };
|
|
317
317
|
});
|
|
318
318
|
});
|
|
319
|
+
|
|
320
|
+
it("should infer optional fields as T | undefined", () => {
|
|
321
|
+
convex
|
|
322
|
+
.mutation()
|
|
323
|
+
.input({
|
|
324
|
+
id: v.id("numbers"),
|
|
325
|
+
name: v.optional(v.string()),
|
|
326
|
+
value: v.optional(v.number()),
|
|
327
|
+
})
|
|
328
|
+
.handler(async ({ input }) => {
|
|
329
|
+
assertType<string>(input.id);
|
|
330
|
+
assertType<string | undefined>(input.name);
|
|
331
|
+
assertType<number | undefined>(input.value);
|
|
332
|
+
return null;
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
it("should handle many optional fields with complex types", () => {
|
|
337
|
+
convex
|
|
338
|
+
.mutation()
|
|
339
|
+
.input({
|
|
340
|
+
id: v.id("numbers"),
|
|
341
|
+
name: v.optional(v.string()),
|
|
342
|
+
count: v.optional(v.number()),
|
|
343
|
+
status: v.optional(v.union(v.string(), v.null())),
|
|
344
|
+
items: v.optional(
|
|
345
|
+
v.array(
|
|
346
|
+
v.object({
|
|
347
|
+
x: v.number(),
|
|
348
|
+
y: v.number(),
|
|
349
|
+
})
|
|
350
|
+
)
|
|
351
|
+
),
|
|
352
|
+
})
|
|
353
|
+
.handler(async ({ input }) => {
|
|
354
|
+
assertType<string>(input.id);
|
|
355
|
+
assertType<string | undefined>(input.name);
|
|
356
|
+
assertType<number | undefined>(input.count);
|
|
357
|
+
assertType<string | null | undefined>(input.status);
|
|
358
|
+
assertType<Array<{ x: number; y: number }> | undefined>(input.items);
|
|
359
|
+
return null;
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
it("should allow all fields to be optional", () => {
|
|
364
|
+
convex
|
|
365
|
+
.query()
|
|
366
|
+
.input({
|
|
367
|
+
name: v.optional(v.string()),
|
|
368
|
+
minValue: v.optional(v.number()),
|
|
369
|
+
maxValue: v.optional(v.number()),
|
|
370
|
+
})
|
|
371
|
+
.handler(async ({ input }) => {
|
|
372
|
+
assertType<string | undefined>(input.name);
|
|
373
|
+
assertType<number | undefined>(input.minValue);
|
|
374
|
+
assertType<number | undefined>(input.maxValue);
|
|
375
|
+
return [];
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
it("should make all properties required but allow undefined for optional fields", () => {
|
|
380
|
+
convex
|
|
381
|
+
.mutation()
|
|
382
|
+
.input({
|
|
383
|
+
id: v.id("numbers"),
|
|
384
|
+
name: v.optional(v.string()),
|
|
385
|
+
value: v.optional(v.number()),
|
|
386
|
+
})
|
|
387
|
+
.handler(async ({ input }) => {
|
|
388
|
+
// All properties are present in the type
|
|
389
|
+
assertType<string>(input.id);
|
|
390
|
+
assertType<string | undefined>(input.name);
|
|
391
|
+
assertType<number | undefined>(input.value);
|
|
392
|
+
|
|
393
|
+
// Valid assignments with all properties
|
|
394
|
+
const testArgs1: typeof input = {
|
|
395
|
+
id: "123" as any,
|
|
396
|
+
name: undefined,
|
|
397
|
+
value: undefined,
|
|
398
|
+
};
|
|
399
|
+
const testArgs2: typeof input = {
|
|
400
|
+
id: "123" as any,
|
|
401
|
+
name: "test",
|
|
402
|
+
value: undefined,
|
|
403
|
+
};
|
|
404
|
+
const testArgs3: typeof input = {
|
|
405
|
+
id: "123" as any,
|
|
406
|
+
name: undefined,
|
|
407
|
+
value: 42,
|
|
408
|
+
};
|
|
409
|
+
const testArgs4: typeof input = {
|
|
410
|
+
id: "123" as any,
|
|
411
|
+
name: "test",
|
|
412
|
+
value: 42,
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
return { id: input.id };
|
|
416
|
+
});
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
it("should work with Partial for truly optional calling patterns", () => {
|
|
420
|
+
convex
|
|
421
|
+
.mutation()
|
|
422
|
+
.input({
|
|
423
|
+
id: v.id("numbers"),
|
|
424
|
+
name: v.optional(v.string()),
|
|
425
|
+
count: v.optional(v.number()),
|
|
426
|
+
status: v.optional(v.union(v.string(), v.null())),
|
|
427
|
+
})
|
|
428
|
+
.handler(async ({ input }) => {
|
|
429
|
+
// When calling, use Partial to make properties truly optional
|
|
430
|
+
type CallArgs = Partial<typeof input> & Pick<typeof input, "id">;
|
|
431
|
+
|
|
432
|
+
// Test various combinations are valid
|
|
433
|
+
const testArgs1: CallArgs = { id: "123" as any };
|
|
434
|
+
const testArgs2: CallArgs = { id: "123" as any, name: "test" };
|
|
435
|
+
const testArgs3: CallArgs = { id: "123" as any, count: 10 };
|
|
436
|
+
const testArgs4: CallArgs = { id: "123" as any, status: "active" };
|
|
437
|
+
const testArgs5: CallArgs = { id: "123" as any, status: null };
|
|
438
|
+
const testArgs6: CallArgs = {
|
|
439
|
+
id: "123" as any,
|
|
440
|
+
name: "test",
|
|
441
|
+
count: 10,
|
|
442
|
+
};
|
|
443
|
+
const testArgs7: CallArgs = {
|
|
444
|
+
id: "123" as any,
|
|
445
|
+
name: "test",
|
|
446
|
+
count: 10,
|
|
447
|
+
status: "active",
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
return null;
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
it("should allow empty object when all fields are optional", () => {
|
|
455
|
+
convex
|
|
456
|
+
.query()
|
|
457
|
+
.input({
|
|
458
|
+
name: v.optional(v.string()),
|
|
459
|
+
minValue: v.optional(v.number()),
|
|
460
|
+
maxValue: v.optional(v.number()),
|
|
461
|
+
})
|
|
462
|
+
.handler(async ({ input }) => {
|
|
463
|
+
// For calling, use Partial
|
|
464
|
+
type CallArgs = Partial<typeof input>;
|
|
465
|
+
|
|
466
|
+
// Test various combinations are valid
|
|
467
|
+
const testArgs1: CallArgs = {};
|
|
468
|
+
const testArgs2: CallArgs = { name: "test" };
|
|
469
|
+
const testArgs3: CallArgs = { minValue: 10 };
|
|
470
|
+
const testArgs4: CallArgs = { maxValue: 20 };
|
|
471
|
+
const testArgs5: CallArgs = { minValue: 10, maxValue: 20 };
|
|
472
|
+
const testArgs6: CallArgs = {
|
|
473
|
+
name: "test",
|
|
474
|
+
minValue: 10,
|
|
475
|
+
maxValue: 20,
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
return [];
|
|
479
|
+
});
|
|
480
|
+
});
|
|
319
481
|
});
|
|
320
482
|
|
|
321
483
|
describe("complex types", () => {
|
package/src/builder.ts
CHANGED
|
@@ -91,9 +91,15 @@ export class ConvexBuilder<
|
|
|
91
91
|
});
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
middleware<UInContext extends Context, UOutContext extends Context>(
|
|
95
|
+
middleware: ConvexMiddleware<UInContext, UOutContext>
|
|
96
|
+
): ConvexMiddleware<UInContext, UOutContext>;
|
|
94
97
|
middleware<UOutContext extends Context>(
|
|
95
98
|
middleware: ConvexMiddleware<TInitialContext, UOutContext>
|
|
96
|
-
): ConvexMiddleware<TInitialContext, UOutContext
|
|
99
|
+
): ConvexMiddleware<TInitialContext, UOutContext>;
|
|
100
|
+
middleware<UInContext extends Context, UOutContext extends Context>(
|
|
101
|
+
middleware: ConvexMiddleware<UInContext, UOutContext>
|
|
102
|
+
): ConvexMiddleware<UInContext, UOutContext> {
|
|
97
103
|
return middleware;
|
|
98
104
|
}
|
|
99
105
|
|
package/src/types.ts
CHANGED
|
@@ -11,16 +11,36 @@ export type Context = Record<PropertyKey, any>;
|
|
|
11
11
|
export type ConvexArgsValidator = PropertyValidators | GenericValidator;
|
|
12
12
|
export type ConvexReturnsValidator = GenericValidator;
|
|
13
13
|
|
|
14
|
+
type ValidatorType<T> = T extends GenericValidator ? T["type"] : never;
|
|
15
|
+
|
|
16
|
+
type OptionalKeys<T extends Record<PropertyKey, any>> = {
|
|
17
|
+
[K in keyof T]: T[K] extends GenericValidator
|
|
18
|
+
? T[K]["isOptional"] extends "optional"
|
|
19
|
+
? K
|
|
20
|
+
: never
|
|
21
|
+
: never;
|
|
22
|
+
}[keyof T];
|
|
23
|
+
|
|
24
|
+
type RequiredKeys<T extends Record<PropertyKey, any>> = {
|
|
25
|
+
[K in keyof T]: T[K] extends GenericValidator
|
|
26
|
+
? T[K]["isOptional"] extends "optional"
|
|
27
|
+
? never
|
|
28
|
+
: K
|
|
29
|
+
: never;
|
|
30
|
+
}[keyof T];
|
|
31
|
+
|
|
32
|
+
type OptionalArgs<T extends Record<PropertyKey, any>> = {
|
|
33
|
+
[K in OptionalKeys<T>]?: T[K] extends GenericValidator
|
|
34
|
+
? ValidatorType<T[K]> | undefined
|
|
35
|
+
: never;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
type RequiredArgs<T extends Record<PropertyKey, any>> = {
|
|
39
|
+
[K in RequiredKeys<T>]: ValidatorType<T[K]>;
|
|
40
|
+
};
|
|
41
|
+
|
|
14
42
|
export type InferArgs<T extends ConvexArgsValidator> =
|
|
15
|
-
T extends GenericValidator
|
|
16
|
-
? T["type"]
|
|
17
|
-
: {
|
|
18
|
-
[K in keyof T]: T[K] extends GenericValidator
|
|
19
|
-
? T[K]["isOptional"] extends true
|
|
20
|
-
? T[K]["type"] | undefined
|
|
21
|
-
: T[K]["type"]
|
|
22
|
-
: never;
|
|
23
|
-
};
|
|
43
|
+
T extends GenericValidator ? T["type"] : RequiredArgs<T> & OptionalArgs<T>;
|
|
24
44
|
|
|
25
45
|
export type Promisable<T> = T | PromiseLike<T>;
|
|
26
46
|
|
package/README.md
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
# Fluent Convex
|
|
2
|
-
|
|
3
|
-
A fluent API builder for Convex functions with middleware support, inspired by [oRPC](https://orpc.unnoq.com/).
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- 🔄 **Middleware support** - Compose reusable middleware for authentication, logging, and more
|
|
8
|
-
- 🎯 **Type-safe** - Full TypeScript support with type inference
|
|
9
|
-
- ✨ **Fluent API** - Chain methods for a clean, readable syntax
|
|
10
|
-
- 🔌 **Zod integration** - Use Zod schemas alongside Convex validators
|
|
11
|
-
- 🚀 **Works with Convex** - Built on top of Convex's function system
|
|
12
|
-
|
|
13
|
-
## Installation
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
npm install fluent-convex convex convex-helpers zod
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Quick Start
|
|
20
|
-
|
|
21
|
-
```ts
|
|
22
|
-
import { convex } from "fluent-convex";
|
|
23
|
-
import { v } from "convex/values";
|
|
24
|
-
|
|
25
|
-
// Simple query
|
|
26
|
-
export const listNumbers = convex
|
|
27
|
-
.query()
|
|
28
|
-
.input({ count: v.number() })
|
|
29
|
-
.handler(async ({ context, input }) => {
|
|
30
|
-
const numbers = await context.db
|
|
31
|
-
.query("numbers")
|
|
32
|
-
.order("desc")
|
|
33
|
-
.take(input.count);
|
|
34
|
-
|
|
35
|
-
return { numbers: numbers.map((n) => n.value) };
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// With middleware
|
|
39
|
-
const authMiddleware = convex.query().middleware(async ({ context, next }) => {
|
|
40
|
-
const identity = await context.auth.getUserIdentity();
|
|
41
|
-
if (!identity) {
|
|
42
|
-
throw new Error("Unauthorized");
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return next({
|
|
46
|
-
context: {
|
|
47
|
-
...context,
|
|
48
|
-
user: {
|
|
49
|
-
id: identity.subject,
|
|
50
|
-
name: identity.name ?? "Unknown",
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
export const listNumbersAuth = convex
|
|
57
|
-
.query()
|
|
58
|
-
.use(authMiddleware)
|
|
59
|
-
.input({ count: v.number() })
|
|
60
|
-
.handler(async ({ context, input }) => {
|
|
61
|
-
const numbers = await context.db
|
|
62
|
-
.query("numbers")
|
|
63
|
-
.order("desc")
|
|
64
|
-
.take(input.count);
|
|
65
|
-
|
|
66
|
-
return {
|
|
67
|
-
viewer: context.user.name, // user is available from middleware!
|
|
68
|
-
numbers: numbers.map((n) => n.value),
|
|
69
|
-
};
|
|
70
|
-
});
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## Using Zod
|
|
74
|
-
|
|
75
|
-
```ts
|
|
76
|
-
import { z } from "zod";
|
|
77
|
-
import { convex } from "fluent-convex";
|
|
78
|
-
|
|
79
|
-
export const listNumbersWithZod = convex
|
|
80
|
-
.query()
|
|
81
|
-
.input(
|
|
82
|
-
z.object({
|
|
83
|
-
count: z.number().int().min(1).max(100),
|
|
84
|
-
})
|
|
85
|
-
)
|
|
86
|
-
.handler(async ({ context, input }) => {
|
|
87
|
-
// input.count is properly typed as number
|
|
88
|
-
const numbers = await context.db.query("numbers").take(input.count);
|
|
89
|
-
|
|
90
|
-
return { numbers: numbers.map((n) => n.value) };
|
|
91
|
-
});
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## API
|
|
95
|
-
|
|
96
|
-
### Methods
|
|
97
|
-
|
|
98
|
-
- `.query()` - Define a Convex query
|
|
99
|
-
- `.mutation()` - Define a Convex mutation
|
|
100
|
-
- `.action()` - Define a Convex action
|
|
101
|
-
- `.internal()` - Make the function internal (private)
|
|
102
|
-
- `.input(validator)` - Set input validation (Convex or Zod)
|
|
103
|
-
- `.returns(validator)` - Set return validation (Convex or Zod)
|
|
104
|
-
- `.use(middleware)` - Apply middleware
|
|
105
|
-
- `.middleware(fn)` - Create a middleware function
|
|
106
|
-
- `.handler(fn)` - Define the function handler
|
|
107
|
-
|
|
108
|
-
## Example
|
|
109
|
-
|
|
110
|
-
Check out the `/example` directory for a complete working example with various use cases including:
|
|
111
|
-
|
|
112
|
-
- Simple queries and mutations
|
|
113
|
-
- Middleware composition
|
|
114
|
-
- Zod integration
|
|
115
|
-
- Internal functions
|
|
116
|
-
- Type-safe context transformations
|
|
117
|
-
|
|
118
|
-
## Development
|
|
119
|
-
|
|
120
|
-
This is a monorepo structure:
|
|
121
|
-
|
|
122
|
-
- `/src` - The npm package source code
|
|
123
|
-
- `/example` - Example Convex app using the package
|
|
124
|
-
|
|
125
|
-
### Building the package
|
|
126
|
-
|
|
127
|
-
```bash
|
|
128
|
-
npm run build
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
### Running tests
|
|
132
|
-
|
|
133
|
-
```bash
|
|
134
|
-
npm test
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### Running the example
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
cd example
|
|
141
|
-
npm install
|
|
142
|
-
npm run dev
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
## Credits
|
|
146
|
-
|
|
147
|
-
Borrowed heavily from [oRPC](https://orpc.unnoq.com/learn-and-contribute/overview) and helped out by AI.
|