Skip to content

Commit 38480e5

Browse files
committed
fix: check union case if there is an objectString
1 parent 2ec0a75 commit 38480e5

File tree

4 files changed

+47
-18
lines changed

4 files changed

+47
-18
lines changed

src/compose.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1461,9 +1461,21 @@ export const composeHandler = ({
14611461

14621462
if (candidate) {
14631463
const isFirst = fileUnions.length === 0
1464+
// Handle case where schema is wrapped in a Union (e.g., ObjectString coercion)
1465+
let properties = candidate.schema?.properties ?? type.properties
1466+
1467+
// If no properties but schema is a Union, try to find the Object in anyOf
1468+
if (!properties && candidate.schema?.anyOf) {
1469+
const objectSchema = candidate.schema.anyOf.find((s: any) => s.type === 'object')
1470+
if (objectSchema) {
1471+
properties = objectSchema.properties
1472+
}
1473+
}
1474+
1475+
if (!properties) continue
14641476

14651477
const iterator = Object.entries(
1466-
type.properties
1478+
properties
14671479
) as [string, TSchema][]
14681480

14691481
let validator = isFirst ? '\n' : ' else '

src/replace-schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ const replaceSchemaTypeFromOption = (
8585
if (shouldTransform) {
8686
return option.to(s) as TSchema;
8787
}
88-
return s
88+
return s;
8989
}
9090

9191
if (isRoot && option.rootOnly) {

src/schema.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,12 @@ export const hasAdditionalProperties = (
126126
/**
127127
* Resolve a schema that might be a model reference (string) to the actual schema
128128
*/
129-
export const resolveSchema = (
130-
schema: TAnySchema | string,
129+
export const resolveSchema = (
130+
schema: TAnySchema | string | undefined,
131131
models?: Record<string, TAnySchema | StandardSchemaV1Like>,
132132
modules?: TModule<any, any>
133-
): TAnySchema | StandardSchemaV1Like | undefined => {
133+
): TAnySchema | StandardSchemaV1Like | undefined => {
134+
if (!schema) return undefined
134135
if (typeof schema !== 'string') return schema
135136

136137
// Check modules first (higher priority)
@@ -141,7 +142,7 @@ export const resolveSchema = (
141142

142143
// Then check models
143144
return models?.[schema]
144-
}
145+
}
145146

146147
export const hasType = (type: string, schema: TAnySchema): boolean => {
147148
if (!schema) return false
@@ -456,12 +457,14 @@ export const getSchemaValidator = <
456457
if (!schema) return undefined as any
457458
}
458459

460+
const hasAdditionalCoerce = Array.isArray(additionalCoerce) ?
461+
additionalCoerce.length > 0 : !!additionalCoerce
459462
if (Kind in schema) {
460463
if (schema[Kind] === 'Import') {
461464
if (!hasRef(schema.$defs[schema.$ref])) {
462465
schema = schema.$defs[schema.$ref]
463466

464-
if (coerce || additionalCoerce) {
467+
if (coerce || hasAdditionalCoerce) {
465468
schema = replaceSchema(schema as TSchema)
466469
if ('$id' in schema && !schema.$defs) {
467470
schema.$id = `${schema.$id}_coerced_${randomId()}`;
@@ -479,7 +482,7 @@ export const getSchemaValidator = <
479482
})
480483

481484
schema = model.Import(id)
482-
} else if (coerce || additionalCoerce)
485+
} else if (coerce || hasAdditionalCoerce)
483486
schema = replaceSchema(schema as TSchema)
484487
}
485488
}
@@ -694,16 +697,15 @@ export const getSchemaValidator = <
694697
schema = replaceSchemaTypeFromManyOptions(schema, {
695698
onlyFirst: "object",
696699
from: t.Object({}),
697-
to({ properties, ...options }) {
698-
// If nothing is return, use the original schema
699-
if (!properties) return { properties, ...options };
700-
if ("additionalProperties" in schema) return { properties, ...options };
701-
702-
return t.Object(properties, {
703-
...options,
704-
additionalProperties: false,
705-
});
706-
},
700+
to(schema) {
701+
if (!schema.properties) return schema;
702+
if ("additionalProperties" in schema) return schema;
703+
704+
return t.Object(schema.properties, {
705+
...schema,
706+
additionalProperties: false,
707+
});
708+
}
707709
});
708710
}
709711

test/aot/has-type.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,21 @@ describe('Has Transform', () => {
6868
expect(hasType('File', schema)).toBe(true)
6969
})
7070

71+
it('found on direct Union', () => {
72+
const schema = t.Union([
73+
t.Object({
74+
id: t.Number(),
75+
liyue: t.File()
76+
}),
77+
t.Object({
78+
id: t.Number(),
79+
liyue: t.Number(),
80+
}),
81+
])
82+
83+
expect(hasType('File', schema)).toBe(true)
84+
})
85+
7186
it('find in Import wrapping File', () => {
7287
const schema = t.Module({
7388
Avatar: t.File()

0 commit comments

Comments
 (0)