Skip to content

Commit

Permalink
Merge pull request #24 from sebastianwessel/22-handle-array-with-allo…
Browse files Browse the repository at this point in the history
…wed-values

feat: Handle array and string with allowed values #22
  • Loading branch information
sebastianwessel authored Jun 22, 2024
2 parents e674263 + c0befd8 commit 7f38490
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 15 deletions.
27 changes: 27 additions & 0 deletions src/genSchema/getDetailsFromDefinition.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,33 @@ describe('getDetailsFromDefinition', () => {

expect(result.zodString).toBe('z.array(z.string())')
})

it('generates a enum schema for string', () => {
const result = getDetailsFromDefinition(
"DEFINE FIELD permissions ON acl TYPE string ASSERT INSIDE ['create', 'read', 'write', 'delete'] PERMISSIONS FULL;",
isInputSchema,
)

expect(result.zodString).toBe("z.enum(['create', 'read', 'write', 'delete'])")
})

it('generates a enum schema for array<string>', () => {
const result = getDetailsFromDefinition(
"DEFINE FIELD permissions ON acl TYPE array<string> ASSERT ALLINSIDE ['create', 'read', 'write', 'delete'] PERMISSIONS FULL;",
isInputSchema,
)

expect(result.zodString).toBe("z.array(z.enum(['create', 'read', 'write', 'delete']))")
})

it('generates a enum schema for array', () => {
const result = getDetailsFromDefinition(
"DEFINE FIELD permissions ON acl TYPE array ASSERT ALLINSIDE ['create', 'read', 'write', 'delete'] PERMISSIONS FULL;",
isInputSchema,
)

expect(result.zodString).toBe("z.array(z.enum(['create', 'read', 'write', 'delete']))")
})
})

describe('output schema', () => {
Expand Down
26 changes: 15 additions & 11 deletions src/genSchema/getDetailsFromDefinition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { type TokenizedDefinition, tokenize } from './tokenize.js'

const _optionalTypeRegex = /option<([^>]*)>/im
const stringAssertionRegex = /\sstring::is::([^)]*)\(/im
const _allInsideAssertionRegex = /ASSERT (?:.*)ALLINSIDE (\[.*\])/im
const insideAssertionRegex = /ASSERT (?:.*)INSIDE (\[.*\])/im
const allInsideAssertionRegex = /ALLINSIDE (\[.*\])/im
const insideAssertionRegex = /INSIDE (\[.*\])/im

const typeRegex = /(?:option<)?(\w+)(?:<)?(\w+)?/i

Expand All @@ -17,9 +17,8 @@ const getStringType = (tokens: TokenizedDefinition): string => {

let match = tokens.assert.match(insideAssertionRegex)

if (match) {
// TODO: convert to enum
return 'z.string()'
if (match?.[1]) {
return `z.enum(${match[1]})`
}

match = tokens.assert.match(stringAssertionRegex)
Expand All @@ -43,9 +42,14 @@ const getStringType = (tokens: TokenizedDefinition): string => {
return result
}

const getArrayType = (tokens: TokenizedDefinition, subSchema?: string): string => {
const getArrayType = (tokens: TokenizedDefinition): string => {
const match = tokens.type?.match(typeRegex)

const enumMatch = tokens.assert?.match(allInsideAssertionRegex)
if (enumMatch?.[1]) {
return `z.array(z.enum(${enumMatch[1]}))`
}

if (match && match.length > 2) {
const t = getZodTypeFromQLType(
{
Expand All @@ -57,7 +61,7 @@ const getArrayType = (tokens: TokenizedDefinition, subSchema?: string): string =
return `z.array(${t})`
}

return `z.array(${subSchema ?? 'z.unknown()'})`
return 'z.array(z.unknown())'
}

const makeOptional = (schema: string, tokens: TokenizedDefinition, isInputSchema: boolean) => {
Expand Down Expand Up @@ -102,14 +106,14 @@ export const getZodTypeFromQLType = (tokens: TokenizedDefinition, isInputSchema:
case 'object':
return makeFlexible(makeOptional(subSchema ?? 'z.object({})', tokens, isInputSchema), !!tokens.flexible)
case 'record':
return 'z.any()'
return 'z.unknown()'
case 'geometry':
return 'z.any()'
return 'z.unknown()'
default:
return 'z.any()'
return 'z.unknown()'
}
}
return 'z.any()'
return 'z.unknown()'
}

export const shouldFieldBeSkipped = (tokens: TokenizedDefinition, isInputSchema: boolean): boolean => {
Expand Down
8 changes: 4 additions & 4 deletions src/genSchema/tokenizer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ describe('Field schema generation', () => {
type: 'array',
})

expect(getZodTypeFromQLType(result, false)).toBe('z.array(z.any())')
expect(getZodTypeFromQLType(result, false)).toBe('z.array(z.unknown())')
})

it('optional', () => {
Expand All @@ -404,7 +404,7 @@ describe('Field schema generation', () => {
type: 'option<array>',
})

expect(getZodTypeFromQLType(result, false)).toBe('z.array(z.any()).optional()')
expect(getZodTypeFromQLType(result, false)).toBe('z.array(z.unknown()).optional()')
})

it('is optional for input if default is set', () => {
Expand All @@ -418,7 +418,7 @@ describe('Field schema generation', () => {
default: '[1,2,3]',
})

expect(getZodTypeFromQLType(result, true)).toBe('z.array(z.any()).optional()')
expect(getZodTypeFromQLType(result, true)).toBe('z.array(z.unknown()).optional()')
})

it('is required for output if default is set', () => {
Expand All @@ -432,7 +432,7 @@ describe('Field schema generation', () => {
default: '[1,2,3]',
})

expect(getZodTypeFromQLType(result, false)).toBe('z.array(z.any())')
expect(getZodTypeFromQLType(result, false)).toBe('z.array(z.unknown())')
})

it('optional number array', () => {
Expand Down

0 comments on commit 7f38490

Please sign in to comment.