Skip to content

Commit

Permalink
fix: Mark only imported types as optional in validation (#204)
Browse files Browse the repository at this point in the history
  • Loading branch information
tvillaren committed Feb 28, 2024
1 parent 34e76f2 commit 9e52cca
Show file tree
Hide file tree
Showing 9 changed files with 523 additions and 35 deletions.
1 change: 1 addition & 0 deletions example/heros.ts
Expand Up @@ -24,6 +24,7 @@ export type SupermanName = Superman["name"];
export type SupermanInvinciblePower = Superman["powers"][2];

export interface Superman {
person: Person;
name: "superman" | "clark kent" | "kal-l";
enemies: Record<string, Enemy>;
age: number;
Expand Down
1 change: 1 addition & 0 deletions example/heros.zod.ts
Expand Up @@ -17,6 +17,7 @@ export const enemySchema = personSchema.extend({
});

export const supermanSchema = z.object({
person: personSchema,
name: z.union([
z.literal("superman"),
z.literal("clark kent"),
Expand Down
42 changes: 38 additions & 4 deletions src/cli.ts
Expand Up @@ -300,20 +300,54 @@ See more help with --help`,
if (!Flags.skipValidation) {
const validatorSpinner = ora("Validating generated types").start();
if (Flags.all) validatorSpinner.indent = 1;

const extraFiles = [];
for (const io of inputOutputMappings) {
if (getImportPath(inputPath, io.input) !== "/") {
try {
const fileInputPath = join(process.cwd(), io.input);
const inputFile = await readFile(fileInputPath, "utf-8");
extraFiles.push({
sourceText: inputFile,
relativePath: io.input,
});
} catch {
validatorSpinner.warn(`File "${io.input}" not found`);
}

try {
const fileOutputPath = join(process.cwd(), io.output);
const outputFile = await readFile(fileOutputPath, "utf-8");
extraFiles.push({
sourceText: outputFile,
relativePath: io.output,
});
} catch {
validatorSpinner.warn(
`File "${io.output}" not found: maybe it hasn't been generated yet?`
);
}
}
}

const generationErrors = await worker.validateGeneratedTypesInWorker({
sourceTypes: {
sourceText: transformedSourceText,
relativePath: "./source.ts",
relativePath: input,
},
integrationTests: {
sourceText: getIntegrationTestFile("./source", "./source.zod"),
sourceText: getIntegrationTestFile(
getImportPath("./source.integration.ts", input),
getImportPath("./source.integration.ts", output || input)
),
relativePath: "./source.integration.ts",
},
zodSchemas: {
sourceText: getZodSchemasFile("./source"),
relativePath: "./source.zod.ts",
sourceText: getZodSchemasFile(getImportPath(output || input, input)),
relativePath: output || input,
},
skipParseJSDoc: Boolean(generateOptions.skipParseJSDoc),
extraFiles,
});

generationErrors.length
Expand Down
7 changes: 4 additions & 3 deletions src/core/generate.ts
@@ -1,7 +1,6 @@
import { camel } from "case";
import { getJsDoc } from "tsutils";
import ts from "typescript";
import { relative } from "path";
import {
InputOutputMapping,
JSDocTagFilter,
Expand All @@ -28,6 +27,7 @@ import {
generateZodSchemaVariableStatementForImport,
} from "./generateZodSchema";
import { transformRecursiveSchema } from "./transformRecursiveSchema";
import { areImportPathsEqualIgnoringExtension } from "../utils/getImportPath";

const DEFAULT_GET_SCHEMA = (id: string) => camel(id) + "Schema";

Expand Down Expand Up @@ -121,11 +121,12 @@ export function generate({
// Check if we're importing from a mapped file
const eligibleMapping = inputOutputMappings.find(
(io: InputOutputMapping) =>
relative(
areImportPathsEqualIgnoringExtension(
io.input,
(node.moduleSpecifier as ts.StringLiteral).text
) === ""
)
);

if (eligibleMapping) {
const schemaMethod =
eligibleMapping.getSchemaName || DEFAULT_GET_SCHEMA;
Expand Down

0 comments on commit 9e52cca

Please sign in to comment.