diff --git a/generator.ts b/generator.ts index e22037d..503d362 100644 --- a/generator.ts +++ b/generator.ts @@ -4,15 +4,18 @@ import { dirname } from "node:path"; interface Config { enumType: "stringUnion" | "enum"; - enumSuffix: string; enumPrefix: string; - modelSuffix: string; + enumSuffix: string; modelPrefix: string; + modelSuffix: string; + typePrefix: string; + typeSuffix: string; dateType: "string" | "Date"; bigIntType: "string" | "bigint"; decimalType: "string" | "Decimal"; - bytesType: "Buffer" | "string"; - prettier: "true" | "false"; + bytesType: "string" | "Buffer" | "BufferObject" | "number[]"; + optionalRelations: boolean; + prettier: boolean; } // Map of Prisma scalar types to Typescript type getters @@ -31,9 +34,10 @@ const SCALAR_TYPE_GETTERS: Record string> = { // Since we want the output to have zero dependencies, define custom types which are compatible // with the actual Prisma types. If users need the real Prisma types, they can cast to them. const CUSTOM_TYPES: Record = { + BufferObject: 'type BufferObject = { type: "Buffer"; data: number[] };', + Decimal: "type Decimal = { valueOf(): string };", JsonValue: - "type JsonValue = string | number | boolean | { [key in string]: JsonValue } | Array | null;", - Decimal: "interface Decimal {\n valueOf(): string;\n}", + "type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null;", }; function validateConfig(config: Config) { @@ -50,12 +54,9 @@ function validateConfig(config: Config) { if (!["string", "Decimal"].includes(config.decimalType)) { errors.push(`Invalid decimalType: ${config.decimalType}`); } - if (!["Buffer", "string"].includes(config.bytesType)) { + if (!["string", "Buffer", "BufferObject", "number[]"].includes(config.bytesType)) { errors.push(`Invalid bytesType: ${config.bytesType}`); } - if (!["true", "false"].includes(config.prettier)) { - errors.push(`Invalid prettier: ${config.prettier}`); - } if (errors.length > 0) { throw new Error(errors.join("\n")); } @@ -87,12 +88,15 @@ function getModelTs( modelData: DMMF.Model, modelNameMap: Map, enumNameMap: Map, + typeNameMap: Map, usedCustomTypes: Set, ): string { const fields = modelData.fields .map(({ name, kind, type, isRequired, isList }) => { - const getDefinition = (resolvedType: string) => - ` ${name}: ${resolvedType}${isList ? "[]" : ""}${!isRequired ? " | null" : ""};`; + const getDefinition = (resolvedType: string, optional = false) => + ` ${name}${optional ? "?" : ""}: ${resolvedType}${isList ? "[]" : ""}${ + !isRequired ? " | null" : "" + };`; switch (kind) { case "scalar": { @@ -108,10 +112,14 @@ function getModelTs( } case "object": { const modelName = modelNameMap.get(type); - if (!modelName) { + const typeName = typeNameMap.get(type); + if (!modelName && !typeName) { throw new Error(`Unknown model name: ${type}`); } - return getDefinition(modelName); + return getDefinition( + (modelName ?? typeName) as string, + config.optionalRelations && !typeName, // Type relations are never optional + ); } case "enum": { const enumName = enumNameMap.get(type); @@ -128,7 +136,8 @@ function getModelTs( }) .join("\n"); - return `export interface ${modelNameMap.get(modelData.name)} {\n${fields}\n}`; + const name = modelNameMap.get(modelData.name) ?? typeNameMap.get(modelData.name); + return `export interface ${name} {\n${fields}\n}`; } generatorHandler({ @@ -139,27 +148,31 @@ generatorHandler({ }; }, async onGenerate(options) { + const baseConfig = options.generator.config; const config: Config = { - enumType: "enum", - enumSuffix: "", + enumType: "stringUnion", enumPrefix: "", - modelSuffix: "", + enumSuffix: "", modelPrefix: "", + modelSuffix: "", + typePrefix: "", + typeSuffix: "", dateType: "Date", bigIntType: "bigint", decimalType: "Decimal", bytesType: "Buffer", - prettier: "false", - ...options.generator.config, + ...baseConfig, + // Booleans go here since in the base config they are strings + optionalRelations: baseConfig.optionalRelations !== "false", // Default true + prettier: baseConfig.prettier === "true", // Default false }; validateConfig(config); const datamodel = options.dmmf.datamodel; + const models = datamodel.models; const enums = datamodel.enums; - - // For the purposes of this generator, models and types are equivalent - const models = [...datamodel.models, ...datamodel.types]; + const types = datamodel.types; const usedCustomTypes = new Set(); @@ -169,16 +182,20 @@ generatorHandler({ const modelNameMap = new Map( models.map((m) => [m.name, `${config.modelPrefix}${m.name}${config.modelSuffix}`]), ); + const typeNameMap = new Map( + types.map((t) => [t.name, `${config.typePrefix}${t.name}${config.typeSuffix}`]), + ); const enumsTs = enums.map((e) => getEnumTs(config, e, enumNameMap)); - const modelsTs = models.map((m) => - getModelTs(config, m, modelNameMap, enumNameMap, usedCustomTypes), + // Types and Models are essentially the same thing, so we can run both through getModelTs + const modelsTs = [...models, ...types].map((m) => + getModelTs(config, m, modelNameMap, enumNameMap, typeNameMap, usedCustomTypes), ); const customTypesTs = Array.from(usedCustomTypes).map((t) => CUSTOM_TYPES[t]); let ts = [...enumsTs, ...modelsTs, ...customTypesTs].join("\n\n") + "\n"; - if (config.prettier === "true") { + if (config.prettier) { // Prettier is imported inside this if so that it's not a required dependency let prettier: typeof import("prettier"); try { diff --git a/prisma/example.prisma b/prisma/example.prisma index eec3f64..88e8d26 100644 --- a/prisma/example.prisma +++ b/prisma/example.prisma @@ -3,7 +3,7 @@ datasource db { provider = "postgresql" - url = "" + url = "postgresql://postgres:password@localhost:5432/testing?schema=public" } generator client { @@ -16,6 +16,17 @@ generator typescriptInterfaces { prettier = true } +generator typescriptInterfacesJson { + provider = "node --loader ts-node/esm generator.ts" + output = "exampleJson.ts" + modelSuffix = "Json" + dateType = "string" + bigIntType = "string" + decimalType = "string" + bytesType = "BufferObject" + prettier = true +} + enum Gender { Male Female @@ -30,8 +41,8 @@ model Person { gender Gender addressId Int address Address @relation(fields: [addressId], references: [id]) - friends Person[] @relation("Friends") friendsOf Person[] @relation("Friends") + friends Person[] @relation("Friends") data Data? } diff --git a/test.ts b/test.ts index ba054cd..a6d1c47 100644 --- a/test.ts +++ b/test.ts @@ -5,7 +5,10 @@ * "expected-error.txt" file in the relevant test folder. * * You can run specific tests by passing the one(s) you want to run as arguments to this script: - * npm run test custom-output no-options prettier + * npm run test -- custom-output no-options prettier + * + * If you want to run all tests even if some fail, pass the --continue or -c flag: + * npm run test -- -c */ import { exec } from "node:child_process"; @@ -15,7 +18,7 @@ import fs from "node:fs/promises"; import path from "node:path"; const TEMP_TEST_DIRNAME = "__TEST_TMP__"; -const BASE_REPLACE_STRING = "// TEST_INSERT_BASE_HERE"; +const BASE_REPLACE_REGEX = /^\/\/ ?#INSERT base\.([a-z]+)\.prisma$/gm; const RED = "\x1b[1m\x1b[41m\x1b[97m"; const GREEN = "\x1b[1m\x1b[42m\x1b[97m"; const RESET = "\x1b[0m"; @@ -29,29 +32,50 @@ const trimMultiLine = (s: string) => .map((l) => l.trim()) .join("\n"); -const testFilters = process.argv.slice(2); +let testFilters = process.argv.slice(2); + +// Continue on errors if --continue or -c is passed +let continueOnError = false; +let hasErrors = false; +if (testFilters.some((f) => f === "--continue" || f === "-c")) { + continueOnError = true; + testFilters = testFilters.filter((f) => f !== "--continue" && f !== "-c"); +} -const tests = (await fs.readdir("tests", { withFileTypes: true })) - .filter( - (dirent) => dirent.isDirectory() && (!testFilters.length || testFilters.includes(dirent.name)), - ) - .map((t) => path.join(t.path, t.name)); +const testsEntries = await fs.readdir("tests", { withFileTypes: true }); +const tests = testsEntries + .filter((d) => d.isDirectory() && (!testFilters.length || testFilters.includes(d.name))) + .map((d) => path.join(d.path, d.name)); + +// Common schemas used by multiple tests +const baseSchemas = new Map( + await Promise.all( + testsEntries + .filter((f) => f.isFile() && /^base\.[a-z]+\.prisma$/.test(f.name)) + .map>((f) => + readFile(path.join(f.path, f.name)).then((c) => [f.name, c]), + ), + ), +); // Get the length of the longest test name, so we can pad the output const longestName = Math.max(...tests.map((t) => t.length)); -// Common schema text used by many of the tests -const baseSchema = await readFile(path.join("tests", "base.prisma")); - console.log("Running tests..."); -try { - for (const test of tests) { +for (const test of tests) { + try { process.stdout.write(` ${test}${" ".repeat(longestName - test.length + 2)}`); - const schema = (await readFile(path.join(test, "schema.prisma"))).replace( - BASE_REPLACE_STRING, - baseSchema, + const schema = (await readFile(path.join(test, "schema.prisma"))).replaceAll( + BASE_REPLACE_REGEX, + (_, baseName) => { + const baseSchema = baseSchemas.get(`base.${baseName}.prisma`); + if (!baseSchema) { + throw new Error(`Unknown base schema: ${baseName}`); + } + return baseSchema; + }, ); let expectedError: string | null; // Text of expected stderr after a non-zero exit code @@ -119,11 +143,19 @@ try { process.stdout.write(GREEN + " PASS " + RESET + "\n"); await rimraf(testDir); + } catch (e) { + process.stdout.write(RED + " FAIL " + RESET + "\n\n"); + console.error((e as Error).message, "\n"); + hasErrors = true; + if (!continueOnError) { + process.exit(1); + } } +} - console.log("\n\nAll tests passed!"); -} catch (e) { - process.stdout.write(RED + " FAIL " + RESET + "\n\n"); - console.error((e as Error).message); +if (hasErrors) { + console.error("\nSome tests failed!"); process.exit(1); +} else { + console.log("\nAll tests passed!"); } diff --git a/tests/base.mongo.prisma b/tests/base.mongo.prisma new file mode 100644 index 0000000..9d39f40 --- /dev/null +++ b/tests/base.mongo.prisma @@ -0,0 +1,45 @@ +// We need to use mongo to test composite types +datasource db { + provider = "mongodb" + url = "" +} + +enum Gender { + Male + Female + Other +} + +enum PhotoType { + Selfie + Profile + Tagged +} + +model Person { + id Int @id @map("_id") + name String + gender Gender + addressId Int + address Address @relation(fields: [addressId], references: [id]) + photos Photo[] + tags Tag? +} + +model Address { + id Int @id @map("_id") + addresText String + people Person[] +} + +type Photo { + height Int + Width Int + url String + type PhotoType +} + +type Tag { + id Int + name String +} diff --git a/tests/base.prisma b/tests/base.postgres.prisma similarity index 91% rename from tests/base.prisma rename to tests/base.postgres.prisma index fae81ef..c480d79 100644 --- a/tests/base.prisma +++ b/tests/base.postgres.prisma @@ -10,6 +10,13 @@ enum Gender { Other } +enum DataTest { + Apple + Banana + Orange + Pear +} + model Person { id Int @id @default(autoincrement()) name String @@ -43,6 +50,7 @@ model Data { dateField DateTime jsonField Json bytesField Bytes + enumField DataTest optionalStringField String? optionalBooleanField Boolean? @@ -53,6 +61,7 @@ model Data { optionalDateField DateTime? optionalJsonField Json? optionalBytesField Bytes? + optionalEnumField DataTest? stringArrayField String[] booleanArrayField Boolean[] @@ -63,6 +72,7 @@ model Data { dateArrayField DateTime[] jsonArrayField Json[] bytesArrayField Bytes[] + enumArrayField DataTest[] personId Int @unique person Person @relation(fields: [personId], references: [id]) diff --git a/tests/buffer-array-type/expected/interfaces.ts b/tests/buffer-array-type/expected/interfaces.ts new file mode 100644 index 0000000..977085a --- /dev/null +++ b/tests/buffer-array-type/expected/interfaces.ts @@ -0,0 +1,65 @@ +export type Gender = "Male" | "Female" | "Other"; + +export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; + +export interface Person { + id: number; + name: string; + age: number; + email: string | null; + gender: Gender; + addressId: number; + address?: Address; + friends?: Person[]; + friendsOf?: Person[]; + data?: Data | null; +} + +export interface Address { + id: number; + streetNumber: number; + streetName: string; + city: string; + isBilling: boolean; + people?: Person[]; +} + +export interface Data { + id: string; + stringField: string; + booleanField: boolean; + intField: number; + bigIntField: bigint; + floatField: number; + decimalField: Decimal; + dateField: Date; + jsonField: JsonValue; + bytesField: number[]; + enumField: DataTest; + optionalStringField: string | null; + optionalBooleanField: boolean | null; + optionalIntField: number | null; + optionalBigIntField: bigint | null; + optionalFloatField: number | null; + optionalDecimalField: Decimal | null; + optionalDateField: Date | null; + optionalJsonField: JsonValue | null; + optionalBytesField: number[] | null; + optionalEnumField: DataTest | null; + stringArrayField: string[]; + booleanArrayField: boolean[]; + intArrayField: number[]; + bigIntArrayField: bigint[]; + floatArrayField: number[]; + decimalArrayField: Decimal[]; + dateArrayField: Date[]; + jsonArrayField: JsonValue[]; + bytesArrayField: number[][]; + enumArrayField: DataTest[]; + personId: number; + person?: Person; +} + +type Decimal = { valueOf(): string }; + +type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; diff --git a/tests/buffer-array-type/schema.prisma b/tests/buffer-array-type/schema.prisma new file mode 100644 index 0000000..80b7cc2 --- /dev/null +++ b/tests/buffer-array-type/schema.prisma @@ -0,0 +1,6 @@ +generator typescriptInterfaces { + provider = "node generator.js" + bytesType = "number[]" +} + +// #INSERT base.postgres.prisma diff --git a/tests/buffer-object-type/expected/interfaces.ts b/tests/buffer-object-type/expected/interfaces.ts new file mode 100644 index 0000000..53c1ff4 --- /dev/null +++ b/tests/buffer-object-type/expected/interfaces.ts @@ -0,0 +1,67 @@ +export type Gender = "Male" | "Female" | "Other"; + +export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; + +export interface Person { + id: number; + name: string; + age: number; + email: string | null; + gender: Gender; + addressId: number; + address?: Address; + friends?: Person[]; + friendsOf?: Person[]; + data?: Data | null; +} + +export interface Address { + id: number; + streetNumber: number; + streetName: string; + city: string; + isBilling: boolean; + people?: Person[]; +} + +export interface Data { + id: string; + stringField: string; + booleanField: boolean; + intField: number; + bigIntField: bigint; + floatField: number; + decimalField: Decimal; + dateField: Date; + jsonField: JsonValue; + bytesField: BufferObject; + enumField: DataTest; + optionalStringField: string | null; + optionalBooleanField: boolean | null; + optionalIntField: number | null; + optionalBigIntField: bigint | null; + optionalFloatField: number | null; + optionalDecimalField: Decimal | null; + optionalDateField: Date | null; + optionalJsonField: JsonValue | null; + optionalBytesField: BufferObject | null; + optionalEnumField: DataTest | null; + stringArrayField: string[]; + booleanArrayField: boolean[]; + intArrayField: number[]; + bigIntArrayField: bigint[]; + floatArrayField: number[]; + decimalArrayField: Decimal[]; + dateArrayField: Date[]; + jsonArrayField: JsonValue[]; + bytesArrayField: BufferObject[]; + enumArrayField: DataTest[]; + personId: number; + person?: Person; +} + +type Decimal = { valueOf(): string }; + +type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; + +type BufferObject = { type: "Buffer"; data: number[] }; diff --git a/tests/buffer-object-type/schema.prisma b/tests/buffer-object-type/schema.prisma new file mode 100644 index 0000000..cec0bc0 --- /dev/null +++ b/tests/buffer-object-type/schema.prisma @@ -0,0 +1,6 @@ +generator typescriptInterfaces { + provider = "node generator.js" + bytesType = "BufferObject" +} + +// #INSERT base.postgres.prisma diff --git a/tests/custom-output/expected/generated.ts b/tests/custom-output/expected/generated.ts index 2003333..4ce581e 100644 --- a/tests/custom-output/expected/generated.ts +++ b/tests/custom-output/expected/generated.ts @@ -1,8 +1,6 @@ -export enum Gender { - Male = "Male", - Female = "Female", - Other = "Other" -} +export type Gender = "Male" | "Female" | "Other"; + +export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; export interface Person { id: number; @@ -11,10 +9,10 @@ export interface Person { email: string | null; gender: Gender; addressId: number; - address: Address; - friends: Person[]; - friendsOf: Person[]; - data: Data | null; + address?: Address; + friends?: Person[]; + friendsOf?: Person[]; + data?: Data | null; } export interface Address { @@ -23,7 +21,7 @@ export interface Address { streetName: string; city: string; isBilling: boolean; - people: Person[]; + people?: Person[]; } export interface Data { @@ -37,6 +35,7 @@ export interface Data { dateField: Date; jsonField: JsonValue; bytesField: Buffer; + enumField: DataTest; optionalStringField: string | null; optionalBooleanField: boolean | null; optionalIntField: number | null; @@ -46,6 +45,7 @@ export interface Data { optionalDateField: Date | null; optionalJsonField: JsonValue | null; optionalBytesField: Buffer | null; + optionalEnumField: DataTest | null; stringArrayField: string[]; booleanArrayField: boolean[]; intArrayField: number[]; @@ -55,12 +55,11 @@ export interface Data { dateArrayField: Date[]; jsonArrayField: JsonValue[]; bytesArrayField: Buffer[]; + enumArrayField: DataTest[]; personId: number; - person: Person; + person?: Person; } -interface Decimal { - valueOf(): string; -} +type Decimal = { valueOf(): string }; -type JsonValue = string | number | boolean | { [key in string]: JsonValue } | Array | null; +type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; diff --git a/tests/custom-output/schema.prisma b/tests/custom-output/schema.prisma index 73abbb0..7b63736 100644 --- a/tests/custom-output/schema.prisma +++ b/tests/custom-output/schema.prisma @@ -3,4 +3,4 @@ generator typescriptInterfaces { output = "generated.ts" } -// TEST_INSERT_BASE_HERE +// #INSERT base.postgres.prisma diff --git a/tests/enums-prefix-suffix/expected/interfaces.ts b/tests/enums-prefix-suffix/expected/interfaces.ts new file mode 100644 index 0000000..7b031b1 --- /dev/null +++ b/tests/enums-prefix-suffix/expected/interfaces.ts @@ -0,0 +1,74 @@ +export enum EnumGenderUnion { + Male = "Male", + Female = "Female", + Other = "Other" +} + +export enum EnumDataTestUnion { + Apple = "Apple", + Banana = "Banana", + Orange = "Orange", + Pear = "Pear" +} + +export interface Person { + id: number; + name: string; + age: number; + email: string | null; + gender: EnumGenderUnion; + addressId: number; + address?: Address; + friends?: Person[]; + friendsOf?: Person[]; + data?: Data | null; +} + +export interface Address { + id: number; + streetNumber: number; + streetName: string; + city: string; + isBilling: boolean; + people?: Person[]; +} + +export interface Data { + id: string; + stringField: string; + booleanField: boolean; + intField: number; + bigIntField: bigint; + floatField: number; + decimalField: Decimal; + dateField: Date; + jsonField: JsonValue; + bytesField: Buffer; + enumField: EnumDataTestUnion; + optionalStringField: string | null; + optionalBooleanField: boolean | null; + optionalIntField: number | null; + optionalBigIntField: bigint | null; + optionalFloatField: number | null; + optionalDecimalField: Decimal | null; + optionalDateField: Date | null; + optionalJsonField: JsonValue | null; + optionalBytesField: Buffer | null; + optionalEnumField: EnumDataTestUnion | null; + stringArrayField: string[]; + booleanArrayField: boolean[]; + intArrayField: number[]; + bigIntArrayField: bigint[]; + floatArrayField: number[]; + decimalArrayField: Decimal[]; + dateArrayField: Date[]; + jsonArrayField: JsonValue[]; + bytesArrayField: Buffer[]; + enumArrayField: EnumDataTestUnion[]; + personId: number; + person?: Person; +} + +type Decimal = { valueOf(): string }; + +type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; diff --git a/tests/union-enums-prefix-suffix/schema.prisma b/tests/enums-prefix-suffix/schema.prisma similarity index 68% rename from tests/union-enums-prefix-suffix/schema.prisma rename to tests/enums-prefix-suffix/schema.prisma index 9cbf14e..d1b5eb5 100644 --- a/tests/union-enums-prefix-suffix/schema.prisma +++ b/tests/enums-prefix-suffix/schema.prisma @@ -1,8 +1,8 @@ generator typescriptInterfaces { provider = "node generator.js" - enumType = "stringUnion" + enumType = "enum" enumPrefix = "Enum" enumSuffix = "Union" } -// TEST_INSERT_BASE_HERE +// #INSERT base.postgres.prisma diff --git a/tests/union-enums-prefix-suffix/expected/interfaces.ts b/tests/enums/expected/interfaces.ts similarity index 66% rename from tests/union-enums-prefix-suffix/expected/interfaces.ts rename to tests/enums/expected/interfaces.ts index e86c098..1f86d2d 100644 --- a/tests/union-enums-prefix-suffix/expected/interfaces.ts +++ b/tests/enums/expected/interfaces.ts @@ -1,16 +1,27 @@ -export type EnumGenderUnion = "Male" | "Female" | "Other"; +export enum Gender { + Male = "Male", + Female = "Female", + Other = "Other" +} + +export enum DataTest { + Apple = "Apple", + Banana = "Banana", + Orange = "Orange", + Pear = "Pear" +} export interface Person { id: number; name: string; age: number; email: string | null; - gender: EnumGenderUnion; + gender: Gender; addressId: number; - address: Address; - friends: Person[]; - friendsOf: Person[]; - data: Data | null; + address?: Address; + friends?: Person[]; + friendsOf?: Person[]; + data?: Data | null; } export interface Address { @@ -19,7 +30,7 @@ export interface Address { streetName: string; city: string; isBilling: boolean; - people: Person[]; + people?: Person[]; } export interface Data { @@ -33,6 +44,7 @@ export interface Data { dateField: Date; jsonField: JsonValue; bytesField: Buffer; + enumField: DataTest; optionalStringField: string | null; optionalBooleanField: boolean | null; optionalIntField: number | null; @@ -42,6 +54,7 @@ export interface Data { optionalDateField: Date | null; optionalJsonField: JsonValue | null; optionalBytesField: Buffer | null; + optionalEnumField: DataTest | null; stringArrayField: string[]; booleanArrayField: boolean[]; intArrayField: number[]; @@ -51,12 +64,11 @@ export interface Data { dateArrayField: Date[]; jsonArrayField: JsonValue[]; bytesArrayField: Buffer[]; + enumArrayField: DataTest[]; personId: number; - person: Person; + person?: Person; } -interface Decimal { - valueOf(): string; -} +type Decimal = { valueOf(): string }; -type JsonValue = string | number | boolean | { [key in string]: JsonValue } | Array | null; +type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; diff --git a/tests/union-enums/schema.prisma b/tests/enums/schema.prisma similarity index 57% rename from tests/union-enums/schema.prisma rename to tests/enums/schema.prisma index cd42fdd..395a805 100644 --- a/tests/union-enums/schema.prisma +++ b/tests/enums/schema.prisma @@ -1,6 +1,6 @@ generator typescriptInterfaces { provider = "node generator.js" - enumType = "stringUnion" + enumType = "enum" } -// TEST_INSERT_BASE_HERE +// #INSERT base.postgres.prisma diff --git a/tests/mongo-types/expected/interfaces.ts b/tests/mongo-types/expected/interfaces.ts index a1d6b57..ed19d41 100644 --- a/tests/mongo-types/expected/interfaces.ts +++ b/tests/mongo-types/expected/interfaces.ts @@ -1,21 +1,13 @@ -export enum Gender { - Male = "Male", - Female = "Female", - Other = "Other" -} +export type Gender = "Male" | "Female" | "Other"; -export enum PhotoType { - Selfie = "Selfie", - Profile = "Profile", - Tagged = "Tagged" -} +export type PhotoType = "Selfie" | "Profile" | "Tagged"; export interface Person { id: number; name: string; gender: Gender; addressId: number; - address: Address; + address?: Address; photos: Photo[]; tags: Tag | null; } @@ -23,7 +15,7 @@ export interface Person { export interface Address { id: number; addresText: string; - people: Person[]; + people?: Person[]; } export interface Photo { diff --git a/tests/mongo-types/schema.prisma b/tests/mongo-types/schema.prisma index d44c79a..53df48a 100644 --- a/tests/mongo-types/schema.prisma +++ b/tests/mongo-types/schema.prisma @@ -1,48 +1,5 @@ -datasource db { - provider = "mongodb" - url = "" -} - generator typescriptInterfaces { provider = "node generator.js" } -enum Gender { - Male - Female - Other -} - -enum PhotoType { - Selfie - Profile - Tagged -} - -model Person { - id Int @id @map("_id") - name String - gender Gender - addressId Int - address Address @relation(fields: [addressId], references: [id]) - photos Photo[] - tags Tag? -} - -model Address { - id Int @id @map("_id") - addresText String - people Person[] -} - -type Photo { - height Int - Width Int - url String - type PhotoType -} - -type Tag { - id Int - name String -} +// #INSERT base.mongo.prisma diff --git a/tests/no-custom-types/schema.prisma b/tests/no-custom-types/schema.prisma index c367a18..e5c1014 100644 --- a/tests/no-custom-types/schema.prisma +++ b/tests/no-custom-types/schema.prisma @@ -7,7 +7,7 @@ datasource db { url = "" } -// Basic model which does not use Json or Decimal +// Basic model which does not use custom types such as Json or Decimal model User { id String @id @default(cuid()) name String diff --git a/tests/no-options/expected/interfaces.ts b/tests/no-options/expected/interfaces.ts index 2003333..4ce581e 100644 --- a/tests/no-options/expected/interfaces.ts +++ b/tests/no-options/expected/interfaces.ts @@ -1,8 +1,6 @@ -export enum Gender { - Male = "Male", - Female = "Female", - Other = "Other" -} +export type Gender = "Male" | "Female" | "Other"; + +export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; export interface Person { id: number; @@ -11,10 +9,10 @@ export interface Person { email: string | null; gender: Gender; addressId: number; - address: Address; - friends: Person[]; - friendsOf: Person[]; - data: Data | null; + address?: Address; + friends?: Person[]; + friendsOf?: Person[]; + data?: Data | null; } export interface Address { @@ -23,7 +21,7 @@ export interface Address { streetName: string; city: string; isBilling: boolean; - people: Person[]; + people?: Person[]; } export interface Data { @@ -37,6 +35,7 @@ export interface Data { dateField: Date; jsonField: JsonValue; bytesField: Buffer; + enumField: DataTest; optionalStringField: string | null; optionalBooleanField: boolean | null; optionalIntField: number | null; @@ -46,6 +45,7 @@ export interface Data { optionalDateField: Date | null; optionalJsonField: JsonValue | null; optionalBytesField: Buffer | null; + optionalEnumField: DataTest | null; stringArrayField: string[]; booleanArrayField: boolean[]; intArrayField: number[]; @@ -55,12 +55,11 @@ export interface Data { dateArrayField: Date[]; jsonArrayField: JsonValue[]; bytesArrayField: Buffer[]; + enumArrayField: DataTest[]; personId: number; - person: Person; + person?: Person; } -interface Decimal { - valueOf(): string; -} +type Decimal = { valueOf(): string }; -type JsonValue = string | number | boolean | { [key in string]: JsonValue } | Array | null; +type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; diff --git a/tests/no-options/schema.prisma b/tests/no-options/schema.prisma index 63cd7b8..fc8316b 100644 --- a/tests/no-options/schema.prisma +++ b/tests/no-options/schema.prisma @@ -2,4 +2,4 @@ generator typescriptInterfaces { provider = "node generator.js" } -// TEST_INSERT_BASE_HERE +// #INSERT base.postgres.prisma diff --git a/tests/prefix-suffix/expected/interfaces.ts b/tests/prefix-suffix/expected/interfaces.ts index 065536d..24cc369 100644 --- a/tests/prefix-suffix/expected/interfaces.ts +++ b/tests/prefix-suffix/expected/interfaces.ts @@ -1,66 +1,31 @@ -export enum enumGenderEnum { - Male = "Male", - Female = "Female", - Other = "Other" -} +export type enumGenderEnum = "Male" | "Female" | "Other"; + +export type enumPhotoTypeEnum = "Selfie" | "Profile" | "Tagged"; export interface modelPersonModel { id: number; name: string; - age: number; - email: string | null; gender: enumGenderEnum; addressId: number; - address: modelAddressModel; - friends: modelPersonModel[]; - friendsOf: modelPersonModel[]; - data: modelDataModel | null; + address?: modelAddressModel; + photos: typePhotoType[]; + tags: typeTagType | null; } export interface modelAddressModel { id: number; - streetNumber: number; - streetName: string; - city: string; - isBilling: boolean; - people: modelPersonModel[]; + addresText: string; + people?: modelPersonModel[]; } -export interface modelDataModel { - id: string; - stringField: string; - booleanField: boolean; - intField: number; - bigIntField: bigint; - floatField: number; - decimalField: Decimal; - dateField: Date; - jsonField: JsonValue; - bytesField: Buffer; - optionalStringField: string | null; - optionalBooleanField: boolean | null; - optionalIntField: number | null; - optionalBigIntField: bigint | null; - optionalFloatField: number | null; - optionalDecimalField: Decimal | null; - optionalDateField: Date | null; - optionalJsonField: JsonValue | null; - optionalBytesField: Buffer | null; - stringArrayField: string[]; - booleanArrayField: boolean[]; - intArrayField: number[]; - bigIntArrayField: bigint[]; - floatArrayField: number[]; - decimalArrayField: Decimal[]; - dateArrayField: Date[]; - jsonArrayField: JsonValue[]; - bytesArrayField: Buffer[]; - personId: number; - person: modelPersonModel; +export interface typePhotoType { + height: number; + Width: number; + url: string; + type: enumPhotoTypeEnum; } -interface Decimal { - valueOf(): string; +export interface typeTagType { + id: number; + name: string; } - -type JsonValue = string | number | boolean | { [key in string]: JsonValue } | Array | null; diff --git a/tests/prefix-suffix/schema.prisma b/tests/prefix-suffix/schema.prisma index 1c1fd14..b251a3e 100644 --- a/tests/prefix-suffix/schema.prisma +++ b/tests/prefix-suffix/schema.prisma @@ -4,6 +4,8 @@ generator typescriptInterfaces { enumSuffix = "Enum" modelPrefix = "model" modelSuffix = "Model" + typePrefix = "type" + typeSuffix = "Type" } -// TEST_INSERT_BASE_HERE +// #INSERT base.mongo.prisma diff --git a/tests/prettier/expected/interfaces.ts b/tests/prettier/expected/interfaces.ts index 7b9bcbc..eee3254 100644 --- a/tests/prettier/expected/interfaces.ts +++ b/tests/prettier/expected/interfaces.ts @@ -1,8 +1,6 @@ -export enum Gender { - Male = "Male", - Female = "Female", - Other = "Other", -} +export type Gender = "Male" | "Female" | "Other"; + +export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; export interface Person { id: number; @@ -11,10 +9,10 @@ export interface Person { email: string | null; gender: Gender; addressId: number; - address: Address; - friends: Person[]; - friendsOf: Person[]; - data: Data | null; + address?: Address; + friends?: Person[]; + friendsOf?: Person[]; + data?: Data | null; } export interface Address { @@ -23,7 +21,7 @@ export interface Address { streetName: string; city: string; isBilling: boolean; - people: Person[]; + people?: Person[]; } export interface Data { @@ -37,6 +35,7 @@ export interface Data { dateField: Date; jsonField: JsonValue; bytesField: Buffer; + enumField: DataTest; optionalStringField: string | null; optionalBooleanField: boolean | null; optionalIntField: number | null; @@ -46,6 +45,7 @@ export interface Data { optionalDateField: Date | null; optionalJsonField: JsonValue | null; optionalBytesField: Buffer | null; + optionalEnumField: DataTest | null; stringArrayField: string[]; booleanArrayField: boolean[]; intArrayField: number[]; @@ -55,18 +55,17 @@ export interface Data { dateArrayField: Date[]; jsonArrayField: JsonValue[]; bytesArrayField: Buffer[]; + enumArrayField: DataTest[]; personId: number; - person: Person; + person?: Person; } -interface Decimal { - valueOf(): string; -} +type Decimal = { valueOf(): string }; type JsonValue = | string | number | boolean - | { [key in string]: JsonValue } + | { [key in string]?: JsonValue } | Array | null; diff --git a/tests/prettier/schema.prisma b/tests/prettier/schema.prisma index a9428ba..f990b4d 100644 --- a/tests/prettier/schema.prisma +++ b/tests/prettier/schema.prisma @@ -3,4 +3,4 @@ generator typescriptInterfaces { prettier = true } -// TEST_INSERT_BASE_HERE +// #INSERT base.postgres.prisma diff --git a/tests/union-enums/expected/interfaces.ts b/tests/required-relations/expected/interfaces.ts similarity index 81% rename from tests/union-enums/expected/interfaces.ts rename to tests/required-relations/expected/interfaces.ts index beeb8de..8b800af 100644 --- a/tests/union-enums/expected/interfaces.ts +++ b/tests/required-relations/expected/interfaces.ts @@ -1,5 +1,7 @@ export type Gender = "Male" | "Female" | "Other"; +export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; + export interface Person { id: number; name: string; @@ -33,6 +35,7 @@ export interface Data { dateField: Date; jsonField: JsonValue; bytesField: Buffer; + enumField: DataTest; optionalStringField: string | null; optionalBooleanField: boolean | null; optionalIntField: number | null; @@ -42,6 +45,7 @@ export interface Data { optionalDateField: Date | null; optionalJsonField: JsonValue | null; optionalBytesField: Buffer | null; + optionalEnumField: DataTest | null; stringArrayField: string[]; booleanArrayField: boolean[]; intArrayField: number[]; @@ -51,12 +55,11 @@ export interface Data { dateArrayField: Date[]; jsonArrayField: JsonValue[]; bytesArrayField: Buffer[]; + enumArrayField: DataTest[]; personId: number; person: Person; } -interface Decimal { - valueOf(): string; -} +type Decimal = { valueOf(): string }; -type JsonValue = string | number | boolean | { [key in string]: JsonValue } | Array | null; +type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; diff --git a/tests/required-relations/schema.prisma b/tests/required-relations/schema.prisma new file mode 100644 index 0000000..e06ebd4 --- /dev/null +++ b/tests/required-relations/schema.prisma @@ -0,0 +1,6 @@ +generator typescriptInterfaces { + provider = "node generator.js" + optionalRelations = false +} + +// #INSERT base.postgres.prisma diff --git a/tests/changed-types/expected/interfaces.ts b/tests/string-types/expected/interfaces.ts similarity index 72% rename from tests/changed-types/expected/interfaces.ts rename to tests/string-types/expected/interfaces.ts index edcb05b..55b42b8 100644 --- a/tests/changed-types/expected/interfaces.ts +++ b/tests/string-types/expected/interfaces.ts @@ -1,8 +1,6 @@ -export enum Gender { - Male = "Male", - Female = "Female", - Other = "Other" -} +export type Gender = "Male" | "Female" | "Other"; + +export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; export interface Person { id: number; @@ -11,10 +9,10 @@ export interface Person { email: string | null; gender: Gender; addressId: number; - address: Address; - friends: Person[]; - friendsOf: Person[]; - data: Data | null; + address?: Address; + friends?: Person[]; + friendsOf?: Person[]; + data?: Data | null; } export interface Address { @@ -23,7 +21,7 @@ export interface Address { streetName: string; city: string; isBilling: boolean; - people: Person[]; + people?: Person[]; } export interface Data { @@ -37,6 +35,7 @@ export interface Data { dateField: string; jsonField: JsonValue; bytesField: string; + enumField: DataTest; optionalStringField: string | null; optionalBooleanField: boolean | null; optionalIntField: number | null; @@ -46,6 +45,7 @@ export interface Data { optionalDateField: string | null; optionalJsonField: JsonValue | null; optionalBytesField: string | null; + optionalEnumField: DataTest | null; stringArrayField: string[]; booleanArrayField: boolean[]; intArrayField: number[]; @@ -55,8 +55,9 @@ export interface Data { dateArrayField: string[]; jsonArrayField: JsonValue[]; bytesArrayField: string[]; + enumArrayField: DataTest[]; personId: number; - person: Person; + person?: Person; } -type JsonValue = string | number | boolean | { [key in string]: JsonValue } | Array | null; +type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; diff --git a/tests/changed-types/schema.prisma b/tests/string-types/schema.prisma similarity index 84% rename from tests/changed-types/schema.prisma rename to tests/string-types/schema.prisma index dd4fb51..73dd734 100644 --- a/tests/changed-types/schema.prisma +++ b/tests/string-types/schema.prisma @@ -6,4 +6,4 @@ generator typescriptInterfaces { bytesType = "string" } -// TEST_INSERT_BASE_HERE +// #INSERT base.postgres.prisma diff --git a/tests/validation-errors/expected-error.txt b/tests/validation-errors/expected-error.txt index f1039d9..cd1ceeb 100644 --- a/tests/validation-errors/expected-error.txt +++ b/tests/validation-errors/expected-error.txt @@ -4,4 +4,3 @@ Invalid dateType: wrong Invalid bigIntType: values Invalid decimalType: go Invalid bytesType: here -Invalid prettier: bad diff --git a/tests/validation-errors/schema.prisma b/tests/validation-errors/schema.prisma index 82edd22..d3cd542 100644 --- a/tests/validation-errors/schema.prisma +++ b/tests/validation-errors/schema.prisma @@ -8,4 +8,4 @@ generator typescriptInterfaces { prettier = "bad" } -// TEST_INSERT_BASE_HERE +// #INSERT base.postgres.prisma