mirror of
https://github.com/zhigang1992/pocketbase-typegen.git
synced 2026-04-29 12:45:19 +08:00
refactor type map
This commit is contained in:
42
src/lib.ts
42
src/lib.ts
@@ -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) {
|
||||
|
||||
@@ -29,6 +29,7 @@ export type CollectionRecord = {
|
||||
schema: Array<RecordSchema>
|
||||
}
|
||||
|
||||
// Every field is optional
|
||||
export type RecordOptions = {
|
||||
maxSelect?: number | null
|
||||
min?: number | null
|
||||
|
||||
158
test/lib.test.ts
158
test/lib.test.ts
@@ -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")
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user