Skip to content

Commit

Permalink
fix: lint
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastianwessel committed Jul 15, 2024
1 parent 21e6c03 commit 424652b
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 70 deletions.
6 changes: 3 additions & 3 deletions src/genSchema/generateTableSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ export const generateTableSchema = async (outFolder: string, tableInfo: Record<s
const generatedFiles: string[] = []

for (const name in tableInfo) {
const { inputFields, outputFields } = await generateSchemaForTable(name, tableInfo[name]!)
const info = tableInfo[name] as string
const { inputFields, outputFields } = await generateSchemaForTable(name, info)

const tableName = toCamelCase(name)
const tableSchemaFolder = resolve(genSchemaFolder, tableName)
Expand Down Expand Up @@ -166,9 +167,8 @@ export type ${toUpperCamelCase(tableName)} = z.output<typeof ${tableName}Schema>
} else {
console.log(' ❎ _generated/index.ts already exists')
}

} catch (error) {
console.error('An error occurred during schema generation:', error)
throw error
}
}
}
133 changes: 76 additions & 57 deletions src/genSchema/generateZodSchemaCode.test.ts
Original file line number Diff line number Diff line change
@@ -1,106 +1,120 @@
import { generateZodSchemaCode } from './generateZodSchemaCode.js'
import { getDetailsFromDefinition } from './getDetailsFromDefinition.js'
import {generateZodSchemaCode} from "./generateZodSchemaCode.js";

describe('generateZodSchemaCode', () => {
describe('basic schema', () => {
it('returns schema for simple object', () => {
const definition = `
describe('basic schema', () => {
it('returns schema for simple object', () => {
const definition = `
DEFINE FIELD reviews ON TABLE product TYPE array<string>;
DEFINE FIELD user ON TABLE product TYPE record<user>;
DEFINE FIELD rating ON TABLE product TYPE number;
`
const fields = definition.split(';').filter(x => x.trim().length).map(def => getDetailsFromDefinition(def, false))
const generatedSchema = generateZodSchemaCode(fields, 'schema')
const fields = definition
.split(';')
.filter(x => x.trim().length)
.map(def => getDetailsFromDefinition(def, false))
const generatedSchema = generateZodSchemaCode(fields, 'schema')

expect(generatedSchema).toEqualIgnoringWhitespace(`
expect(generatedSchema).toEqualIgnoringWhitespace(`
const schema = z.object({
reviews: z.array(z.string()),
user: recordId('user'),
rating: z.number()
})
`)
})
})
})
})

describe('object schema', () => {
it('returns schema for simple object', () => {
const definition = `
describe('object schema', () => {
it('returns schema for simple object', () => {
const definition = `
DEFINE FIELD review ON TABLE product TYPE object;
DEFINE FIELD review.rating ON TABLE product TYPE number;
DEFINE FIELD review.comment ON TABLE product TYPE string;
`
const fields = definition.split(';').filter(x => x.trim().length).map(def => getDetailsFromDefinition(def, false))
console.log("fields", fields)
const generatedSchema = generateZodSchemaCode(fields, 'schema')
const fields = definition
.split(';')
.filter(x => x.trim().length)
.map(def => getDetailsFromDefinition(def, false))
console.log('fields', fields)
const generatedSchema = generateZodSchemaCode(fields, 'schema')

console.log("generatedSchema", generatedSchema)
console.log('generatedSchema', generatedSchema)

expect(generatedSchema).toEqualIgnoringWhitespace(`
expect(generatedSchema).toEqualIgnoringWhitespace(`
const schema = z.object({
review: z.object({
rating: z.number(),
comment: z.string()
})
})
`)
})
})

it('returns schema for optional object', () => {
const definition = `
it('returns schema for optional object', () => {
const definition = `
DEFINE FIELD review ON TABLE product TYPE option<object>;
DEFINE FIELD review.rating ON TABLE product TYPE number;
DEFINE FIELD review.comment ON TABLE product TYPE string;
`
const fields = definition.split(';').filter(x => x.trim().length).map(def => getDetailsFromDefinition(def, false))
console.log("fields", fields)
const generatedSchema = generateZodSchemaCode(fields, 'schema')
const fields = definition
.split(';')
.filter(x => x.trim().length)
.map(def => getDetailsFromDefinition(def, false))
console.log('fields', fields)
const generatedSchema = generateZodSchemaCode(fields, 'schema')

console.log("generatedSchema", generatedSchema)
console.log('generatedSchema', generatedSchema)

expect(generatedSchema).toEqualIgnoringWhitespace(`
expect(generatedSchema).toEqualIgnoringWhitespace(`
const schema = z.object({
review: z.object({
rating: z.number(),
comment: z.string()
}).optional()
})
`)
})
})

it('returns schema for optional object derived from all values being optional', () => {
const definition = `
it('returns schema for optional object derived from all values being optional', () => {
const definition = `
DEFINE FIELD review ON TABLE product TYPE object;
DEFINE FIELD review.rating ON TABLE product TYPE option<number>;
DEFINE FIELD review.comment ON TABLE product TYPE option<string>;
`
const fields = definition.split(';').filter(x => x.trim().length).map(def => getDetailsFromDefinition(def, false))
console.log("fields", fields)
const generatedSchema = generateZodSchemaCode(fields, 'schema')
const fields = definition
.split(';')
.filter(x => x.trim().length)
.map(def => getDetailsFromDefinition(def, false))
console.log('fields', fields)
const generatedSchema = generateZodSchemaCode(fields, 'schema')

console.log("generatedSchema", generatedSchema)
console.log('generatedSchema', generatedSchema)

expect(generatedSchema).toEqualIgnoringWhitespace(`
expect(generatedSchema).toEqualIgnoringWhitespace(`
const schema = z.object({
review: z.object({
rating: z.number().optional(),
comment: z.string().optional()
}).optional()
})
`)
})
})

