diff --git a/README.md b/README.md index 375c4fd..a939ad9 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ Note that `bigint` types don't have a default `toJSON` method, so the above assu | typePrefix | `string` | `""` | Prefix to add to [type](https://www.prisma.io/docs/concepts/components/prisma-schema/data-model#defining-composite-types) types (mongodb only). | | typeSuffix | `string` | `""` | Suffix to add to [type](https://www.prisma.io/docs/concepts/components/prisma-schema/data-model#defining-composite-types) types (mongodb only). | | headerComment | `string` | `"This file was auto-generated by prisma-generator-typescript-interfaces"` | Sets the header comment added to the top of the generated file. Set this to an empty string to disable the header comment. Supports multiple lines with `"\n"`. | +| definitionType | `"interface" \| "type"` | `"interface"` | Controls how the model definitions are generated. `"interface"` will create Typescript interfaces, `"type"` will create Typescript types. | | enumType | `"stringUnion" \| "enum"` | `"stringUnion"` | Controls how enums are generated. `"enum"` will create Typescript enums, `"stringUnion"` will create union types with all the enum values. | | dateType | `"Date" \| "string" \| "number"` | `"Date"` | The type to use for DateTime model fields. | | bigIntType | `"bigint" \| "string" \| "number"` | `"bigint"` | The type to use for BigInt model fields. | diff --git a/generator.ts b/generator.ts index ff82ff7..12b9b1c 100644 --- a/generator.ts +++ b/generator.ts @@ -15,6 +15,7 @@ interface Config { typePrefix: string; typeSuffix: string; headerComment: string; + definitionType: "interface" | "type"; enumType: "stringUnion" | "enum"; dateType: "Date" | "string" | "number"; bigIntType: "bigint" | "string" | "number"; @@ -48,6 +49,9 @@ const CUSTOM_TYPES: Record = { function validateConfig(config: Config) { const errors: string[] = []; + if (!["interface", "type"].includes(config.definitionType)) { + errors.push(`Invalid definitionType: ${config.definitionType}`); + } if (!["stringUnion", "enum"].includes(config.enumType)) { errors.push(`Invalid enumType: ${config.enumType}`); } @@ -143,7 +147,15 @@ function getModelTs( .join("\n"); const name = modelNameMap.get(modelData.name) ?? typeNameMap.get(modelData.name); - return `export interface ${name} {\n${fields}\n}`; + + switch (config.definitionType) { + case "interface": + return `export interface ${name} {\n${fields}\n}`; + case "type": + return `export type ${name} = {\n${fields}\n};`; + default: + throw new Error(`Unknown definitionType: ${config.definitionType}`); + } } generatorHandler({ @@ -163,6 +175,7 @@ generatorHandler({ typePrefix: "", typeSuffix: "", headerComment: "This file was auto-generated by prisma-generator-typescript-interfaces", + definitionType: "interface", enumType: "stringUnion", dateType: "Date", bigIntType: "bigint", diff --git a/package-lock.json b/package-lock.json index cedf3f8..a423def 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,18 @@ { "name": "prisma-generator-typescript-interfaces", - "version": "1.1.1", + "version": "1.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "prisma-generator-typescript-interfaces", - "version": "1.1.1", + "version": "1.3.0", "license": "MIT", "dependencies": { "@prisma/generator-helper": "^5.7.0" }, "bin": { - "prisma-generator-typescript-interfaces": "bin.js" + "prisma-generator-typescript-interfaces": "generator.js" }, "devDependencies": { "@prisma/client": "^5.7.0", diff --git a/package.json b/package.json index e474cc0..fc63623 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prisma-generator-typescript-interfaces", - "version": "1.2.0", + "version": "1.3.0", "description": "Generate zero-dependency Typescript interfaces from Prisma schema", "author": "Morgan Zolob", "license": "MIT", diff --git a/tests/options-behavior/expected/typeDefinitions.ts b/tests/options-behavior/expected/typeDefinitions.ts new file mode 100644 index 0000000..9c6c735 --- /dev/null +++ b/tests/options-behavior/expected/typeDefinitions.ts @@ -0,0 +1,67 @@ +// This file was auto-generated by prisma-generator-typescript-interfaces + +export type Gender = "Male" | "Female" | "Other"; + +export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; + +export type Person = { + id: number; + name: string; + age: number; + email: string | null; + gender: Gender; + addressId: number; + address?: Address; + friends?: Person[]; + friendsOf?: Person[]; + data?: Data | null; +}; + +export type Address = { + id: number; + streetNumber: number; + streetName: string; + city: string; + isBilling: boolean; + people?: Person[]; +}; + +export type Data = { + id: string; + stringField: string; + booleanField: boolean; + intField: number; + bigIntField: bigint; + floatField: number; + decimalField: Decimal; + dateField: Date; + jsonField: JsonValue; + bytesField: Buffer; + 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: Buffer | null; + optionalEnumField: DataTest | null; + stringArrayField: string[]; + booleanArrayField: boolean[]; + intArrayField: number[]; + bigIntArrayField: bigint[]; + floatArrayField: number[]; + decimalArrayField: Decimal[]; + dateArrayField: Date[]; + jsonArrayField: JsonValue[]; + bytesArrayField: Buffer[]; + 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/options-behavior/schema.prisma b/tests/options-behavior/schema.prisma index d19fbc1..8a6e276 100644 --- a/tests/options-behavior/schema.prisma +++ b/tests/options-behavior/schema.prisma @@ -90,6 +90,12 @@ generator enumTypeSuffixPrefix { enumSuffix = "Enum" } +generator typeDefinitions { + provider = "node --loader ts-node/esm generator.ts" + output = "typeDefinitions.ts" + definitionType = "type" +} + // ======================== // Prisma Schema // ======================== diff --git a/tests/validation-errors/expected-error.txt b/tests/validation-errors/expected-error.txt index cd1ceeb..6ee547f 100644 --- a/tests/validation-errors/expected-error.txt +++ b/tests/validation-errors/expected-error.txt @@ -1,4 +1,5 @@ Error: +Invalid definitionType: bad Invalid enumType: incorrect Invalid dateType: wrong Invalid bigIntType: values diff --git a/tests/validation-errors/schema.prisma b/tests/validation-errors/schema.prisma index 611433c..92be8f8 100644 --- a/tests/validation-errors/schema.prisma +++ b/tests/validation-errors/schema.prisma @@ -3,13 +3,13 @@ // ======================== generator typescriptInterfaces { - provider = "node --loader ts-node/esm generator.ts" - enumType = "incorrect" - dateType = "wrong" - bigIntType = "values" - decimalType = "go" - bytesType = "here" - prettier = "bad" + provider = "node --loader ts-node/esm generator.ts" + definitionType = "bad" + enumType = "incorrect" + dateType = "wrong" + bigIntType = "values" + decimalType = "go" + bytesType = "here" } // ========================