refactor type map

This commit is contained in:
Patrick
2022-10-23 10:41:27 -07:00
parent 26012a03e5
commit 88ff1c1cf1
3 changed files with 137 additions and 64 deletions

View File

@@ -1,4 +1,4 @@
import { CollectionRecord, RecordSchema } from "./types"
import { CollectionRecord, RecordOptions, RecordSchema } from "./types"
import { promises as fs } from "fs"
import { toPascalCase } from "./utils"
@@ -12,8 +12,8 @@ const pbSchemaTypescriptMap = {
date: "string",
select: "string",
json: "null | unknown",
file: "string",
files: "string[]",
file: (opts: RecordOptions) =>
opts.maxSelect && opts.maxSelect > 1 ? "string[]" : "string",
relation: "string",
user: "string",
}
@@ -61,31 +61,29 @@ export function createRecordType(
schema: Array<RecordSchema>
): string {
let typeString = `export type ${toPascalCase(name)}Record = {\n`
schema.forEach((field: RecordSchema) => {
const pbType =
field.type === "file" &&
field.options.maxSelect &&
field.options.maxSelect > 1
? "files"
: field.type
typeString += createTypeField(field.name, field.required, pbType)
schema.forEach((recordSchema: RecordSchema) => {
typeString += createTypeField(recordSchema)
})
typeString += `}`
return typeString
}
export function createTypeField(
name: string,
required: boolean,
pbType: string
) {
if (pbType in pbSchemaTypescriptMap) {
return `\t${name}${required ? "" : "?"}: ${
pbSchemaTypescriptMap[pbType as keyof typeof pbSchemaTypescriptMap]
}\n`
} else {
throw new Error(`unknown type ${pbType} found in schema`)
export function createTypeField(recordSchema: RecordSchema) {
if (!(recordSchema.type in pbSchemaTypescriptMap)) {
throw new Error(`unknown type ${recordSchema.type} found in schema`)
}
const typeStringOrFunc =
pbSchemaTypescriptMap[
recordSchema.type as keyof typeof pbSchemaTypescriptMap
]
const typeString =
typeof typeStringOrFunc === "function"
? typeStringOrFunc(recordSchema.options)
: typeStringOrFunc
return `\t${recordSchema.name}${
recordSchema.required ? "" : "?"
}: ${typeString}\n`
}
export async function saveFile(outPath: string, typeString: string) {

View File

@@ -29,6 +29,7 @@ export type CollectionRecord = {
schema: Array<RecordSchema>
}
// Every field is optional
export type RecordOptions = {
maxSelect?: number | null
min?: number | null

View File

@@ -7,6 +7,16 @@ import {
generate,
} from "../src/lib"
const defaultRecord = {
id: "abc",
system: false,
unique: false,
options: {},
name: "defaultName",
required: true,
type: "text",
}
describe("generate", () => {
it("generates correct output given db input", () => {
const collections: Array<CollectionRecord> = [
@@ -89,53 +99,117 @@ describe("createRecordType", () => {
describe("createTypeField", () => {
it("handles required and optional fields", () => {
expect(createTypeField("name", true, "text")).toEqual("\tname: string\n")
expect(createTypeField("name", false, "text")).toEqual("\tname?: string\n")
expect(
createTypeField({
...defaultRecord,
required: false,
})
).toEqual("\tdefaultName?: string\n")
expect(
createTypeField({
...defaultRecord,
required: true,
})
).toEqual("\tdefaultName: string\n")
})
it("converts pocketbase schema types to typescript", () => {
expect(createTypeField("name", true, "text")).toEqual("\tname: string\n")
expect(createTypeField("textField", true, "text")).toEqual(
"\ttextField: string\n"
)
expect(createTypeField("numberField", true, "number")).toEqual(
"\tnumberField: number\n"
)
expect(createTypeField("boolField", true, "bool")).toEqual(
"\tboolField: boolean\n"
)
expect(createTypeField("emailField", true, "email")).toEqual(
"\temailField: string\n"
)
expect(createTypeField("urlField", true, "url")).toEqual(
"\turlField: string\n"
)
expect(createTypeField("dateField", true, "date")).toEqual(
"\tdateField: string\n"
)
expect(createTypeField("selectField", true, "select")).toEqual(
"\tselectField: string\n"
)
expect(createTypeField("jsonField", true, "json")).toEqual(
"\tjsonField: null | unknown\n"
)
expect(createTypeField("fileField", true, "file")).toEqual(
"\tfileField: string\n"
)
expect(createTypeField("manyFiles", true, "files")).toEqual(
"\tmanyFiles: string[]\n"
)
expect(createTypeField("relationField", true, "relation")).toEqual(
"\trelationField: string\n"
)
expect(createTypeField("userField", true, "user")).toEqual(
"\tuserField: string\n"
)
expect(
createTypeField({
...defaultRecord,
})
).toEqual("\tdefaultName: string\n")
expect(
createTypeField({
...defaultRecord,
name: "textField",
})
).toEqual("\ttextField: string\n")
expect(
createTypeField({
...defaultRecord,
name: "numberField",
type: "number",
})
).toEqual("\tnumberField: number\n")
expect(
createTypeField({
...defaultRecord,
name: "boolField",
type: "bool",
})
).toEqual("\tboolField: boolean\n")
expect(
createTypeField({
...defaultRecord,
name: "emailField",
type: "email",
})
).toEqual("\temailField: string\n")
expect(
createTypeField({
...defaultRecord,
name: "urlField",
type: "url",
})
).toEqual("\turlField: string\n")
expect(
createTypeField({
...defaultRecord,
name: "dateField",
type: "date",
})
).toEqual("\tdateField: string\n")
expect(
createTypeField({
...defaultRecord,
name: "selectField",
type: "select",
})
).toEqual("\tselectField: string\n")
expect(
createTypeField({
...defaultRecord,
name: "jsonField",
type: "json",
})
).toEqual("\tjsonField: null | unknown\n")
expect(
createTypeField({
...defaultRecord,
name: "fileField",
type: "file",
})
).toEqual("\tfileField: string\n")
expect(
createTypeField({
...defaultRecord,
name: "fileField",
type: "file",
options: {
maxSelect: 3,
},
})
).toEqual("\tfileField: string[]\n")
expect(
createTypeField({
...defaultRecord,
name: "relationField",
type: "relation",
})
).toEqual("\trelationField: string\n")
expect(
createTypeField({
...defaultRecord,
name: "userField",
type: "user",
})
).toEqual("\tuserField: string\n")
})
it("throws for unexpected types", () => {
expect(() => createTypeField("name", true, "unknowntype")).toThrowError(
"unknown type unknowntype found in schema"
)
expect(() =>
createTypeField({ ...defaultRecord, type: "unknowntype" })
).toThrowError("unknown type unknowntype found in schema")
})
})