it('returns schema for object with nested array', () => {
const definition = `
it('returns schema for object with nested array', () => {
const definition = `
DEFINE FIELD review ON TABLE product TYPE object;
DEFINE FIELD review.related ON TABLE product TYPE array<object>;
DEFINE FIELD review.related[*].name ON TABLE product TYPE string;
DEFINE FIELD review.related[*].rating ON TABLE product TYPE number;
`
const fields = definition.split(';').filter(x => x.trim().length).map(def => getDetailsFromDefinition(def, false))
const generatedSchema = generateZodSchemaCode(fields, 'schema')
const fields = definition
.split(';')
.filter(x => x.trim().length)
.map(def => getDetailsFromDefinition(def, false))
const generatedSchema = generateZodSchemaCode(fields, 'schema')


expect(generatedSchema).toEqualIgnoringWhitespace(`
expect(generatedSchema).toEqualIgnoringWhitespace(`
const schema = z.object({
review: z.object({
related: z.object({
Expand All @@ -110,10 +124,10 @@ describe('generateZodSchemaCode', () => {
})
})
`)
})
})

it('returns schema for complex object', () => {
const definition = `
it('returns schema for complex object', () => {
const definition = `
DEFINE FIELD name ON TABLE product TYPE string;
DEFINE FIELD price ON TABLE product TYPE number;
DEFINE FIELD published_at ON TABLE product TYPE datetime;
Expand All @@ -136,13 +150,16 @@ describe('generateZodSchemaCode', () => {
DEFINE FIELD review.related[*].meta.comment ON TABLE product TYPE string;
DEFINE FIELD review.related[*].meta.tags ON TABLE product TYPE array<string>;
`
const fields = definition.split(';').filter(x => x.trim().length).map(def => getDetailsFromDefinition(def, false))
console.log("fields", fields)
const generatedSchema = generateZodSchemaCode(fields, 'schema')
const fields = definition
.split(';')
.filter(x => x.trim().length)
.map(def => getDetailsFromDefinition(def, false))
console.log('fields', fields)
const generatedSchema = generateZodSchemaCode(fields, 'schema')

console.log("generatedSchema", generatedSchema)
console.log('generatedSchema', generatedSchema)

expect(generatedSchema).toEqualIgnoringWhitespace(`
expect(generatedSchema).toEqualIgnoringWhitespace(`
const schema = z.object({
name: z.string(),
price: z.number(),
Expand Down Expand Up @@ -171,10 +188,10 @@ describe('generateZodSchemaCode', () => {
})
})
`)
})
})

it('returns schema for complex object with duplicate field with asterisk syntax', () => {
const definition = `
it('returns schema for complex object with duplicate field with asterisk syntax', () => {
const definition = `
DEFINE FIELD review ON TABLE product TYPE object;
DEFINE FIELD review.rating ON TABLE product TYPE number;
DEFINE FIELD review.comment ON TABLE product TYPE string;
Expand All @@ -185,10 +202,13 @@ describe('generateZodSchemaCode', () => {
DEFINE FIELD review.author.tags[*] ON TABLE product TYPE string;
DEFINE FIELD review.author.user ON TABLE product TYPE record<user>;
`
const fields = definition.split(';').filter(x => x.trim().length).map(def => getDetailsFromDefinition(def, false))
const generatedSchema = generateZodSchemaCode(fields, 'schema')
const fields = definition
.split(';')
.filter(x => x.trim().length)
.map(def => getDetailsFromDefinition(def, false))
const generatedSchema = generateZodSchemaCode(fields, 'schema')

expect(generatedSchema).toEqualIgnoringWhitespace(`
expect(generatedSchema).toEqualIgnoringWhitespace(`
const schema = z.object({
review: z.object({
rating: z.number(),
Expand All @@ -202,7 +222,6 @@ describe('generateZodSchemaCode', () => {
})
})
`)
})

})
})
})
})
19 changes: 9 additions & 10 deletions src/genSchema/generateZodSchemaCode.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import type { FieldDetail } from './getDetailsFromDefinition.js'

const escapeRegExp = (string:string) => {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
};
const escapeRegExp = (string: string) => {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
}

const createRegex = (key:string) => {
const escapedKey = escapeRegExp(key);
return new RegExp(`(?<!${escapedKey})\\[\\*\\]`, 'g');
};
const createRegex = (key: string) => {
const escapedKey = escapeRegExp(key)
return new RegExp(`(?<!${escapedKey})\\[\\*\\]`, 'g')
}

export const generateZodSchemaCode = (fields: FieldDetail[], schemaName: string): string => {
console.log("fields", fields)
console.log('fields', fields)
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
const buildSchema = (fieldMap: { [key: string]: any }, fields: FieldDetail[]) => {
for (const field of fields) {
Expand Down Expand Up @@ -48,7 +48,7 @@ export const generateZodSchemaCode = (fields: FieldDetail[], schemaName: string)
const fullKey = parentKey ? `${parentKey}.${key}` : key
const regex = createRegex(key)
const isArray = fields.some(f => {
return f.name.replace(regex, '').includes(`${fullKey}[*]`)
return f.name.replace(regex, '').includes(`${fullKey}[*]`)
})

if (typeof value === 'string') {
Expand Down Expand Up @@ -77,7 +77,6 @@ export const generateZodSchemaCode = (fields: FieldDetail[], schemaName: string)
return entries.join(',\n ')
}


const schema = `z.object({\n${buildObject(fieldMap)}\n})`
return `const ${schemaName} = ${schema}`
}
Expand Down

0 comments on commit 424652b

Please sign in to comment.