diff --git a/README.md b/README.md index 375c4fd..4852d97 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"`. | +| modelType | `"interface" \| "type"` | `"interface"` | Controls how model definitions are generated. `"interface"` will create Typescript interfaces, `"type"` will create Typescript types. If using mongodb, this also affects `type` definitions. | | 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..5799b17 100644 --- a/generator.ts +++ b/generator.ts @@ -15,6 +15,7 @@ interface Config { typePrefix: string; typeSuffix: string; headerComment: string; + modelType: "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.modelType)) { + errors.push(`Invalid modelType: ${config.modelType}`); + } 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.modelType) { + case "interface": + return `export interface ${name} {\n${fields}\n}`; + case "type": + return `export type ${name} = {\n${fields}\n};`; + default: + throw new Error(`Unknown modelType: ${config.modelType}`); + } } generatorHandler({ @@ -163,6 +175,7 @@ generatorHandler({ typePrefix: "", typeSuffix: "", headerComment: "This file was auto-generated by prisma-generator-typescript-interfaces", + modelType: "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/mongo-types/expected/mongoModelType.ts b/tests/mongo-types/expected/mongoModelType.ts new file mode 100644 index 0000000..25035ca --- /dev/null +++ b/tests/mongo-types/expected/mongoModelType.ts @@ -0,0 +1,33 @@ +// This file was auto-generated by prisma-generator-typescript-interfaces + +export type Gender = "Male" | "Female" | "Other"; + +export type PhotoType = "Selfie" | "Profile" | "Tagged"; + +export type Person = { + id: number; + name: string; + gender: Gender; + addressId: number; + address?: Address; + photos: Photo[]; + tags: Tag | null; +}; + +export type Address = { + id: number; + addressText: string; + people?: Person[]; +}; + +export type Photo = { + height: number; + Width: number; + url: string; + type: PhotoType; +}; + +export type Tag = { + id: number; + name: string; +}; diff --git a/tests/mongo-types/schema.prisma b/tests/mongo-types/schema.prisma index 7454334..20ea2b9 100644 --- a/tests/mongo-types/schema.prisma +++ b/tests/mongo-types/schema.prisma @@ -10,6 +10,12 @@ generator mongoTypes { output = "mongoTypes.ts" } +generator mongoModelType { + provider = "node --loader ts-node/esm generator.ts" + output = "mongoModelType.ts" + modelType = "type" +} + generator prefixSuffix { provider = "node --loader ts-node/esm generator.ts" output = "prefixSuffix.ts" diff --git a/tests/options-behavior/expected/modelType.ts b/tests/options-behavior/expected/modelType.ts new file mode 100644 index 0000000..9c6c735 --- /dev/null +++ b/tests/options-behavior/expected/modelType.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..699acdd 100644 --- a/tests/options-behavior/schema.prisma +++ b/tests/options-behavior/schema.prisma @@ -90,6 +90,12 @@ generator enumTypeSuffixPrefix { enumSuffix = "Enum" } +generator modelType { + provider = "node --loader ts-node/esm generator.ts" + output = "modelType.ts" + modelType = "type" +} + // ======================== // Prisma Schema // ======================== diff --git a/tests/validation-errors/expected-error.txt b/tests/validation-errors/expected-error.txt index cd1ceeb..1850a83 100644 --- a/tests/validation-errors/expected-error.txt +++ b/tests/validation-errors/expected-error.txt @@ -1,4 +1,5 @@ Error: +Invalid modelType: 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..976a0d5 100644 --- a/tests/validation-errors/schema.prisma +++ b/tests/validation-errors/schema.prisma @@ -4,12 +4,12 @@ generator typescriptInterfaces { provider = "node --loader ts-node/esm generator.ts" + modelType = "bad" enumType = "incorrect" dateType = "wrong" bigIntType = "values" decimalType = "go" bytesType = "here" - prettier = "bad" } // ========================