Skip to content

Commit

Permalink
rename, handle intersection scenario
Browse files Browse the repository at this point in the history
  • Loading branch information
samchungy committed Oct 30, 2024
1 parent cad3c6d commit f0cfee4
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 13 deletions.
54 changes: 54 additions & 0 deletions src/create/schema/parsers/intersection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,58 @@ describe('createIntersectionSchema', () => {

expect(result).toEqual(expected);
});

it('handles z.undefined() option', () => {
const expected: Schema = {
type: 'schema',
schema: {
allOf: [
{
type: 'string',
},
],
},
};
const schema = z.intersection(z.undefined(), z.string());

const result = createIntersectionSchema(schema, createOutputState());

expect(result).toEqual(expected);
});

it('handles z.literal(undefined) option', () => {
const expected: Schema = {
type: 'schema',
schema: {
allOf: [
{
type: 'string',
},
],
},
};
const schema = z.intersection(z.string(), z.literal(undefined));

const result = createIntersectionSchema(schema, createOutputState());

expect(result).toEqual(expected);
});

it('handles z.never() option', () => {
const expected: Schema = {
type: 'schema',
schema: {
allOf: [
{
type: 'string',
},
],
},
};
const schema = z.intersection(z.string(), z.never());

const result = createIntersectionSchema(schema, createOutputState());

expect(result).toEqual(expected);
});
});
21 changes: 13 additions & 8 deletions src/create/schema/parsers/intersection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
createSchemaObject,
} from '../../schema';

import { isOptionalObjectKey } from './optional';
import { flattenEffects } from './transform';

export const createIntersectionSchema = <
Expand All @@ -15,18 +16,22 @@ export const createIntersectionSchema = <
zodIntersection: ZodIntersection<T, U>,
state: SchemaState,
): Schema => {
const left = createSchemaObject(zodIntersection._def.left, state, [
'intersection left',
]);
const right = createSchemaObject(zodIntersection._def.right, state, [
'intersection right',
]);
const left = !isOptionalObjectKey(zodIntersection._def.left)
? createSchemaObject(zodIntersection._def.left, state, [
'intersection left',
])
: undefined;
const right = !isOptionalObjectKey(zodIntersection._def.right)
? createSchemaObject(zodIntersection._def.right, state, [
'intersection right',
])
: undefined;

return {
type: 'schema',
schema: {
allOf: [left.schema, right.schema],
allOf: [...(left ? [left.schema] : []), ...(right ? [right.schema] : [])],
},
effects: flattenEffects([left.effects, right.effects]),
effects: flattenEffects([left?.effects, right?.effects]),
};
};
1 change: 1 addition & 0 deletions src/create/schema/parsers/object.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ describe('required', () => {
.transform((str) => str?.length)
.pipe(z.number().optional()),
m: z.string().default('a'),
n: z.intersection(z.literal(undefined), z.number()),
});

const result = createObjectSchema(schema, createInputState());
Expand Down
4 changes: 2 additions & 2 deletions src/create/schema/parsers/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
createSchemaObject,
} from '../../schema';

import { isOptionalKeys } from './optional';
import { isOptionalObjectKey } from './optional';
import { flattenEffects } from './transform';

export const createObjectSchema = <
Expand Down Expand Up @@ -288,7 +288,7 @@ export const mapProperties = (
}
return shapeEntries.reduce(
(acc, [key, zodSchema]) => {
if (isOptionalKeys(zodSchema)) {
if (isOptionalObjectKey(zodSchema)) {
return acc;
}

Expand Down
2 changes: 1 addition & 1 deletion src/create/schema/parsers/optional.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const createOptionalSchema = <T extends ZodTypeAny>(
state: SchemaState,
): Schema => createSchemaObject(zodOptional.unwrap(), state, ['optional']); // Optional doesn't change OpenAPI schema

export const isOptionalKeys = (zodSchema: ZodTypeAny) =>
export const isOptionalObjectKey = (zodSchema: ZodTypeAny) =>
isZodType(zodSchema, 'ZodNever') ||
isZodType(zodSchema, 'ZodUndefined') ||
(isZodType(zodSchema, 'ZodLiteral') && zodSchema._def.value === undefined);
4 changes: 2 additions & 2 deletions src/create/schema/parsers/union.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
createSchemaObject,
} from '../../schema';

import { isOptionalKeys } from './optional';
import { isOptionalObjectKey } from './optional';
import { flattenEffects } from './transform';

export const createUnionSchema = <
Expand All @@ -16,7 +16,7 @@ export const createUnionSchema = <
state: SchemaState,
): Schema => {
const schemas = zodUnion.options.reduce<Schema[]>((acc, option, index) => {
if (!isOptionalKeys(option)) {
if (!isOptionalObjectKey(option)) {
acc.push(createSchemaObject(option, state, [`union option ${index}`]));
}
return acc;
Expand Down

0 comments on commit f0cfee4

Please sign in to comment.