zodvex 0.2.5 → 0.3.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/README.md +319 -7
- package/dist/index.d.ts +177 -66
- package/dist/index.js +122 -21
- package/dist/index.js.map +1 -1
- package/package.json +4 -16
- package/src/__type-tests__/infer-returns.ts +154 -0
- package/src/__type-tests__/zodTable-inference.ts +476 -0
- package/src/custom.ts +15 -6
- package/src/ids.ts +8 -8
- package/src/registry.ts +171 -0
- package/src/tables.ts +238 -30
- package/src/types.ts +10 -22
- package/src/wrappers.ts +2 -2
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { NoOp } from 'convex-helpers/server/customFunctions';
|
|
|
2
2
|
export { customCtx } from 'convex-helpers/server/customFunctions';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { v, ConvexError } from 'convex/values';
|
|
5
|
+
import { defineTable } from 'convex/server';
|
|
5
6
|
import { Table } from 'convex-helpers/server';
|
|
6
7
|
|
|
7
8
|
// src/index.ts
|
|
@@ -13,9 +14,7 @@ var registryHelpers = {
|
|
|
13
14
|
function zid(tableName) {
|
|
14
15
|
const baseSchema = z.string().refine((val) => typeof val === "string" && val.length > 0, {
|
|
15
16
|
message: `Invalid ID for table "${tableName}"`
|
|
16
|
-
}).
|
|
17
|
-
return val;
|
|
18
|
-
}).brand(`ConvexId_${tableName}`).describe(`convexId:${tableName}`);
|
|
17
|
+
}).describe(`convexId:${tableName}`);
|
|
19
18
|
registryHelpers.setMetadata(baseSchema, {
|
|
20
19
|
isConvexId: true,
|
|
21
20
|
tableName
|
|
@@ -57,6 +56,56 @@ function isDateSchema(schema) {
|
|
|
57
56
|
}
|
|
58
57
|
return false;
|
|
59
58
|
}
|
|
59
|
+
function isZidSchema(schema) {
|
|
60
|
+
const description = schema.description;
|
|
61
|
+
return typeof description === "string" && description.startsWith("convexId:");
|
|
62
|
+
}
|
|
63
|
+
function getZidTableName(schema) {
|
|
64
|
+
const description = schema.description;
|
|
65
|
+
if (typeof description === "string" && description.startsWith("convexId:")) {
|
|
66
|
+
return description.slice("convexId:".length);
|
|
67
|
+
}
|
|
68
|
+
return void 0;
|
|
69
|
+
}
|
|
70
|
+
function zodvexJSONSchemaOverride(ctx) {
|
|
71
|
+
const { zodSchema, jsonSchema } = ctx;
|
|
72
|
+
if (isZidSchema(zodSchema)) {
|
|
73
|
+
const tableName = getZidTableName(zodSchema);
|
|
74
|
+
jsonSchema.type = "string";
|
|
75
|
+
if (tableName) {
|
|
76
|
+
jsonSchema.format = `convex-id:${tableName}`;
|
|
77
|
+
}
|
|
78
|
+
if (zodSchema.description) {
|
|
79
|
+
jsonSchema.description = zodSchema.description;
|
|
80
|
+
}
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (zodSchema instanceof z.ZodDate || zodSchema.type === "date") {
|
|
84
|
+
jsonSchema.type = "string";
|
|
85
|
+
jsonSchema.format = "date-time";
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function composeOverrides(...overrides) {
|
|
90
|
+
return (ctx) => {
|
|
91
|
+
for (const override of overrides) {
|
|
92
|
+
override?.(ctx);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function toJSONSchema(schema, options) {
|
|
97
|
+
const userOverride = options?.override;
|
|
98
|
+
return z.toJSONSchema(schema, {
|
|
99
|
+
...options,
|
|
100
|
+
// Default to 'any' so transforms don't throw
|
|
101
|
+
unrepresentable: options?.unrepresentable ?? "any",
|
|
102
|
+
// Chain our override with user's override
|
|
103
|
+
override: (ctx) => {
|
|
104
|
+
zodvexJSONSchemaOverride(ctx);
|
|
105
|
+
userOverride?.(ctx);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
60
109
|
function convertEnumType(actualValidator) {
|
|
61
110
|
const options = actualValidator.options;
|
|
62
111
|
if (options && Array.isArray(options) && options.length > 0) {
|
|
@@ -681,9 +730,10 @@ function customFnBuilder(builder, customization) {
|
|
|
681
730
|
const inputArgs = customization.args ?? NoOp.args;
|
|
682
731
|
return function customBuilder(fn) {
|
|
683
732
|
const { args, handler = fn, returns: maybeObject, ...extra } = fn;
|
|
733
|
+
const skipConvexValidation = fn.skipConvexValidation ?? false;
|
|
684
734
|
const returns = maybeObject && !(maybeObject instanceof z.ZodType) ? z.object(maybeObject) : maybeObject;
|
|
685
|
-
const returnValidator = returns && !
|
|
686
|
-
if (args
|
|
735
|
+
const returnValidator = returns && !skipConvexValidation ? { returns: zodToConvex(returns) } : void 0;
|
|
736
|
+
if (args) {
|
|
687
737
|
let argsValidator = args;
|
|
688
738
|
let argsSchema;
|
|
689
739
|
if (argsValidator instanceof z.ZodType) {
|
|
@@ -698,9 +748,9 @@ function customFnBuilder(builder, customization) {
|
|
|
698
748
|
} else {
|
|
699
749
|
argsSchema = z.object(argsValidator);
|
|
700
750
|
}
|
|
701
|
-
const
|
|
751
|
+
const convexArgs = skipConvexValidation ? inputArgs : { ...zodToConvexFields(argsValidator), ...inputArgs };
|
|
702
752
|
return builder({
|
|
703
|
-
args:
|
|
753
|
+
args: convexArgs,
|
|
704
754
|
...returnValidator,
|
|
705
755
|
handler: async (ctx, allArgs) => {
|
|
706
756
|
const added = await customInput(
|
|
@@ -720,7 +770,7 @@ function customFnBuilder(builder, customization) {
|
|
|
720
770
|
const addedArgs = added?.args ?? {};
|
|
721
771
|
const finalArgs = { ...baseArgs, ...addedArgs };
|
|
722
772
|
const ret = await handler(finalCtx, finalArgs);
|
|
723
|
-
if (returns
|
|
773
|
+
if (returns) {
|
|
724
774
|
let validated;
|
|
725
775
|
try {
|
|
726
776
|
validated = returns.parse(ret);
|
|
@@ -757,7 +807,7 @@ function customFnBuilder(builder, customization) {
|
|
|
757
807
|
const addedArgs = added?.args ?? {};
|
|
758
808
|
const finalArgs = { ...baseArgs, ...addedArgs };
|
|
759
809
|
const ret = await handler(finalCtx, finalArgs);
|
|
760
|
-
if (returns
|
|
810
|
+
if (returns) {
|
|
761
811
|
let validated;
|
|
762
812
|
try {
|
|
763
813
|
validated = returns.parse(ret);
|
|
@@ -802,7 +852,7 @@ function containsCustom(schema, maxDepth = 50, currentDepth = 0) {
|
|
|
802
852
|
return false;
|
|
803
853
|
}
|
|
804
854
|
let result = false;
|
|
805
|
-
if (schema
|
|
855
|
+
if (schema instanceof z.ZodCustom) {
|
|
806
856
|
result = true;
|
|
807
857
|
} else if (schema instanceof z.ZodUnion) {
|
|
808
858
|
result = schema.options.some(
|
|
@@ -976,6 +1026,27 @@ function zCustomActionBuilder(action, customization) {
|
|
|
976
1026
|
customization
|
|
977
1027
|
);
|
|
978
1028
|
}
|
|
1029
|
+
function addSystemFields(tableName, schema) {
|
|
1030
|
+
if (schema instanceof z.ZodUnion || schema instanceof z.ZodDiscriminatedUnion) {
|
|
1031
|
+
const options = schema.options.map((variant) => {
|
|
1032
|
+
if (variant instanceof z.ZodObject) {
|
|
1033
|
+
return variant.extend({
|
|
1034
|
+
_id: zid(tableName),
|
|
1035
|
+
_creationTime: z.number()
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
return variant;
|
|
1039
|
+
});
|
|
1040
|
+
return z.union(options);
|
|
1041
|
+
}
|
|
1042
|
+
if (schema instanceof z.ZodObject) {
|
|
1043
|
+
return schema.extend({
|
|
1044
|
+
_id: zid(tableName),
|
|
1045
|
+
_creationTime: z.number()
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1048
|
+
return schema;
|
|
1049
|
+
}
|
|
979
1050
|
function zodDoc(tableName, schema) {
|
|
980
1051
|
return schema.extend({
|
|
981
1052
|
_id: zid(tableName),
|
|
@@ -985,18 +1056,48 @@ function zodDoc(tableName, schema) {
|
|
|
985
1056
|
function zodDocOrNull(tableName, schema) {
|
|
986
1057
|
return z.union([zodDoc(tableName, schema), z.null()]);
|
|
987
1058
|
}
|
|
988
|
-
function
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
const
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1059
|
+
function isObjectShape(input) {
|
|
1060
|
+
if (!input || typeof input !== "object") return false;
|
|
1061
|
+
if (input instanceof z.ZodType) return false;
|
|
1062
|
+
for (const key in input) {
|
|
1063
|
+
if (!(input[key] instanceof z.ZodType)) {
|
|
1064
|
+
return false;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
return true;
|
|
1068
|
+
}
|
|
1069
|
+
function zodTable(name, schemaOrShape) {
|
|
1070
|
+
if (isObjectShape(schemaOrShape)) {
|
|
1071
|
+
const shape = schemaOrShape;
|
|
1072
|
+
const convexFields = zodToConvexFields(shape);
|
|
1073
|
+
const table = Table(
|
|
1074
|
+
name,
|
|
1075
|
+
convexFields
|
|
1076
|
+
);
|
|
1077
|
+
const zDoc = zodDoc(name, z.object(shape));
|
|
1078
|
+
const docArray = z.array(zDoc);
|
|
1079
|
+
return Object.assign(table, {
|
|
1080
|
+
shape,
|
|
1081
|
+
zDoc,
|
|
1082
|
+
docArray
|
|
1083
|
+
});
|
|
1084
|
+
} else {
|
|
1085
|
+
const schema = schemaOrShape;
|
|
1086
|
+
const convexValidator = zodToConvex(schema);
|
|
1087
|
+
const table = defineTable(convexValidator);
|
|
1088
|
+
const withFields = addSystemFields(name, schema);
|
|
1089
|
+
const docArray = z.array(withFields);
|
|
1090
|
+
return {
|
|
1091
|
+
table,
|
|
1092
|
+
tableName: name,
|
|
1093
|
+
validator: convexValidator,
|
|
1094
|
+
schema,
|
|
1095
|
+
docArray,
|
|
1096
|
+
withSystemFields: () => addSystemFields(name, schema)
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
998
1099
|
}
|
|
999
1100
|
|
|
1000
|
-
export { convexCodec, customFnBuilder, findBaseCodec, formatZodIssues, fromConvexJS, getObjectShape, handleZodValidationError, isDateSchema, makeUnion, mapDateFieldToNumber, pick, pickShape, registerBaseCodec, registryHelpers, returnsAs, safeOmit, safePick, toConvexJS, zActionBuilder, zCustomAction, zCustomActionBuilder, zCustomMutation, zCustomMutationBuilder, zCustomQuery, zCustomQueryBuilder, zMutationBuilder, zPaginated, zQueryBuilder, zid, zodDoc, zodDocOrNull, zodTable, zodToConvex, zodToConvexFields };
|
|
1101
|
+
export { addSystemFields, composeOverrides, convexCodec, customFnBuilder, findBaseCodec, formatZodIssues, fromConvexJS, getObjectShape, getZidTableName, handleZodValidationError, isDateSchema, isZidSchema, makeUnion, mapDateFieldToNumber, pick, pickShape, registerBaseCodec, registryHelpers, returnsAs, safeOmit, safePick, toConvexJS, toJSONSchema, zActionBuilder, zCustomAction, zCustomActionBuilder, zCustomMutation, zCustomMutationBuilder, zCustomQuery, zCustomQueryBuilder, zMutationBuilder, zPaginated, zQueryBuilder, zid, zodDoc, zodDocOrNull, zodTable, zodToConvex, zodToConvexFields, zodvexJSONSchemaOverride };
|
|
1001
1102
|
//# sourceMappingURL=index.js.map
|
|
1002
1103
|
//# sourceMappingURL=index.js.map
|