diff --git a/dist/index.js b/dist/index.js index 08d8dca..502f184 100755 --- a/dist/index.js +++ b/dist/index.js @@ -37,9 +37,6 @@ async function fromURL(url, email = "", password = "") { return result.items; } -// src/lib.ts -import { promises as fs2 } from "fs"; - // src/utils.ts function toPascalCase(str) { if (/^[\p{L}\d]+$/iu.test(str)) { @@ -50,8 +47,17 @@ function toPascalCase(str) { (g0, g1, g2) => g1.toUpperCase() + g2.toLowerCase() ).replace(/[^\p{L}\d]/giu, ""); } +function sanitizeFieldName(name) { + if (!isNaN(parseFloat(name.charAt(0)))) { + console.log({ found: name, return: `"${name}"` }); + return `"${name}"`; + } else { + return name; + } +} // src/lib.ts +import { promises as fs2 } from "fs"; var pbSchemaTypescriptMap = { text: "string", number: "number", @@ -61,8 +67,7 @@ var pbSchemaTypescriptMap = { date: "string", select: "string", json: "null | unknown", - file: "string", - files: "string[]", + file: (opts) => opts.maxSelect && opts.maxSelect > 1 ? "string[]" : "string", relation: "string", user: "string" }; @@ -107,20 +112,20 @@ function createCollectionRecord(collectionNames) { function createRecordType(name, schema) { let typeString = `export type ${toPascalCase(name)}Record = { `; - schema.forEach((field) => { - 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) => { + typeString += createTypeField(recordSchema); }); typeString += `}`; return typeString; } -function createTypeField(name, required, pbType) { - if (pbType in pbSchemaTypescriptMap) { - return ` ${name}${required ? "" : "?"}: ${pbSchemaTypescriptMap[pbType]} -`; - } else { - throw new Error(`unknown type ${pbType} found in schema`); +function createTypeField(recordSchema) { + if (!(recordSchema.type in pbSchemaTypescriptMap)) { + throw new Error(`unknown type ${recordSchema.type} found in schema`); } + const typeStringOrFunc = pbSchemaTypescriptMap[recordSchema.type]; + const typeString = typeof typeStringOrFunc === "function" ? typeStringOrFunc(recordSchema.options) : typeStringOrFunc; + return ` ${sanitizeFieldName(recordSchema.name)}${recordSchema.required ? "" : "?"}: ${typeString} +`; } async function saveFile(outPath, typeString) { await fs2.writeFile(outPath, typeString, "utf8"); diff --git a/src/lib.ts b/src/lib.ts index bb0186d..17e4791 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -1,7 +1,7 @@ import { CollectionRecord, RecordOptions, RecordSchema } from "./types" +import { sanitizeFieldName, toPascalCase } from "./utils" import { promises as fs } from "fs" -import { toPascalCase } from "./utils" const pbSchemaTypescriptMap = { text: "string", @@ -81,7 +81,7 @@ export function createTypeField(recordSchema: RecordSchema) { typeof typeStringOrFunc === "function" ? typeStringOrFunc(recordSchema.options) : typeStringOrFunc - return `\t${recordSchema.name}${ + return `\t${sanitizeFieldName(recordSchema.name)}${ recordSchema.required ? "" : "?" }: ${typeString}\n` } diff --git a/src/utils.ts b/src/utils.ts index 3884328..52389b8 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -10,3 +10,13 @@ export function toPascalCase(str: string) { ) .replace(/[^\p{L}\d]/giu, "") } + +export function sanitizeFieldName(name: string) { + // If the first character is a number, wrap it in quotes to pass typecheck + if (!isNaN(parseFloat(name.charAt(0)))) { + console.log({ found: name, return: `"${name}"` }) + return `"${name}"` + } else { + return name + } +} diff --git a/test/utils.test.ts b/test/utils.test.ts index 3142c47..f71781d 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -1,17 +1,24 @@ -import { toPascalCase } from "../src/utils" +import { sanitizeFieldName, toPascalCase } from "../src/utils" describe("toPascalCase", () => { - it("return pascal case string", () => { - expect(toPascalCase("foo bar")).toEqual("FooBar") - expect(toPascalCase("Foo Bar")).toEqual("FooBar") - expect(toPascalCase("fooBar")).toEqual("FooBar") - expect(toPascalCase("FooBar")).toEqual("FooBar") - expect(toPascalCase("--foo-bar--")).toEqual("FooBar") - expect(toPascalCase("__FOO_BAR__")).toEqual("FooBar") - expect(toPascalCase("!--foo-¿?-bar--121-**%")).toEqual("FooBar121") - expect(toPascalCase("Here i am")).toEqual("HereIAm") - expect(toPascalCase("FOO BAR")).toEqual("FooBar") - expect(toPascalCase("ça.roule")).toEqual("ÇaRoule") - expect(toPascalCase("добрий-день")).toEqual("ДобрийДень") - }) + it("return pascal case string", () => { + expect(toPascalCase("foo bar")).toEqual("FooBar") + expect(toPascalCase("Foo Bar")).toEqual("FooBar") + expect(toPascalCase("fooBar")).toEqual("FooBar") + expect(toPascalCase("FooBar")).toEqual("FooBar") + expect(toPascalCase("--foo-bar--")).toEqual("FooBar") + expect(toPascalCase("__FOO_BAR__")).toEqual("FooBar") + expect(toPascalCase("!--foo-¿?-bar--121-**%")).toEqual("FooBar121") + expect(toPascalCase("Here i am")).toEqual("HereIAm") + expect(toPascalCase("FOO BAR")).toEqual("FooBar") + expect(toPascalCase("ça.roule")).toEqual("ÇaRoule") + expect(toPascalCase("добрий-день")).toEqual("ДобрийДень") + }) +}) + +describe("sanitizeFieldName", () => { + it("returns valid typescript fields", () => { + expect(sanitizeFieldName("foo_bar")).toEqual("foo_bar") + expect(sanitizeFieldName("4number")).toEqual('"4number"') + }) })