Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/strong-worms-watch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@alova/wormhole": patch
---

handle array default items in union and avoid TypeError
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,21 @@ export const TYPE_SPECIFIC_KEYWORDS = {
array: ['items', 'minItems', 'maxItems', 'uniqueItems'],
object: ['properties', 'additionalProperties', 'required', 'minProperties', 'maxProperties'],
}
export const TYPE_REQUIRE_KEYWORDS: Record<string, Array<[string, any]>> = {
string: [],
number: [],
integer: [],
array: [['items', { type: 'any' }]],
object: [],
}

export function assignTypeSpecificKeywords(
branch: SchemaObject,
type: string,
typeSpecificKeywords: Record<string, any>,
) {
const keywords = TYPE_SPECIFIC_KEYWORDS[type as keyof typeof TYPE_SPECIFIC_KEYWORDS]
const requireKeywords = TYPE_REQUIRE_KEYWORDS[type as keyof typeof TYPE_REQUIRE_KEYWORDS]
if (!keywords) {
return
}
Expand All @@ -32,6 +40,11 @@ export function assignTypeSpecificKeywords(
(branch as any)[key] = typeSpecificKeywords[key]
}
})
requireKeywords.forEach(([key, value]) => {
if (!(key in typeSpecificKeywords)) {
(branch as any)[key] = value
}
})
}

export default function convertTypeArray(schema: SchemaObject): SchemaObject | void {
Expand Down
20 changes: 19 additions & 1 deletion packages/wormhole/test/generates/array.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ describe('array Type Generator', () => {
comment: ``,
type: 'type',
code: `Array<{
value?:string
value?:string
}>`,
})
expect(result).toEqual(expectResult)
Expand Down Expand Up @@ -167,4 +167,22 @@ describe('array Type Generator', () => {
})
expect(result).toEqual(expectResult)
})

it('should generate array type with ANY default', async () => {
const ast: TArray = {
type: ASTType.ARRAY,
keyName: 'AnyArray',
params: {
type: ASTType.ANY,
},
}
const result = await normalizeGeneratorResult(arrayTypeGenerator(ast, defaultCtx))
const expectResult = await normalizeGeneratorResult({
name: 'AnyArray',
comment: ``,
type: 'type',
code: `any[]`,
})
expect(result).toEqual(expectResult)
})
})
50 changes: 38 additions & 12 deletions packages/wormhole/test/generates/group.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('group Type Generator', () => {
name: 'Status',
comment: `
/**
* Status type
* Status type
*/`,
type: 'type',
code: 'string | number',
Expand Down Expand Up @@ -83,10 +83,10 @@ describe('group Type Generator', () => {
* User with role
*/`,
type: 'type',
code: `{
name?:string
} & {
role?:string
code: `{
name?:string
} & {
role?:string
}`,
})
expect(result).toEqual(expectResult)
Expand Down Expand Up @@ -145,12 +145,12 @@ describe('group Type Generator', () => {
name: 'ComplexType',
comment: '',
type: 'type',
code: `{
id?:number
code: `{
id?:number
} & {
name?:string
name?:string
} | {
code?:string
code?:string
}`,
})
expect(result).toEqual(expectResult)
Expand Down Expand Up @@ -196,12 +196,38 @@ describe('group Type Generator', () => {
name: 'DeepTest',
comment: '',
type: 'type',
code: `{
value?:string
code: `{
value?:string
} | {
value?:number
value?:number
}`,
})
expect(result).toEqual(expectResult)
})

it('should generate union including array(any) and null (fix #140)', async () => {
const ast: TUnion = {
type: ASTType.UNION,
keyName: 'MaybeArray',
params: [
{
type: ASTType.ARRAY,
params: {
type: ASTType.ANY,
},
},
{
type: ASTType.NULL,
},
],
}
const result = await normalizeGeneratorResult(groupTypeGenerator(ast, defaultCtx))
const expectResult = await normalizeGeneratorResult({
name: 'MaybeArray',
comment: '',
type: 'type',
code: 'any[] | null',
})
expect(result).toEqual(expectResult)
})
})
40 changes: 40 additions & 0 deletions packages/wormhole/test/normalize.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,46 @@ describe('schema Normalizer', () => {
expect(stringBranch.minLength).toBe(5)
expect((stringBranch as ArraySchemaObject).items).toBeUndefined()
})

it('should assign default items for array branch when items missing', () => {
const schema: SchemaObject = {
type: ['array', 'string'],
minLength: 5,
title: 'Test',
}

const result = normalizer.normalize(schema) as SchemaObject
expect(result.anyOf).toBeDefined()
expect(result.anyOf).toHaveLength(2)

const arrayBranch = result.anyOf![0] as ArraySchemaObject
const stringBranch = result.anyOf![1] as SchemaObject

expect(arrayBranch.type).toBe('array')
expect(arrayBranch.items).toBeDefined()
expect((arrayBranch.items as SchemaObject).type).toBeDefined()
expect(stringBranch.type).toBe('string')
expect(stringBranch.minLength).toBe(5)
})

it('should handle array | null union by injecting default items into array branch (fix #140)', () => {
const schema: SchemaObject = {
type: ['array', 'null'] as any,
title: 'Issue 140',
}
const result = normalizer.normalize(schema) as SchemaObject
expect(result.type).toBeUndefined()
expect(result.anyOf).toBeDefined()
expect(result.anyOf).toHaveLength(2)

const arrayBranch = result.anyOf![0] as ArraySchemaObject
const nullBranch = result.anyOf![1] as SchemaObject

expect(arrayBranch.type).toBe('array')
expect(arrayBranch.items).toBeDefined()
expect((arrayBranch.items as SchemaObject).type).toBeDefined()
expect(nullBranch.type).toBe('null')
})
})

describe('mergeAnyOf rule', () => {
Expand Down
Loading