Skip to content

Commit ac2a71c

Browse files
committed
refactor: add zod4 getzodtypename methods to the zod4 namespace
1 parent f141b27 commit ac2a71c

File tree

1 file changed

+131
-16
lines changed

1 file changed

+131
-16
lines changed

apps/web/src/utils/upload2.ts

Lines changed: 131 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,15 @@ namespace Zod3 {
116116
return isObjectLike(value) && value.constructor.name === 'ZodObject';
117117
}
118118

119-
function isZodTypeDef(value: unknown): value is AnyZodTypeDef {
119+
export function isZodTypeDef(value: unknown): value is AnyZodTypeDef {
120120
return isPlainObject(value) && ZOD_TYPE_NAMES.includes(value.typeName as ZodTypeName);
121121
}
122122

123123
function isZodOptionalDef(def: AnyZodTypeDef): def is z3.ZodOptionalDef<z3.ZodTypeAny> {
124124
return def.typeName === z3.ZodFirstPartyTypeKind.ZodOptional;
125125
}
126126

127-
function isZodEnumDef(def: AnyZodTypeDef): def is z3.ZodEnumDef {
127+
export function isZodEnumDef(def: AnyZodTypeDef): def is z3.ZodEnumDef {
128128
return def.typeName === z3.ZodFirstPartyTypeKind.ZodEnum;
129129
}
130130

@@ -144,7 +144,7 @@ namespace Zod3 {
144144
return def.typeName === z3.ZodFirstPartyTypeKind.ZodEffects;
145145
}
146146

147-
function interpretZodArray(def: ZodObjectArrayDef, isOptional?: boolean): ZodTypeNameResult {
147+
export function interpretZodArray(def: ZodObjectArrayDef, isOptional?: boolean): ZodTypeNameResult {
148148
const listOfZodElements: ZodTypeNameResult[] = [];
149149
const listOfZodKeys: string[] = [];
150150

@@ -810,13 +810,136 @@ namespace Zod4 {
810810
filename: getTemplateFilename(instrumentInternal)
811811
};
812812
}
813-
//to be filled
813+
814+
//getzod4typename
815+
816+
function getZodTypeName(schema: z4.ZodType<unknown, unknown>, isOptional?: boolean): Zod3.ZodTypeNameResult {
817+
const defUnknown: unknown = schema._def;
818+
if (!defUnknown) {
819+
throw new UploadError({
820+
en: 'Invalid Zod v4 definition structure',
821+
fr: 'Structure de définition Zod v4 invalide'
822+
});
823+
}
824+
825+
const def = defUnknown;
826+
827+
if (!def.type) {
828+
throw new UploadError({
829+
en: 'Invalid Zod v4 definition structure',
830+
fr: 'Structure de définition Zod v4 invalide'
831+
});
832+
}
833+
if (!isObjectLike(def) || typeof def.type !== 'string') {
834+
throw new UploadError({
835+
en: 'Invalid Zod v4 definition structure',
836+
fr: 'Structure de définition Zod v4 invalide'
837+
});
838+
}
839+
if (def.type === 'optional' && def.innerType) {
840+
return getZodTypeName(def.innerType, true);
841+
} else if (def.type === 'enum') {
842+
if (def.entries) {
843+
const entries = Object.keys(def.entries as object);
844+
845+
return {
846+
enumValues: entries,
847+
isOptional: Boolean(isOptional),
848+
typeName: jsonToZod(def.type)
849+
};
850+
}
851+
return {
852+
enumValues: def.values,
853+
isOptional: Boolean(isOptional),
854+
typeName: jsonToZod(def.type)
855+
};
856+
} else if (def.type === 'array') {
857+
const arrayName = jsonToZod(def.type) as z3.ZodFirstPartyTypeKind.ZodArray;
858+
859+
return interpretZod4Array(schema, arrayName, isOptional);
860+
} else if (def.type === 'set') {
861+
const innerDef: unknown = def.valueType._def;
862+
863+
if (!Zod3.isZodTypeDef(innerDef)) {
864+
throw new UploadError({
865+
en: 'Invalid inner type: ZodSet value type must have a valid type definition',
866+
fr: 'Type interne invalide : le type de valeur ZodSet doit avoir une définition de type valide'
867+
});
868+
}
869+
870+
if (Zod3.isZodEnumDef(innerDef)) {
871+
return {
872+
enumValues: innerDef.values,
873+
isOptional: Boolean(isOptional),
874+
typeName: jsonToZod(def.type)
875+
};
876+
}
877+
}
878+
879+
return {
880+
isOptional: Boolean(isOptional),
881+
typeName: jsonToZod(def.type)
882+
};
883+
}
884+
885+
//function to interpret zod 4 arrays
886+
function interpretZod4Array(
887+
def: unknown,
888+
originalName: z3.ZodFirstPartyTypeKind.ZodArray,
889+
isOptional?: boolean
890+
): Zod3.ZodTypeNameResult {
891+
const listOfZodElements: Zod3.ZodTypeNameResult[] = [];
892+
const listOfZodKeys: string[] = [];
893+
const castedDef = def as z4.core.$ZodAny;
894+
if (!castedDef.element) {
895+
throw new UploadError({
896+
en: 'Failure to interpret Zod Object or Array',
897+
fr: "Échec de l'interprétation de l'objet ou du tableau Zod"
898+
});
899+
}
900+
const shape = castedDef.element.shape;
901+
902+
if (!shape || shape === undefined) {
903+
throw new UploadError({
904+
en: 'Failure to interpret Zod Object or Array',
905+
fr: "Échec de l'interprétation de l'objet ou du tableau Zod"
906+
});
907+
}
908+
909+
for (const [key, insideType] of Object.entries(shape)) {
910+
const def: unknown = insideType._def;
911+
if (def.type) {
912+
const innerTypeName = getZodTypeName(insideType as z4.ZodTypeAny);
913+
listOfZodElements.push(innerTypeName);
914+
listOfZodKeys.push(key);
915+
} else {
916+
console.error({ def });
917+
throw new Error(`Unhandled case! / Cas non géré !`);
918+
}
919+
}
920+
921+
if (listOfZodElements.length === 0) {
922+
throw new UploadError({
923+
en: 'Failure to interpret Zod Object or Array',
924+
fr: "Échec de l'interprétation de l'objet ou du tableau Zod"
925+
});
926+
}
927+
928+
return {
929+
isOptional: Boolean(isOptional),
930+
multiKeys: listOfZodKeys,
931+
multiValues: listOfZodElements,
932+
typeName: originalName
933+
};
934+
}
935+
936+
//process instrument CSV zod4 method
814937
export async function processInstrumentCSV(
815938
input: File,
816939
instrument: AnyUnilingualFormInstrument
817940
): Promise<UploadOperationResult<FormTypes.Data[]>> {
818941
const instrumentSchema = instrument.validationSchema as z4.ZodObject;
819-
let shape: { [key: string]: z3.ZodTypeAny } = {};
942+
let shape: { [key: string]: z4.ZodTypeAny } = {};
820943
let instrumentSchemaWithInternal: z4.ZodObject;
821944

822945
if (instrumentSchema instanceof z4.ZodObject) {
@@ -881,7 +1004,7 @@ namespace Zod4 {
8811004
});
8821005
}
8831006
try {
884-
const typeNameResult = Zod3.getZodTypeName(shape[key]);
1007+
const typeNameResult = getZodTypeName(shape[key]);
8851008

8861009
let interpreterResult: UploadOperationResult<FormTypes.FieldValue> = {
8871010
message: {
@@ -915,15 +1038,6 @@ namespace Zod4 {
9151038
typeNameResult.isOptional
9161039
);
9171040
}
918-
// if (!interpreterResult.success) {
919-
// return resolve({
920-
// message: {
921-
// en: `${interpreterResult.message.en} at column name: '${key}' and row number ${rowNumber}`,
922-
// fr: `${interpreterResult.message.fr} au nom de colonne : '${key}' et numéro de ligne ${rowNumber}`
923-
// },
924-
// success: false
925-
// });
926-
// }
9271041
if (interpreterResult.success) jsonLine[headers[j]!] = interpreterResult.value;
9281042
} catch (error: unknown) {
9291043
if (error instanceof UploadError) {
@@ -975,7 +1089,8 @@ export function createUploadTemplateCSV(instrument: AnyUnilingualFormInstrument)
9751089

9761090
//new process instrument csv methods
9771091
export function processInstrumentCSV(input: File, instrument: AnyUnilingualFormInstrument) {
978-
if (isZodType(instrument, { version: 4 })) {
1092+
const instrumentSchema = instrument.validationSchema;
1093+
if (isZodType(instrumentSchema, { version: 4 })) {
9791094
return Zod4.processInstrumentCSV(input, instrument);
9801095
}
9811096
return Zod3.processInstrumentCSV(input, instrument);

0 commit comments

Comments
 (0)