mirror of
https://github.com/zhigang1992/pocketbase-typegen.git
synced 2026-01-12 09:14:16 +08:00
Refactor fields (#48)
* separate out field handling into new file * sort fields * formatting
This commit is contained in:
@@ -18,6 +18,10 @@
|
||||
"rules": {
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"sort-keys-fix/sort-keys-fix": "warn"
|
||||
"sort-keys-fix/sort-keys-fix": [
|
||||
"warn",
|
||||
"asc",
|
||||
{ "allowLineSeparatedGroups": true }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
96
src/fields.ts
Normal file
96
src/fields.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import {
|
||||
DATE_STRING_TYPE_NAME,
|
||||
HTML_STRING_NAME,
|
||||
RECORD_ID_STRING_NAME,
|
||||
} from "./constants"
|
||||
import { getOptionEnumName, getOptionValues, sanitizeFieldName } from "./utils"
|
||||
|
||||
import { FieldSchema } from "./types"
|
||||
import { fieldNameToGeneric } from "./generics"
|
||||
|
||||
/**
|
||||
* Convert the pocketbase field type to the equivalent typescript type
|
||||
*/
|
||||
export const pbSchemaTypescriptMap = {
|
||||
// Basic fields
|
||||
bool: "boolean",
|
||||
date: DATE_STRING_TYPE_NAME,
|
||||
editor: HTML_STRING_NAME,
|
||||
email: "string",
|
||||
text: "string",
|
||||
url: "string",
|
||||
number: "number",
|
||||
|
||||
// Dependent on schema
|
||||
file: (fieldSchema: FieldSchema) =>
|
||||
fieldSchema.options.maxSelect && fieldSchema.options.maxSelect > 1
|
||||
? "string[]"
|
||||
: "string",
|
||||
json: (fieldSchema: FieldSchema) =>
|
||||
`null | ${fieldNameToGeneric(fieldSchema.name)}`,
|
||||
relation: (fieldSchema: FieldSchema) =>
|
||||
fieldSchema.options.maxSelect && fieldSchema.options.maxSelect === 1
|
||||
? RECORD_ID_STRING_NAME
|
||||
: `${RECORD_ID_STRING_NAME}[]`,
|
||||
select: (fieldSchema: FieldSchema, collectionName: string) => {
|
||||
// pocketbase v0.8+ values are required
|
||||
const valueType = fieldSchema.options.values
|
||||
? getOptionEnumName(collectionName, fieldSchema.name)
|
||||
: "string"
|
||||
return fieldSchema.options.maxSelect && fieldSchema.options.maxSelect > 1
|
||||
? `${valueType}[]`
|
||||
: valueType
|
||||
},
|
||||
|
||||
// DEPRECATED: PocketBase v0.8 does not have a dedicated user relation
|
||||
user: (fieldSchema: FieldSchema) =>
|
||||
fieldSchema.options.maxSelect && fieldSchema.options.maxSelect > 1
|
||||
? `${RECORD_ID_STRING_NAME}[]`
|
||||
: RECORD_ID_STRING_NAME,
|
||||
}
|
||||
|
||||
export function createTypeField(
|
||||
collectionName: string,
|
||||
fieldSchema: FieldSchema
|
||||
): string {
|
||||
let typeStringOrFunc:
|
||||
| string
|
||||
| ((fieldSchema: FieldSchema, collectionName: string) => string)
|
||||
|
||||
if (!(fieldSchema.type in pbSchemaTypescriptMap)) {
|
||||
console.log(`WARNING: unknown type "${fieldSchema.type}" found in schema`)
|
||||
typeStringOrFunc = "unknown"
|
||||
} else {
|
||||
typeStringOrFunc =
|
||||
pbSchemaTypescriptMap[
|
||||
fieldSchema.type as keyof typeof pbSchemaTypescriptMap
|
||||
]
|
||||
}
|
||||
|
||||
const typeString =
|
||||
typeof typeStringOrFunc === "function"
|
||||
? typeStringOrFunc(fieldSchema, collectionName)
|
||||
: typeStringOrFunc
|
||||
|
||||
const fieldName = sanitizeFieldName(fieldSchema.name)
|
||||
const required = fieldSchema.required ? "" : "?"
|
||||
|
||||
return `\t${fieldName}${required}: ${typeString}`
|
||||
}
|
||||
|
||||
export function createSelectOptions(
|
||||
recordName: string,
|
||||
schema: Array<FieldSchema>
|
||||
): string {
|
||||
const selectFields = schema.filter((field) => field.type === "select")
|
||||
const typestring = selectFields
|
||||
.map(
|
||||
(field) => `export enum ${getOptionEnumName(recordName, field.name)} {
|
||||
${getOptionValues(field)
|
||||
.map((val) => `\t"${val}" = "${val}",`)
|
||||
.join("\n")}
|
||||
}\n`
|
||||
)
|
||||
.join("\n")
|
||||
return typestring
|
||||
}
|
||||
116
src/lib.ts
116
src/lib.ts
@@ -2,79 +2,27 @@ import {
|
||||
ALIAS_TYPE_DEFINITIONS,
|
||||
AUTH_SYSTEM_FIELDS_DEFINITION,
|
||||
BASE_SYSTEM_FIELDS_DEFINITION,
|
||||
DATE_STRING_TYPE_NAME,
|
||||
EXPAND_GENERIC_NAME,
|
||||
EXPORT_COMMENT,
|
||||
HTML_STRING_NAME,
|
||||
RECORD_ID_STRING_NAME,
|
||||
RECORD_TYPE_COMMENT,
|
||||
RESPONSE_TYPE_COMMENT,
|
||||
} from "./constants"
|
||||
import { CollectionRecord, FieldSchema } from "./types"
|
||||
import {
|
||||
canExpand,
|
||||
fieldNameToGeneric,
|
||||
getGenericArgStringForRecord,
|
||||
getGenericArgStringWithDefault,
|
||||
} from "./generics"
|
||||
import {
|
||||
getOptionEnumName,
|
||||
getOptionValues,
|
||||
getSystemFields,
|
||||
sanitizeFieldName,
|
||||
toPascalCase,
|
||||
} from "./utils"
|
||||
import { createSelectOptions, createTypeField } from "./fields"
|
||||
import { getSystemFields, toPascalCase } from "./utils"
|
||||
|
||||
const pbSchemaTypescriptMap = {
|
||||
bool: "boolean",
|
||||
date: DATE_STRING_TYPE_NAME,
|
||||
editor: HTML_STRING_NAME,
|
||||
email: "string",
|
||||
file: (fieldSchema: FieldSchema) =>
|
||||
fieldSchema.options.maxSelect && fieldSchema.options.maxSelect > 1
|
||||
? "string[]"
|
||||
: "string",
|
||||
json: (fieldSchema: FieldSchema) =>
|
||||
`null | ${fieldNameToGeneric(fieldSchema.name)}`,
|
||||
number: "number",
|
||||
relation: (fieldSchema: FieldSchema) =>
|
||||
fieldSchema.options.maxSelect && fieldSchema.options.maxSelect === 1
|
||||
? RECORD_ID_STRING_NAME
|
||||
: `${RECORD_ID_STRING_NAME}[]`,
|
||||
select: (fieldSchema: FieldSchema, collectionName: string) => {
|
||||
// pocketbase v0.8+ values are required
|
||||
const valueType = fieldSchema.options.values
|
||||
? getOptionEnumName(collectionName, fieldSchema.name)
|
||||
: "string"
|
||||
return fieldSchema.options.maxSelect && fieldSchema.options.maxSelect > 1
|
||||
? `${valueType}[]`
|
||||
: valueType
|
||||
},
|
||||
text: "string",
|
||||
|
||||
url: "string",
|
||||
// DEPRECATED: PocketBase v0.8 does not have a dedicated user relation
|
||||
user: (fieldSchema: FieldSchema) =>
|
||||
fieldSchema.options.maxSelect && fieldSchema.options.maxSelect > 1
|
||||
? `${RECORD_ID_STRING_NAME}[]`
|
||||
: RECORD_ID_STRING_NAME,
|
||||
}
|
||||
|
||||
export function generate(results: Array<CollectionRecord>) {
|
||||
export function generate(results: Array<CollectionRecord>): string {
|
||||
const collectionNames: Array<string> = []
|
||||
const recordTypes: Array<string> = []
|
||||
const responseTypes: Array<string> = [RESPONSE_TYPE_COMMENT]
|
||||
|
||||
results
|
||||
.sort((a, b) => {
|
||||
if (a.name < b.name) {
|
||||
return -1
|
||||
}
|
||||
if (a.name > b.name) {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
.sort((a, b) => (a.name <= b.name ? -1 : 1))
|
||||
.forEach((row) => {
|
||||
if (row.name) collectionNames.push(row.name)
|
||||
if (row.schema) {
|
||||
@@ -99,7 +47,7 @@ export function generate(results: Array<CollectionRecord>) {
|
||||
return fileParts.join("\n\n")
|
||||
}
|
||||
|
||||
export function createCollectionEnum(collectionNames: Array<string>) {
|
||||
export function createCollectionEnum(collectionNames: Array<string>): string {
|
||||
const collections = collectionNames
|
||||
.map((name) => `\t${toPascalCase(name)} = "${name}",`)
|
||||
.join("\n")
|
||||
@@ -109,7 +57,9 @@ ${collections}
|
||||
return typeString
|
||||
}
|
||||
|
||||
export function createCollectionRecords(collectionNames: Array<string>) {
|
||||
export function createCollectionRecords(
|
||||
collectionNames: Array<string>
|
||||
): string {
|
||||
const nameRecordMap = collectionNames
|
||||
.map((name) => `\t${name}: ${toPascalCase(name)}Record`)
|
||||
.join("\n")
|
||||
@@ -136,7 +86,9 @@ ${fields}
|
||||
}`
|
||||
}
|
||||
|
||||
export function createResponseType(collectionSchemaEntry: CollectionRecord) {
|
||||
export function createResponseType(
|
||||
collectionSchemaEntry: CollectionRecord
|
||||
): string {
|
||||
const { name, schema, type } = collectionSchemaEntry
|
||||
const pascaleName = toPascalCase(name)
|
||||
const genericArgsWithDefaults = getGenericArgStringWithDefault(schema, {
|
||||
@@ -148,49 +100,3 @@ export function createResponseType(collectionSchemaEntry: CollectionRecord) {
|
||||
|
||||
return `export type ${pascaleName}Response${genericArgsWithDefaults} = ${pascaleName}Record${genericArgsForRecord} & ${systemFields}${expandArgString}`
|
||||
}
|
||||
|
||||
export function createTypeField(
|
||||
collectionName: string,
|
||||
fieldSchema: FieldSchema
|
||||
) {
|
||||
let typeStringOrFunc:
|
||||
| string
|
||||
| ((fieldSchema: FieldSchema, collectionName: string) => string)
|
||||
|
||||
if (!(fieldSchema.type in pbSchemaTypescriptMap)) {
|
||||
console.log(`WARNING: unknown type "${fieldSchema.type}" found in schema`)
|
||||
typeStringOrFunc = "unknown"
|
||||
} else {
|
||||
typeStringOrFunc =
|
||||
pbSchemaTypescriptMap[
|
||||
fieldSchema.type as keyof typeof pbSchemaTypescriptMap
|
||||
]
|
||||
}
|
||||
|
||||
const typeString =
|
||||
typeof typeStringOrFunc === "function"
|
||||
? typeStringOrFunc(fieldSchema, collectionName)
|
||||
: typeStringOrFunc
|
||||
|
||||
const fieldName = sanitizeFieldName(fieldSchema.name)
|
||||
const required = fieldSchema.required ? "" : "?"
|
||||
|
||||
return `\t${fieldName}${required}: ${typeString}`
|
||||
}
|
||||
|
||||
export function createSelectOptions(
|
||||
recordName: string,
|
||||
schema: Array<FieldSchema>
|
||||
) {
|
||||
const selectFields = schema.filter((field) => field.type === "select")
|
||||
const typestring = selectFields
|
||||
.map(
|
||||
(field) => `export enum ${getOptionEnumName(recordName, field.name)} {
|
||||
${getOptionValues(field)
|
||||
.map((val) => `\t"${val}" = "${val}",`)
|
||||
.join("\n")}
|
||||
}\n`
|
||||
)
|
||||
.join("\n")
|
||||
return typestring
|
||||
}
|
||||
|
||||
@@ -36,8 +36,7 @@ export async function fromURL(
|
||||
// Login
|
||||
const { token } = await fetch(`${url}/api/admins/auth-with-password`, {
|
||||
// @ts-ignore
|
||||
body: formData,
|
||||
|
||||
body: formData,
|
||||
method: "post",
|
||||
}).then((res) => res.json())
|
||||
|
||||
|
||||
11
test/__snapshots__/fields.test.ts.snap
Normal file
11
test/__snapshots__/fields.test.ts.snap
Normal file
@@ -0,0 +1,11 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`createSelectOptions creates enum types for select options 1`] = `
|
||||
"export enum ChooseTitleOptions {
|
||||
"one" = "one",
|
||||
"two" = "two",
|
||||
"space space" = "space space",
|
||||
"$@#*(&#%" = "$@#*(&#%",
|
||||
}
|
||||
"
|
||||
`;
|
||||
@@ -34,16 +34,6 @@ exports[`createResponseType handles file fields with multiple files 1`] = `
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`createSelectOptions creates enum types for select options 1`] = `
|
||||
"export enum ChooseTitleOptions {
|
||||
"one" = "one",
|
||||
"two" = "two",
|
||||
"space space" = "space space",
|
||||
"$@#*(&#%" = "$@#*(&#%",
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`generate generates correct output given db input 1`] = `
|
||||
"/**
|
||||
* This file was @generated using pocketbase-typegen
|
||||
|
||||
267
test/fields.test.ts
Normal file
267
test/fields.test.ts
Normal file
@@ -0,0 +1,267 @@
|
||||
import { createSelectOptions, createTypeField } from "../src/fields"
|
||||
|
||||
import { FieldSchema } from "../src/types"
|
||||
|
||||
const defaultFieldSchema: FieldSchema = {
|
||||
id: "abc",
|
||||
name: "defaultName",
|
||||
options: {},
|
||||
required: true,
|
||||
system: false,
|
||||
type: "text",
|
||||
unique: false,
|
||||
}
|
||||
|
||||
describe("createTypeField", () => {
|
||||
it("handles required and optional fields", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
required: false,
|
||||
})
|
||||
).toEqual("\tdefaultName?: string")
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
required: true,
|
||||
})
|
||||
).toEqual("\tdefaultName: string")
|
||||
})
|
||||
|
||||
it("converts default types to typescript", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
})
|
||||
).toEqual("\tdefaultName: string")
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "textField",
|
||||
})
|
||||
).toEqual("\ttextField: string")
|
||||
})
|
||||
|
||||
it("converts number type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "numberField",
|
||||
type: "number",
|
||||
})
|
||||
).toEqual("\tnumberField: number")
|
||||
})
|
||||
|
||||
it("converts bool type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "boolField",
|
||||
type: "bool",
|
||||
})
|
||||
).toEqual("\tboolField: boolean")
|
||||
})
|
||||
|
||||
it("converts email type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "emailField",
|
||||
type: "email",
|
||||
})
|
||||
).toEqual("\temailField: string")
|
||||
})
|
||||
|
||||
it("converts url type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "urlField",
|
||||
type: "url",
|
||||
})
|
||||
).toEqual("\turlField: string")
|
||||
})
|
||||
|
||||
it("converts date type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "dateField",
|
||||
type: "date",
|
||||
})
|
||||
).toEqual("\tdateField: IsoDateString")
|
||||
})
|
||||
|
||||
it("converts select type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "selectField",
|
||||
type: "select",
|
||||
})
|
||||
).toEqual("\tselectField: string")
|
||||
})
|
||||
|
||||
it("converts select type with value", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "selectFieldWithOpts",
|
||||
options: {
|
||||
values: ["one", "two", "three"],
|
||||
},
|
||||
type: "select",
|
||||
})
|
||||
).toEqual(`\tselectFieldWithOpts: TestCollectionSelectFieldWithOptsOptions`)
|
||||
})
|
||||
|
||||
it("converts multi-select type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "selectField",
|
||||
options: {
|
||||
maxSelect: 2,
|
||||
},
|
||||
type: "select",
|
||||
})
|
||||
).toEqual("\tselectField: string[]")
|
||||
})
|
||||
|
||||
it("converts multi-select type with values", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "selectFieldWithOpts",
|
||||
options: {
|
||||
maxSelect: 2,
|
||||
values: ["one", "two", "three"],
|
||||
},
|
||||
type: "select",
|
||||
})
|
||||
).toEqual(
|
||||
`\tselectFieldWithOpts: TestCollectionSelectFieldWithOptsOptions[]`
|
||||
)
|
||||
})
|
||||
|
||||
it("converts json type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "jsonField",
|
||||
type: "json",
|
||||
})
|
||||
).toEqual("\tjsonField: null | TjsonField")
|
||||
})
|
||||
|
||||
it("converts editor type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "editorField",
|
||||
type: "editor",
|
||||
})
|
||||
).toEqual("\teditorField: HTMLString")
|
||||
})
|
||||
|
||||
it("converts file type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "fileField",
|
||||
type: "file",
|
||||
})
|
||||
).toEqual("\tfileField: string")
|
||||
})
|
||||
|
||||
it("converts file type with multiple files", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "fileField",
|
||||
options: {
|
||||
maxSelect: 3,
|
||||
},
|
||||
type: "file",
|
||||
})
|
||||
).toEqual("\tfileField: string[]")
|
||||
})
|
||||
|
||||
it("converts relation type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "relationField",
|
||||
type: "relation",
|
||||
})
|
||||
).toEqual("\trelationField: RecordIdString[]")
|
||||
})
|
||||
|
||||
it("converts relation type with multiple options", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "relationFieldMany",
|
||||
options: {
|
||||
maxSelect: 3,
|
||||
},
|
||||
type: "relation",
|
||||
})
|
||||
).toEqual("\trelationFieldMany: RecordIdString[]")
|
||||
})
|
||||
|
||||
it("converts relation type with unset maxSelect", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "relationFieldMany",
|
||||
options: {
|
||||
maxSelect: null,
|
||||
},
|
||||
type: "relation",
|
||||
})
|
||||
).toEqual("\trelationFieldMany: RecordIdString[]")
|
||||
})
|
||||
|
||||
// DEPRECATED: This was removed in PocketBase v0.8
|
||||
it("converts user relation type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "userRelationField",
|
||||
type: "user",
|
||||
})
|
||||
).toEqual("\tuserRelationField: RecordIdString")
|
||||
})
|
||||
|
||||
it("warns when encountering unexpected types", () => {
|
||||
const logSpy = jest.spyOn(console, "log")
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
// @ts-ignore
|
||||
type: "unknowntype",
|
||||
})
|
||||
expect(logSpy).toHaveBeenCalledWith(
|
||||
'WARNING: unknown type "unknowntype" found in schema'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("createSelectOptions", () => {
|
||||
it("creates enum types for select options", () => {
|
||||
const name = "choose"
|
||||
const schema: FieldSchema[] = [
|
||||
{
|
||||
id: "hhnwjkke",
|
||||
name: "title",
|
||||
options: { values: ["one", "one", "two", "space space", "$@#*(&#%"] },
|
||||
required: false,
|
||||
system: false,
|
||||
type: "select",
|
||||
unique: false,
|
||||
},
|
||||
]
|
||||
const result = createSelectOptions(name, schema)
|
||||
expect(result).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
266
test/lib.test.ts
266
test/lib.test.ts
@@ -4,21 +4,9 @@ import {
|
||||
createCollectionRecords,
|
||||
createRecordType,
|
||||
createResponseType,
|
||||
createSelectOptions,
|
||||
createTypeField,
|
||||
generate,
|
||||
} from "../src/lib"
|
||||
|
||||
const defaultFieldSchema: FieldSchema = {
|
||||
id: "abc",
|
||||
name: "defaultName",
|
||||
options: {},
|
||||
required: true,
|
||||
system: false,
|
||||
type: "text",
|
||||
unique: false,
|
||||
}
|
||||
|
||||
describe("generate", () => {
|
||||
it("generates correct output given db input", () => {
|
||||
const collections: Array<CollectionRecord> = [
|
||||
@@ -146,257 +134,3 @@ describe("createResponseType", () => {
|
||||
expect(result).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
|
||||
describe("createTypeField", () => {
|
||||
it("handles required and optional fields", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
required: false,
|
||||
})
|
||||
).toEqual("\tdefaultName?: string")
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
required: true,
|
||||
})
|
||||
).toEqual("\tdefaultName: string")
|
||||
})
|
||||
|
||||
it("converts default types to typescript", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
})
|
||||
).toEqual("\tdefaultName: string")
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "textField",
|
||||
})
|
||||
).toEqual("\ttextField: string")
|
||||
})
|
||||
|
||||
it("converts number type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "numberField",
|
||||
type: "number",
|
||||
})
|
||||
).toEqual("\tnumberField: number")
|
||||
})
|
||||
|
||||
it("converts bool type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "boolField",
|
||||
type: "bool",
|
||||
})
|
||||
).toEqual("\tboolField: boolean")
|
||||
})
|
||||
|
||||
it("converts email type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "emailField",
|
||||
type: "email",
|
||||
})
|
||||
).toEqual("\temailField: string")
|
||||
})
|
||||
|
||||
it("converts url type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "urlField",
|
||||
type: "url",
|
||||
})
|
||||
).toEqual("\turlField: string")
|
||||
})
|
||||
|
||||
it("converts date type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "dateField",
|
||||
type: "date",
|
||||
})
|
||||
).toEqual("\tdateField: IsoDateString")
|
||||
})
|
||||
|
||||
it("converts select type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "selectField",
|
||||
type: "select",
|
||||
})
|
||||
).toEqual("\tselectField: string")
|
||||
})
|
||||
|
||||
it("converts select type with value", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "selectFieldWithOpts",
|
||||
options: {
|
||||
values: ["one", "two", "three"],
|
||||
},
|
||||
type: "select",
|
||||
})
|
||||
).toEqual(`\tselectFieldWithOpts: TestCollectionSelectFieldWithOptsOptions`)
|
||||
})
|
||||
|
||||
it("converts multi-select type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "selectField",
|
||||
options: {
|
||||
maxSelect: 2,
|
||||
},
|
||||
type: "select",
|
||||
})
|
||||
).toEqual("\tselectField: string[]")
|
||||
})
|
||||
|
||||
it("converts multi-select type with values", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "selectFieldWithOpts",
|
||||
options: {
|
||||
maxSelect: 2,
|
||||
values: ["one", "two", "three"],
|
||||
},
|
||||
type: "select",
|
||||
})
|
||||
).toEqual(
|
||||
`\tselectFieldWithOpts: TestCollectionSelectFieldWithOptsOptions[]`
|
||||
)
|
||||
})
|
||||
|
||||
it("converts json type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "jsonField",
|
||||
type: "json",
|
||||
})
|
||||
).toEqual("\tjsonField: null | TjsonField")
|
||||
})
|
||||
|
||||
it("converts editor type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "editorField",
|
||||
type: "editor",
|
||||
})
|
||||
).toEqual("\teditorField: HTMLString")
|
||||
})
|
||||
|
||||
it("converts file type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "fileField",
|
||||
type: "file",
|
||||
})
|
||||
).toEqual("\tfileField: string")
|
||||
})
|
||||
|
||||
it("converts file type with multiple files", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "fileField",
|
||||
options: {
|
||||
maxSelect: 3,
|
||||
},
|
||||
type: "file",
|
||||
})
|
||||
).toEqual("\tfileField: string[]")
|
||||
})
|
||||
|
||||
it("converts relation type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "relationField",
|
||||
type: "relation",
|
||||
})
|
||||
).toEqual("\trelationField: RecordIdString[]")
|
||||
})
|
||||
|
||||
it("converts relation type with multiple options", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "relationFieldMany",
|
||||
options: {
|
||||
maxSelect: 3,
|
||||
},
|
||||
type: "relation",
|
||||
})
|
||||
).toEqual("\trelationFieldMany: RecordIdString[]")
|
||||
})
|
||||
|
||||
it("converts relation type with unset maxSelect", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "relationFieldMany",
|
||||
options: {
|
||||
maxSelect: null,
|
||||
},
|
||||
type: "relation",
|
||||
})
|
||||
).toEqual("\trelationFieldMany: RecordIdString[]")
|
||||
})
|
||||
|
||||
// DEPRECATED: This was removed in PocketBase v0.8
|
||||
it("converts user relation type", () => {
|
||||
expect(
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
name: "userRelationField",
|
||||
type: "user",
|
||||
})
|
||||
).toEqual("\tuserRelationField: RecordIdString")
|
||||
})
|
||||
|
||||
it("warns when encountering unexpected types", () => {
|
||||
const logSpy = jest.spyOn(console, "log")
|
||||
createTypeField("test_collection", {
|
||||
...defaultFieldSchema,
|
||||
// @ts-ignore
|
||||
type: "unknowntype",
|
||||
})
|
||||
expect(logSpy).toHaveBeenCalledWith(
|
||||
'WARNING: unknown type "unknowntype" found in schema'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("createSelectOptions", () => {
|
||||
it("creates enum types for select options", () => {
|
||||
const name = "choose"
|
||||
const schema: FieldSchema[] = [
|
||||
{
|
||||
id: "hhnwjkke",
|
||||
name: "title",
|
||||
options: { values: ["one", "one", "two", "space space", "$@#*(&#%"] },
|
||||
required: false,
|
||||
system: false,
|
||||
type: "select",
|
||||
unique: false,
|
||||
},
|
||||
]
|
||||
const result = createSelectOptions(name, schema)
|
||||
expect(result).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user