Skip to content

Commit 6beba90

Browse files
committed
chore: update
1 parent 93f5c48 commit 6beba90

File tree

1 file changed

+111
-5
lines changed

1 file changed

+111
-5
lines changed

apps/web/src/utils/upload2.ts

Lines changed: 111 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@ function getTemplateFilename(instrumentInternal: AnyUnilingualFormInstrument['in
5353
namespace Zod3 {
5454
type ZodTypeName = Extract<`${z3.ZodFirstPartyTypeKind}`, (typeof ZOD_TYPE_NAMES)[number]>;
5555

56-
type RequiredZodTypeName = Exclude<ZodTypeName, 'ZodEffects' | 'ZodOptional'>;
56+
export type RequiredZodTypeName = Exclude<ZodTypeName, 'ZodEffects' | 'ZodOptional'>;
5757

5858
type AnyZodTypeDef = z3.ZodTypeDef & { typeName: ZodTypeName };
5959

6060
type ZodObjectArrayDef = z3.ZodArrayDef & { type: z3.AnyZodObject };
6161

62-
type ZodTypeNameResult = {
62+
export type ZodTypeNameResult = {
6363
enumValues?: readonly string[];
6464
isOptional: boolean;
6565
multiKeys?: string[];
@@ -178,7 +178,7 @@ namespace Zod3 {
178178
return isOptional ? `${s} (optional)` : s;
179179
}
180180

181-
function generateSampleData({
181+
export function generateSampleData({
182182
enumValues,
183183
isOptional,
184184
multiKeys,
@@ -286,6 +286,112 @@ namespace Zod3 {
286286
}
287287

288288
namespace Zod4 {
289+
function jsonToZod(givenType: unknown): Zod3.RequiredZodTypeName {
290+
if (typeof givenType === 'string') {
291+
switch (givenType) {
292+
case 'array':
293+
return 'ZodArray';
294+
case 'boolean':
295+
return 'ZodBoolean';
296+
case 'date':
297+
return 'ZodDate';
298+
case 'enum':
299+
return 'ZodEnum';
300+
case 'number':
301+
return 'ZodNumber';
302+
case 'set':
303+
return 'ZodSet';
304+
case 'string':
305+
return 'ZodString';
306+
default:
307+
}
308+
}
309+
throw new Error("Failed to interpret json value / Échec de l'interprétation de la valeur json");
310+
}
311+
312+
function parseJSONSchema(jsonInstrumentSchema: z4.core.JSONSchema.ObjectSchema) {
313+
// TODO - these could actually not exist
314+
// prettier-ignore
315+
if (!(jsonInstrumentSchema.properties && jsonInstrumentSchema.required && Array.isArray(jsonInstrumentSchema.required))) {
316+
throw new UploadError({
317+
en: "Failed to interpret JSON schema",
318+
fr: "Échec de l'interprétation du schéma JSON"
319+
});
320+
}
321+
322+
const jsonColumnNames = Object.keys(jsonInstrumentSchema.properties);
323+
324+
const jsonCSVColumns = INTERNAL_HEADERS.concat(jsonColumnNames);
325+
const jsonSampleData = [...INTERNAL_HEADERS_SAMPLE_DATA];
326+
327+
for (const col of jsonColumnNames) {
328+
let optional = true;
329+
// let data: ZodTypeNameResult;
330+
if (jsonInstrumentSchema.required.includes(col)) {
331+
optional = false;
332+
}
333+
334+
let data: Zod3.ZodTypeNameResult;
335+
const propertySchema = jsonInstrumentSchema.properties[col] as z4.core.JSONSchema.Schema;
336+
337+
if (propertySchema.type === 'array') {
338+
if (!propertySchema.items) {
339+
throw new UploadError({
340+
en: "Property 'items' must be defined for array schema"
341+
});
342+
} else if (Array.isArray(propertySchema.items)) {
343+
throw new UploadError({
344+
en: "Property 'items' must not be array: only JSON schema 2020 or later is supported"
345+
});
346+
}
347+
const itemsSchema = propertySchema.items as z4.core.JSONSchema.ObjectSchema;
348+
const keys = Object.keys(itemsSchema.properties!);
349+
const values = Object.values(itemsSchema.properties!);
350+
const multiVals: Zod3.ZodTypeNameResult[] = [];
351+
352+
let i = 0;
353+
354+
for (const val of values) {
355+
if (val.type && Array.isArray(itemsSchema.required) && keys[i]) {
356+
// optional is false if the key is included in the required items
357+
multiVals.push({
358+
isOptional: !itemsSchema.required.includes(keys[i]!),
359+
typeName: jsonToZod(val.type)
360+
});
361+
i++;
362+
}
363+
}
364+
data = {
365+
isOptional: optional,
366+
multiKeys: keys,
367+
multiValues: multiVals,
368+
typeName: 'ZodObject'
369+
};
370+
} else if (propertySchema.enum) {
371+
data = {
372+
enumValues: propertySchema.enum as readonly string[],
373+
isOptional: optional,
374+
typeName: 'ZodEnum'
375+
};
376+
} else if (jsonToZod(propertySchema.type)) {
377+
data = {
378+
isOptional: optional,
379+
typeName: jsonToZod(propertySchema.type)
380+
};
381+
} else {
382+
throw new UploadError({
383+
en: 'Failed to interpret JSON value from schema',
384+
fr: "Échec de l'interprétation de la valeur JSON du schéma"
385+
});
386+
}
387+
jsonSampleData.push(Zod3.generateSampleData(data));
388+
}
389+
390+
const zod4TemplateData = unparse([jsonCSVColumns, jsonSampleData]);
391+
392+
return zod4TemplateData;
393+
}
394+
289395
export function createUploadTemplateCSV(
290396
instrumentSchema: z4.ZodType<FormTypes.Data>,
291397
instrumentInternal: AnyUnilingualFormInstrument['internal']
@@ -296,9 +402,9 @@ namespace Zod4 {
296402
en: `Expected form validation schema to be of type object, got ${jsonInstrumentSchema.type}`
297403
});
298404
}
299-
const zod4TemplateData = ''; // zod4Helper(jsonInstrumentSchema);
405+
300406
return {
301-
content: zod4TemplateData,
407+
content: parseJSONSchema(jsonInstrumentSchema),
302408
filename: getTemplateFilename(instrumentInternal)
303409
};
304410
}

0 commit comments

Comments
 (0)