├── .github └── workflows │ ├── npm-publish.yml │ └── npm-test.yml ├── .gitignore ├── .husky ├── install.mjs └── pre-commit ├── .prettierignore ├── .prettierrc.yml ├── .vscode ├── launch.json └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── eslint.config.js ├── generator.ts ├── package-lock.json ├── package.json ├── prisma └── example.prisma ├── test.ts ├── tests ├── mongo-types │ ├── expected │ │ ├── mongoModelType.ts │ │ ├── mongoOmitRelations.ts │ │ ├── mongoTypes.ts │ │ └── prefixSuffix.ts │ └── schema.prisma ├── no-custom-types │ ├── expected │ │ └── interfaces.ts │ └── schema.prisma ├── options-behavior │ ├── expected │ │ ├── bytesArrayObject.ts │ │ ├── bytesBuffer.ts │ │ ├── bytesBufferObject.ts │ │ ├── customHeader.ts │ │ ├── customOutput.ts │ │ ├── defaultsSpecified.ts │ │ ├── enumExportFalse.ts │ │ ├── enumExportFalseTypeObject.ts │ │ ├── enumType.ts │ │ ├── enumTypeObject.ts │ │ ├── enumTypeObjectPrefixSuffix.ts │ │ ├── enumTypeObjectValuePrefixSuffix.ts │ │ ├── enumTypePrefixSuffix.ts │ │ ├── formatPrettier.ts │ │ ├── interfaces.ts │ │ ├── modelType.ts │ │ ├── multilineHeader.ts │ │ ├── noHeader.ts │ │ ├── numberTypes.ts │ │ ├── omitRelations.ts │ │ ├── optionalNullables.ts │ │ ├── optionalNullablesRequiredRelations.ts │ │ ├── prefixSuffix.ts │ │ ├── requiredRelations.ts │ │ └── stringTypes.ts │ └── schema.prisma ├── prettier-options │ ├── .prettierrc │ ├── expected │ │ ├── withConfig.ts │ │ └── withoutConfig.ts │ └── schema.prisma ├── type-compatible │ ├── expected │ │ └── interfaces.ts │ ├── schema.prisma │ └── test-types.ts └── validation-errors │ ├── expected-error.txt │ └── schema.prisma ├── tsconfig.build.json └── tsconfig.json /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish package 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | publish-npm: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | - uses: actions/setup-node@v4 13 | with: 14 | node-version: 20 15 | registry-url: https://registry.npmjs.org/ 16 | - run: npm ci 17 | - run: npm run build 18 | - run: npm publish 19 | env: 20 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 21 | -------------------------------------------------------------------------------- /.github/workflows/npm-test.yml: -------------------------------------------------------------------------------- 1 | name: Run tests 2 | 3 | on: 4 | push: 5 | branches: ["main"] 6 | pull_request: 7 | branches: ["main"] 8 | 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: actions/setup-node@v4 15 | with: 16 | node-version: 20 17 | - run: npm ci 18 | - run: npm run lint 19 | - run: npm run build 20 | - run: npm test 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | __TEST_TMP__ 3 | generator.js 4 | *.tgz 5 | 6 | # Ignore eventyrhing in the prisma folder except the example 7 | prisma/* 8 | !prisma/example.prisma 9 | -------------------------------------------------------------------------------- /.husky/install.mjs: -------------------------------------------------------------------------------- 1 | // Skip Husky install in production and CI 2 | if (process.env.NODE_ENV === "production" || process.env.CI === "true") { 3 | process.exit(0); 4 | } 5 | const husky = (await import("husky")).default; 6 | console.log(husky()); 7 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | npm run lint || { echo "Linting failed, run 'npm run lint:fix' to try and fix linting errors." && exit 1; } 2 | npm test || { echo "Tests failed" && exit 1; } 3 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | tests/**/*.ts 2 | -------------------------------------------------------------------------------- /.prettierrc.yml: -------------------------------------------------------------------------------- 1 | printWidth: 100 2 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "attach", 10 | "name": "Attach", 11 | "skipFiles": ["/**"] 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib", 3 | "editor.defaultFormatter": "esbenp.prettier-vscode", 4 | "editor.formatOnSave": true, 5 | "editor.codeActionsOnSave": { 6 | "source.fixAll.eslint": "always" 7 | }, 8 | "cSpell.words": ["autoincrement", "datamodel", "datasource", "dmmf"], 9 | "[prisma]": { 10 | "editor.defaultFormatter": "Prisma.prisma" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 2.1.0 2 | 3 | - Stop enum fields from being marked `readonly` when using `enumType = "object"` - [#14](https://github.com/mogzol/prisma-generator-typescript-interfaces/pull/14) 4 | - Note that this is a **breaking change** if you are using TypeScript < 4.9, as it uses the `satisfies` keyword. Either upgrade TypeScript or use a different `enumType`. 5 | - Add `enumObjectSuffix` and `enumObjectPrefix` options - [#14](https://github.com/mogzol/prisma-generator-typescript-interfaces/pull/14) 6 | - Add `exportEnums` option - [#15](https://github.com/mogzol/prisma-generator-typescript-interfaces/pull/15) 7 | - Thanks [@helmturner](https://github.com/helmturner) for these changes! 8 | 9 | ## 2.0.1 10 | 11 | - Fix README.md example, and re-order the README.md sections. 12 | 13 | # 2.0.0 14 | 15 | - **BREAKING**: Add `Uint8Array` option for `bytesType`, and make it the default. This is to match the changes made in [Prisma v6](https://www.prisma.io/docs/orm/more/upgrade-guides/upgrading-versions/upgrading-to-prisma-6#usage-of-buffer). If you are still using Prisma v5 and want the generated types to be type-compatible with the Prisma client, you will now need to explicitly set `bytesType` to `Buffer`. 16 | - Add `ArrayObject` option for `bytesType`, which matches the output of running `JSON.stringify` on a `Uint8Array`. 17 | - Update dependency declaration for `@prisma/generator-helper` to allow either v5 or v6 of the library, as either will work. 18 | 19 | ## 1.7.0 20 | 21 | - Add `resolvePrettierConfig` option - [#9](https://github.com/mogzol/prisma-generator-typescript-interfaces/pull/9) (thanks [@adrian-rom64](https://github.com/adrian-rom64)) 22 | 23 | ## 1.6.1 24 | 25 | - No code changes since 1.6.0, this is just a documentation update. 26 | 27 | ## 1.6.0 28 | 29 | - Add `optionalNullables` option 30 | 31 | ## 1.5.0 32 | 33 | - Add `object` enumType option that matches Prisma client's enum definitions ([#6](https://github.com/mogzol/prisma-generator-typescript-interfaces/pull/6)) 34 | 35 | ## 1.4.0 36 | 37 | - Add `omitRelations` option to omit model relation fields in the generated file 38 | 39 | ## 1.3.0 40 | 41 | - Add `modelType` option to control whether the model definitions are outputted as Typescript interfaces or types 42 | 43 | ## 1.2.0 44 | 45 | - Add shebang to script, should fix several compatibility issues 46 | - Fix compatibility with `@prisma/generator-helper` v5.7.0 47 | - Update dependencies to their latest version 48 | - Allow `number` types for Date and Decimal (though obviously not recommended if you care about precision) 49 | 50 | ## 1.1.1 51 | 52 | - Add repository info to package.json 53 | 54 | ## 1.1.0 55 | 56 | - Added a header comment to generated output, configurable with the new headerComment option. 57 | - Improved tests 58 | 59 | ## 1.0.1 60 | 61 | - No code changes, just updating the README and package.json 62 | 63 | # 1.0.0 64 | 65 | - Initial release 66 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Morgan Zolob 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Prisma TypeScript Interfaces Generator 2 | 3 | [`prisma-generator-typescript-interfaces`](https://www.npmjs.com/package/prisma-generator-typescript-interfaces) - A [Prisma generator](https://www.prisma.io/docs/concepts/components/prisma-schema/generators) that creates zero-dependency TypeScript interfaces from Prisma schema. 4 | 5 | ## Motivation 6 | 7 | While Prisma client's generated types are sufficient for most use cases, there are some scenarios where using them is not convenient or possible, due to the fact that they rely on both the `@prisma/client` package and on the client generated from your Prisma schema. That is where this generator comes in. It generates a zero-dependency TypeScript file containing type definitions for all your models. This file will not contain any imports and can be used standalone in any TypeScript app. By default, the definitions are [type-compatible](https://www.typescriptlang.org/docs/handbook/type-compatibility.html) with the Prisma client types, however this can be customized via the [options](#options), see below for more info. 8 | 9 | ## Usage 10 | 11 | To use this generator, first install the package: 12 | 13 | ``` 14 | npm install --save-dev prisma-generator-typescript-interfaces 15 | ``` 16 | 17 | Next add the generator to your Prisma schema: 18 | 19 | ```prisma 20 | generator typescriptInterfaces { 21 | provider = "prisma-generator-typescript-interfaces" 22 | } 23 | ``` 24 | 25 | And finally generate your Prisma schema: 26 | 27 | ``` 28 | npx prisma generate 29 | ``` 30 | 31 | By default, that will output the TypeScript interface definitions to a file called `interfaces.ts` in your `prisma` folder, but this can be changed by specifying the `output` option. As mentioned above, the generated types will, by default, be [type-compatible](https://www.typescriptlang.org/docs/handbook/type-compatibility.html) with the Prisma client types. If you instead want to generate types matching the `JSON.stringify`-ed versions of your models, you will need to change some of the options, like so: 32 | 33 | ```prisma 34 | generator typescriptInterfaces { 35 | provider = "prisma-generator-typescript-interfaces" 36 | dateType = "string" 37 | bigIntType = "string" 38 | decimalType = "string" 39 | bytesType = "ArrayObject" 40 | } 41 | ``` 42 | 43 | Note that `bigint` types don't have a default `toJSON` method, so the above assumes that you are converting them to strings somewhere along the line. 44 | 45 | ## Example 46 | 47 | Here is an example of a configuration that generates two separate outputs, `interfaces.ts` with types compatible with the Prisma client types, and a second `json-interfaces.ts` file with types matching the output of `JSON.stringify` when run on the models. Both files are output to the `src/dto` folder (which will be created if it doesn't exist) and are formatted using Prettier. The models in `json-interfaces.ts` also get a `Json` suffix attached to them. 48 | 49 | #### Input 50 | 51 |
52 | prisma/schema.prisma 53 | 54 | ```prisma 55 | datasource db { 56 | provider = "postgresql" 57 | url = env("DATABASE_URL") 58 | } 59 | 60 | generator client { 61 | provider = "prisma-client-js" 62 | } 63 | 64 | generator typescriptInterfaces { 65 | provider = "prisma-generator-typescript-interfaces" 66 | output = "../src/dto/interfaces.ts" 67 | prettier = true 68 | } 69 | 70 | generator typescriptInterfacesJson { 71 | provider = "prisma-generator-typescript-interfaces" 72 | output = "../src/dto/json-interfaces.ts" 73 | modelSuffix = "Json" 74 | dateType = "string" 75 | bigIntType = "string" 76 | decimalType = "string" 77 | bytesType = "ArrayObject" 78 | exportEnums = false 79 | prettier = true 80 | } 81 | 82 | enum Gender { 83 | Male 84 | Female 85 | Other 86 | } 87 | 88 | model Person { 89 | id Int @id @default(autoincrement()) 90 | name String 91 | age Int 92 | email String? 93 | gender Gender 94 | addressId Int 95 | address Address @relation(fields: [addressId], references: [id]) 96 | friendsOf Person[] @relation("Friends") 97 | friends Person[] @relation("Friends") 98 | data Data? 99 | } 100 | 101 | model Address { 102 | id Int @id 103 | streetNumber Int 104 | streetName String 105 | city String 106 | isBilling Boolean 107 | people Person[] 108 | } 109 | 110 | model Data { 111 | id String @id @default(uuid()) @db.Uuid 112 | stringField String 113 | booleanField Boolean 114 | intField Int 115 | bigIntField BigInt 116 | floatField Float 117 | decimalField Decimal 118 | dateField DateTime 119 | jsonField Json 120 | bytesField Bytes 121 | 122 | optionalStringField String? 123 | optionalBooleanField Boolean? 124 | optionalIntField Int? 125 | optionalBigIntField BigInt? 126 | optionalFloatField Float? 127 | optionalDecimalField Decimal? 128 | optionalDateField DateTime? 129 | optionalJsonField Json? 130 | optionalBytesField Bytes? 131 | 132 | stringArrayField String[] 133 | booleanArrayField Boolean[] 134 | intArrayField Int[] 135 | bigIntArrayField BigInt[] 136 | floatArrayField Float[] 137 | decimalArrayField Decimal[] 138 | dateArrayField DateTime[] 139 | jsonArrayField Json[] 140 | bytesArrayField Bytes[] 141 | 142 | personId Int @unique 143 | person Person @relation(fields: [personId], references: [id]) 144 | } 145 | 146 | ``` 147 | 148 |
149 | 150 | #### Output 151 | 152 |
153 | src/dto/interfaces.ts 154 | 155 | ```typescript 156 | // This file was auto-generated by prisma-generator-typescript-interfaces 157 | 158 | export type Gender = "Male" | "Female" | "Other"; 159 | 160 | export interface Person { 161 | id: number; 162 | name: string; 163 | age: number; 164 | email: string | null; 165 | gender: Gender; 166 | addressId: number; 167 | address?: Address; 168 | friendsOf?: Person[]; 169 | friends?: Person[]; 170 | data?: Data | null; 171 | } 172 | 173 | export interface Address { 174 | id: number; 175 | streetNumber: number; 176 | streetName: string; 177 | city: string; 178 | isBilling: boolean; 179 | people?: Person[]; 180 | } 181 | 182 | export interface Data { 183 | id: string; 184 | stringField: string; 185 | booleanField: boolean; 186 | intField: number; 187 | bigIntField: bigint; 188 | floatField: number; 189 | decimalField: Decimal; 190 | dateField: Date; 191 | jsonField: JsonValue; 192 | bytesField: Uint8Array; 193 | optionalStringField: string | null; 194 | optionalBooleanField: boolean | null; 195 | optionalIntField: number | null; 196 | optionalBigIntField: bigint | null; 197 | optionalFloatField: number | null; 198 | optionalDecimalField: Decimal | null; 199 | optionalDateField: Date | null; 200 | optionalJsonField: JsonValue | null; 201 | optionalBytesField: Uint8Array | null; 202 | stringArrayField: string[]; 203 | booleanArrayField: boolean[]; 204 | intArrayField: number[]; 205 | bigIntArrayField: bigint[]; 206 | floatArrayField: number[]; 207 | decimalArrayField: Decimal[]; 208 | dateArrayField: Date[]; 209 | jsonArrayField: JsonValue[]; 210 | bytesArrayField: Uint8Array[]; 211 | personId: number; 212 | person?: Person; 213 | } 214 | 215 | type Decimal = { valueOf(): string }; 216 | 217 | type JsonValue = 218 | | string 219 | | number 220 | | boolean 221 | | { [key in string]?: JsonValue } 222 | | Array 223 | | null; 224 | ``` 225 | 226 |
227 | 228 |
229 | src/dto/json-interfaces.ts 230 | 231 | ```typescript 232 | // This file was auto-generated by prisma-generator-typescript-interfaces 233 | 234 | type Gender = "Male" | "Female" | "Other"; 235 | 236 | export interface PersonJson { 237 | id: number; 238 | name: string; 239 | age: number; 240 | email: string | null; 241 | gender: Gender; 242 | addressId: number; 243 | address?: AddressJson; 244 | friendsOf?: PersonJson[]; 245 | friends?: PersonJson[]; 246 | data?: DataJson | null; 247 | } 248 | 249 | export interface AddressJson { 250 | id: number; 251 | streetNumber: number; 252 | streetName: string; 253 | city: string; 254 | isBilling: boolean; 255 | people?: PersonJson[]; 256 | } 257 | 258 | export interface DataJson { 259 | id: string; 260 | stringField: string; 261 | booleanField: boolean; 262 | intField: number; 263 | bigIntField: string; 264 | floatField: number; 265 | decimalField: string; 266 | dateField: string; 267 | jsonField: JsonValue; 268 | bytesField: ArrayObject; 269 | optionalStringField: string | null; 270 | optionalBooleanField: boolean | null; 271 | optionalIntField: number | null; 272 | optionalBigIntField: string | null; 273 | optionalFloatField: number | null; 274 | optionalDecimalField: string | null; 275 | optionalDateField: string | null; 276 | optionalJsonField: JsonValue | null; 277 | optionalBytesField: ArrayObject | null; 278 | stringArrayField: string[]; 279 | booleanArrayField: boolean[]; 280 | intArrayField: number[]; 281 | bigIntArrayField: string[]; 282 | floatArrayField: number[]; 283 | decimalArrayField: string[]; 284 | dateArrayField: string[]; 285 | jsonArrayField: JsonValue[]; 286 | bytesArrayField: ArrayObject[]; 287 | personId: number; 288 | person?: PersonJson; 289 | } 290 | 291 | type JsonValue = 292 | | string 293 | | number 294 | | boolean 295 | | { [key in string]?: JsonValue } 296 | | Array 297 | | null; 298 | 299 | type ArrayObject = { [index: number]: number } & { length?: never }; 300 | ``` 301 | 302 |
303 | 304 | ## Options 305 | 306 | | **Option** | **Type** | **Default** | **Description** | 307 | | --------------------- | :-------------------------------------------------------------------------------------: | :------------------------------------------------------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 308 | | output | `string` | `"interfaces.ts"` | The output location for the generated TypeScript interfaces. | 309 | | enumPrefix | `string` | `""` | Prefix to add to enum types. | 310 | | enumSuffix | `string` | `""` | Suffix to add to enum types. | 311 | | enumObjectPrefix | `string` | `""` | Prefix to add to enum objects. Only applies when `enumType` is `object`. | 312 | | enumObjectSuffix | `string` | `""` | Suffix to add to enum objects. Only applies when `enumType` is `object`. | 313 | | modelPrefix | `string` | `""` | Prefix to add to model types. | 314 | | modelSuffix | `string` | `""` | Suffix to add to model types. | 315 | | typePrefix | `string` | `""` | Prefix to add to [type](https://www.prisma.io/docs/concepts/components/prisma-schema/data-model#defining-composite-types) types (MongoDB only). | 316 | | typeSuffix | `string` | `""` | Suffix to add to [type](https://www.prisma.io/docs/concepts/components/prisma-schema/data-model#defining-composite-types) types (MongoDB only). | 317 | | 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"`. | 318 | | 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. | 319 | | enumType | `"stringUnion" \| "enum" \| "object"` | `"stringUnion"` | Controls how enums are generated. `"object"` will create an object and string union type like the Prisma client, `"enum"` will create TypeScript enums, `"stringUnion"` will just create a string union type. | 320 | | dateType | `"Date" \| "string" \| "number"` | `"Date"` | The type to use for DateTime model fields. | 321 | | bigIntType | `"bigint" \| "string" \| "number"` | `"bigint"` | The type to use for BigInt model fields. | 322 | | decimalType | `"Decimal" \| "string" \| "number"` | `"Decimal"` | The type to use for Decimal model fields. The `Decimal` type here is just an interface with a `valueOf()` function. You will need to cast to an actual Decimal type if you want to use other methods. | 323 | | bytesType | `"Uint8Array" \| "Buffer" \| "ArrayObject" \| "BufferObject" \| "string" \| "number[]"` | `"Uint8Array"` | The type to use for Bytes model fields. `ArrayObject` is a type which matches a `JSON.stringify`-ed Uint8Array. `BufferObject` is a type which matches a `JSON.stringify`-ed Buffer. | 324 | | exportEnums | `boolean` | `true` | Controls whether enum definitions are exported. If `false`, enums will only be defined in the module scope for use by dependent types. Respects `enumType`. | 325 | | optionalRelations | `boolean` | `true` | Controls whether model relation fields are optional. If `true`, all model relation fields will use `?:` in the field definition. | 326 | | omitRelations | `boolean` | `false` | Controls whether model relation fields are omitted. If `true`, model definitions will not include their relations. | 327 | | optionalNullables | `boolean` | `false` | Controls whether nullable fields are optional. Nullable fields are always defined with `\| null` in their type definition, but if this is `true`, they will also use `?:`. | 328 | | prettier | `boolean` | `false` | Formats the output using Prettier. Setting this to `true` requires that the `prettier` package is available. | 329 | | resolvePrettierConfig | `boolean` | `true` | Tries to find and use a Prettier config file relative to the output location. | 330 | 331 | ## Issues 332 | 333 | Please report any issues to the [issues](https://github.com/mogzol/prisma-generator-typescript-interfaces/issues) page. I am actively using this package, so I'll try my best to address any issues that are reported. Alternatively, feel free to submit a PR. 334 | 335 | ## Developing 336 | 337 | All the code for this generator is contained within the `generator.ts` file. You can build the generator by running `npm install` then `npm run build`. 338 | 339 | ### Tests 340 | 341 | You can run tests with `npm run test`. Tests are run using a custom script, see `test.ts` for details. You can add new tests by placing a Prisma schema and the expected output in a folder under the `tests` directory, you may want to look at the `tests/options-behavior` test as an example. 342 | 343 | You can run specific tests by passing them as arguments to the test command: 344 | 345 | ``` 346 | npm run test -- options-behavior validation-errors 347 | ``` 348 | 349 | When a test fails, you can see the generated output in the `__TEST_TMP__` folder inside that test's directory. Compare this with the expected output to see why it failed. 350 | 351 | Please ensure all tests are passing and that the code is properly linted (`npm run lint`) before submitting a PR, thanks! 352 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | import eslint from "@eslint/js"; 4 | import tseslint from "typescript-eslint"; 5 | import eslintConfigPrettier from "eslint-config-prettier"; 6 | 7 | export default tseslint.config({ 8 | files: ["*.ts"], 9 | extends: [ 10 | eslint.configs.recommended, 11 | eslintConfigPrettier, 12 | ...tseslint.configs.recommendedTypeChecked, 13 | ], 14 | rules: { 15 | "@typescript-eslint/restrict-template-expressions": ["error", { allowNever: true }], 16 | }, 17 | languageOptions: { 18 | parserOptions: { 19 | projectService: true, 20 | tsconfigRootDir: import.meta.dirname, 21 | }, 22 | }, 23 | }); 24 | -------------------------------------------------------------------------------- /generator.ts: -------------------------------------------------------------------------------- 1 | import type { DMMF } from "@prisma/generator-helper"; 2 | import generatorHelper from "@prisma/generator-helper"; 3 | import { mkdir, writeFile } from "node:fs/promises"; 4 | import { dirname } from "node:path"; 5 | 6 | // Need to use default export for ESM compatibility 7 | const { generatorHandler } = generatorHelper; 8 | 9 | interface Config { 10 | enumPrefix: string; 11 | enumSuffix: string; 12 | enumObjectPrefix: string; 13 | enumObjectSuffix: string; 14 | modelPrefix: string; 15 | modelSuffix: string; 16 | typePrefix: string; 17 | typeSuffix: string; 18 | headerComment: string; 19 | modelType: "interface" | "type"; 20 | enumType: "stringUnion" | "enum" | "object"; 21 | dateType: "Date" | "string" | "number"; 22 | bigIntType: "bigint" | "string" | "number"; 23 | decimalType: "Decimal" | "string" | "number"; 24 | bytesType: "Uint8Array" | "Buffer" | "ArrayObject" | "BufferObject" | "string" | "number[]"; 25 | exportEnums: boolean; 26 | optionalRelations: boolean; 27 | omitRelations: boolean; 28 | optionalNullables: boolean; 29 | prettier: boolean; 30 | resolvePrettierConfig: boolean; 31 | } 32 | 33 | // Map of Prisma scalar types to Typescript type getters 34 | const SCALAR_TYPE_GETTERS: Record string> = { 35 | String: () => "string", 36 | Boolean: () => "boolean", 37 | Int: () => "number", 38 | Float: () => "number", 39 | Json: () => "JsonValue", 40 | DateTime: (config) => config.dateType, 41 | BigInt: (config) => config.bigIntType, 42 | Decimal: (config) => config.decimalType, 43 | Bytes: (config) => config.bytesType, 44 | }; 45 | 46 | // Since we want the output to have zero dependencies, define custom types which are compatible 47 | // with the actual Prisma types. If users need the real Prisma types, they can cast to them. 48 | const CUSTOM_TYPES = { 49 | ArrayObject: "type ArrayObject = { [index: number]: number } & { length?: never };", 50 | BufferObject: 'type BufferObject = { type: "Buffer"; data: number[] };', 51 | Decimal: "type Decimal = { valueOf(): string };", 52 | JsonValue: 53 | "type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null;", 54 | }; 55 | 56 | function validateConfig(config: Config) { 57 | const errors: string[] = []; 58 | if (!["interface", "type"].includes(config.modelType)) { 59 | errors.push(`Invalid modelType: ${config.modelType}`); 60 | } 61 | if (!["stringUnion", "enum", "object"].includes(config.enumType)) { 62 | errors.push(`Invalid enumType: ${config.enumType}`); 63 | } 64 | if (!["Date", "string", "number"].includes(config.dateType)) { 65 | errors.push(`Invalid dateType: ${config.dateType}`); 66 | } 67 | if (!["bigint", "string", "number"].includes(config.bigIntType)) { 68 | errors.push(`Invalid bigIntType: ${config.bigIntType}`); 69 | } 70 | if (!["Decimal", "string", "number"].includes(config.decimalType)) { 71 | errors.push(`Invalid decimalType: ${config.decimalType}`); 72 | } 73 | if ( 74 | !["Uint8Array", "Buffer", "ArrayObject", "BufferObject", "string", "number[]"].includes( 75 | config.bytesType, 76 | ) 77 | ) { 78 | errors.push(`Invalid bytesType: ${config.bytesType}`); 79 | } 80 | if (errors.length > 0) { 81 | throw new Error(errors.join("\n")); 82 | } 83 | } 84 | 85 | // Get the Typescript code representing a Prisma Enum 86 | function getEnumTs( 87 | config: Config, 88 | enumData: DMMF.DatamodelEnum, 89 | enumNameMap: Map, 90 | ): string { 91 | const exportKwd = config.exportEnums ? "export " : ""; 92 | switch (config.enumType) { 93 | case "enum": { 94 | const enumValues = enumData.values.map(({ name }) => ` ${name} = "${name}"`).join(",\n"); 95 | return `${exportKwd}enum ${enumNameMap.get(enumData.name)} {\n${enumValues}\n}`; 96 | } 97 | case "stringUnion": { 98 | const enumValues = enumData.values.map(({ name }) => `"${name}"`).join(" | "); 99 | return `${exportKwd}type ${enumNameMap.get(enumData.name)} = ${enumValues};`; 100 | } 101 | case "object": { 102 | const enumValues = enumData.values.map(({ name }) => ` ${name}: "${name}"`).join(",\n"); 103 | const enumName = enumNameMap.get(enumData.name); 104 | const enumObjectName = `${config.enumObjectPrefix}${enumName}${config.enumObjectSuffix}`; 105 | const enumType = enumData.values.map(({ name }) => `"${name}"`).join(" | "); 106 | return `${exportKwd}type ${enumName} = ${enumType};\n\n${exportKwd}const ${enumObjectName} = {\n${enumValues}\n} satisfies Record;`; 107 | } 108 | default: 109 | throw new Error(`Unknown enumType: ${config.enumType}`); 110 | } 111 | } 112 | 113 | // Get the Typescript code representing a Prisma Model 114 | function getModelTs( 115 | config: Config, 116 | modelData: DMMF.Model, 117 | modelNameMap: Map, 118 | enumNameMap: Map, 119 | typeNameMap: Map, 120 | usedCustomTypes: Set, 121 | ): string { 122 | const fields = modelData.fields 123 | .map(({ name, kind, type, isRequired, isList }) => { 124 | const getDefinition = (resolvedType: string, optional = false) => 125 | " " + 126 | `${name}${optional || (!isRequired && config.optionalNullables) ? "?" : ""}: ` + 127 | `${resolvedType}${isList ? "[]" : ""}${!isRequired ? " | null" : ""};`; 128 | 129 | switch (kind) { 130 | case "scalar": { 131 | const typeGetter = SCALAR_TYPE_GETTERS[type]; 132 | if (!typeGetter) { 133 | throw new Error(`Unknown scalar type: ${type}`); 134 | } 135 | const resolvedType = typeGetter(config); 136 | if (resolvedType in CUSTOM_TYPES) { 137 | usedCustomTypes.add(resolvedType as keyof typeof CUSTOM_TYPES); 138 | } 139 | return getDefinition(resolvedType); 140 | } 141 | case "object": { 142 | const modelName = modelNameMap.get(type); 143 | const typeName = typeNameMap.get(type); 144 | if (typeName) { 145 | return getDefinition(typeName); // Type relations are never optional or omitted 146 | } else if (modelName) { 147 | return config.omitRelations ? null : getDefinition(modelName, config.optionalRelations); 148 | } else { 149 | throw new Error(`Unknown model name: ${type}`); 150 | } 151 | } 152 | case "enum": { 153 | const enumName = enumNameMap.get(type); 154 | if (!enumName) { 155 | throw new Error(`Unknown enum name: ${type}`); 156 | } 157 | return getDefinition(enumName); 158 | } 159 | case "unsupported": 160 | return getDefinition("any"); 161 | default: 162 | throw new Error(`Unknown field kind: ${kind}`); 163 | } 164 | }) 165 | .filter((f) => f !== null) 166 | .join("\n"); 167 | 168 | const name = modelNameMap.get(modelData.name) ?? typeNameMap.get(modelData.name); 169 | 170 | switch (config.modelType) { 171 | case "interface": 172 | return `export interface ${name} {\n${fields}\n}`; 173 | case "type": 174 | return `export type ${name} = {\n${fields}\n};`; 175 | default: 176 | throw new Error(`Unknown modelType: ${config.modelType}`); 177 | } 178 | } 179 | 180 | generatorHandler({ 181 | onManifest() { 182 | return { 183 | prettyName: "Typescript Interfaces", 184 | defaultOutput: "interfaces.ts", 185 | }; 186 | }, 187 | async onGenerate(options) { 188 | const baseConfig = options.generator.config; 189 | const config: Config = { 190 | enumPrefix: "", 191 | enumSuffix: "", 192 | enumObjectPrefix: "", 193 | enumObjectSuffix: "", 194 | modelPrefix: "", 195 | modelSuffix: "", 196 | typePrefix: "", 197 | typeSuffix: "", 198 | headerComment: "This file was auto-generated by prisma-generator-typescript-interfaces", 199 | modelType: "interface", 200 | enumType: "stringUnion", 201 | dateType: "Date", 202 | bigIntType: "bigint", 203 | decimalType: "Decimal", 204 | bytesType: "Uint8Array", 205 | ...baseConfig, 206 | // Booleans go here since in the base config they are strings 207 | exportEnums: baseConfig.exportEnums !== "false", // Default true 208 | optionalRelations: baseConfig.optionalRelations !== "false", // Default true 209 | omitRelations: baseConfig.omitRelations === "true", // Default false 210 | optionalNullables: baseConfig.optionalNullables === "true", // Default false 211 | prettier: baseConfig.prettier === "true", // Default false 212 | resolvePrettierConfig: baseConfig.resolvePrettierConfig !== "false", // Default true 213 | }; 214 | 215 | validateConfig(config); 216 | 217 | const datamodel = options.dmmf.datamodel; 218 | const models = datamodel.models; 219 | const enums = datamodel.enums; 220 | const types = datamodel.types; 221 | 222 | const usedCustomTypes = new Set(); 223 | 224 | const enumNameMap = new Map( 225 | enums.map((e) => [e.name, `${config.enumPrefix}${e.name}${config.enumSuffix}`]), 226 | ); 227 | const modelNameMap = new Map( 228 | models.map((m) => [m.name, `${config.modelPrefix}${m.name}${config.modelSuffix}`]), 229 | ); 230 | const typeNameMap = new Map( 231 | types.map((t) => [t.name, `${config.typePrefix}${t.name}${config.typeSuffix}`]), 232 | ); 233 | 234 | const enumsTs = enums.map((e) => getEnumTs(config, e, enumNameMap)); 235 | // Types and Models are essentially the same thing, so we can run both through getModelTs 236 | const modelsTs = [...models, ...types].map((m) => 237 | getModelTs(config, m, modelNameMap, enumNameMap, typeNameMap, usedCustomTypes), 238 | ); 239 | const customTypesTs = Array.from(usedCustomTypes).map((t) => CUSTOM_TYPES[t]); 240 | 241 | let ts = [...enumsTs, ...modelsTs, ...customTypesTs].join("\n\n") + "\n"; 242 | 243 | if (config.headerComment) { 244 | const headerContent = config.headerComment 245 | .split("\n") 246 | .map((line) => `// ${line}`) 247 | .join("\n"); 248 | ts = `${headerContent}\n\n${ts}`; 249 | } 250 | 251 | const outputFile = options.generator.output?.value as string; 252 | const outputDir = dirname(outputFile); 253 | 254 | if (config.prettier) { 255 | // Prettier is imported inside this if so that it's not a required dependency 256 | let prettier: typeof import("prettier"); 257 | try { 258 | prettier = await import("prettier"); 259 | } catch { 260 | throw new Error("Unable import Prettier. Is it installed?"); 261 | } 262 | 263 | const prettierOptions = config.resolvePrettierConfig 264 | ? await prettier.resolveConfig(outputFile) 265 | : null; 266 | 267 | ts = await prettier.format(ts, { ...prettierOptions, parser: "typescript" }); 268 | } 269 | 270 | await mkdir(outputDir, { recursive: true }); 271 | await writeFile(outputFile, ts); 272 | }, 273 | }); 274 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "prisma-generator-typescript-interfaces", 3 | "version": "2.1.0", 4 | "description": "Generate zero-dependency Typescript interfaces from Prisma schema", 5 | "author": "Morgan Zolob", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/mogzol/prisma-generator-typescript-interfaces" 10 | }, 11 | "type": "module", 12 | "main": "generator.js", 13 | "files": [ 14 | "generator.js" 15 | ], 16 | "bin": { 17 | "prisma-generator-typescript-interfaces": "generator.js" 18 | }, 19 | "scripts": { 20 | "build": "tsc -p tsconfig.build.json", 21 | "postbuild": "node -e \"g='generator.js';f=require('fs');f.writeFileSync(g,'#!/usr/bin/env node\\n'+f.readFileSync(g))\"", 22 | "clean": "rimraf --glob generator.js **/__TEST_TMP__", 23 | "generate": "prisma generate --schema=prisma/example.prisma", 24 | "lint": "prettier --check . && eslint . && echo 'Linting complete.'", 25 | "lint:fix": "prettier --write . && eslint . --fix && echo 'Linting complete.'", 26 | "test": "tsx test.ts", 27 | "prepare": "node .husky/install.mjs" 28 | }, 29 | "dependencies": { 30 | "@prisma/generator-helper": "^5 || ^6" 31 | }, 32 | "devDependencies": { 33 | "@eslint/js": "^9.22.0", 34 | "@prisma/client": "^6.5.0", 35 | "@types/node": "^22.13.10", 36 | "eslint": "^9.22.0", 37 | "eslint-config-prettier": "^10.1.1", 38 | "husky": "^9.1.7", 39 | "prettier": "^3.5.3", 40 | "prisma": "^6.5.0", 41 | "rimraf": "^6.0.1", 42 | "tsx": "^4.19.3", 43 | "typescript": "^5.8.2", 44 | "typescript-eslint": "^8.26.1" 45 | }, 46 | "keywords": [ 47 | "prisma", 48 | "generator", 49 | "typescript", 50 | "interface", 51 | "json", 52 | "dto" 53 | ] 54 | } 55 | -------------------------------------------------------------------------------- /prisma/example.prisma: -------------------------------------------------------------------------------- 1 | // Complete example schema to generate during development. Uses tsx to run the generator. 2 | // To generate, run: `npm run generate` or `npx prisma generate --schema=prisma/example.prisma` 3 | 4 | datasource db { 5 | provider = "postgresql" 6 | url = env("DATABASE_URL") 7 | } 8 | 9 | generator client { 10 | provider = "prisma-client-js" 11 | } 12 | 13 | generator typescriptInterfaces { 14 | provider = "tsx generator.ts" 15 | output = "example.ts" 16 | prettier = true 17 | } 18 | 19 | generator typescriptInterfacesJson { 20 | provider = "tsx generator.ts" 21 | output = "exampleJson.ts" 22 | modelSuffix = "Json" 23 | dateType = "string" 24 | bigIntType = "string" 25 | decimalType = "string" 26 | bytesType = "ArrayObject" 27 | prettier = true 28 | } 29 | 30 | enum Gender { 31 | Male 32 | Female 33 | Other 34 | } 35 | 36 | model Person { 37 | id Int @id @default(autoincrement()) 38 | name String 39 | age Int 40 | email String? 41 | gender Gender 42 | addressId Int 43 | address Address @relation(fields: [addressId], references: [id]) 44 | friendsOf Person[] @relation("Friends") 45 | friends Person[] @relation("Friends") 46 | data Data? 47 | } 48 | 49 | model Address { 50 | id Int @id 51 | streetNumber Int 52 | streetName String 53 | city String 54 | isBilling Boolean 55 | people Person[] 56 | } 57 | 58 | model Data { 59 | id String @id @default(uuid()) @db.Uuid 60 | stringField String 61 | booleanField Boolean 62 | intField Int 63 | bigIntField BigInt 64 | floatField Float 65 | decimalField Decimal 66 | dateField DateTime 67 | jsonField Json 68 | bytesField Bytes 69 | 70 | optionalStringField String? 71 | optionalBooleanField Boolean? 72 | optionalIntField Int? 73 | optionalBigIntField BigInt? 74 | optionalFloatField Float? 75 | optionalDecimalField Decimal? 76 | optionalDateField DateTime? 77 | optionalJsonField Json? 78 | optionalBytesField Bytes? 79 | 80 | stringArrayField String[] 81 | booleanArrayField Boolean[] 82 | intArrayField Int[] 83 | bigIntArrayField BigInt[] 84 | floatArrayField Float[] 85 | decimalArrayField Decimal[] 86 | dateArrayField DateTime[] 87 | jsonArrayField Json[] 88 | bytesArrayField Bytes[] 89 | 90 | personId Int @unique 91 | person Person @relation(fields: [personId], references: [id]) 92 | } 93 | -------------------------------------------------------------------------------- /test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Custom testing script which runs the generator on all the schemas in the "tests" directory, and 3 | * validates that the output matches the expected outputs (in the "expected" directory within the 4 | * test folders). If a test is expected to fail, the expected error message should be put in an 5 | * "expected-error.txt" file in the relevant test folder. Optionally, a test can include a 6 | * "test-types.ts" file, which will be type-checked during the test, and will fail the test if there 7 | * are any errors. 8 | * 9 | * You can run specific tests by passing them as arguments to this script: 10 | * npm run test -- options-behavior validation-errors 11 | * 12 | * You can use the "--keep-output" argument to keep the __TEST_TMP__ directories after the tests 13 | * have run, even if they are successful: 14 | * npm run test -- --keep-output 15 | */ 16 | 17 | import { exec } from "node:child_process"; 18 | import { promisify } from "node:util"; 19 | import { rimraf } from "rimraf"; 20 | import fs from "node:fs/promises"; 21 | import path from "node:path"; 22 | 23 | const TEMP_TEST_DIRNAME = "__TEST_TMP__"; 24 | const RED = "\x1b[1;97;41m"; 25 | const GREEN = "\x1b[1;102;30m"; 26 | const RESET = "\x1b[0m"; 27 | 28 | const execAsync = promisify(exec); 29 | const trimMultiLine = (s: string) => 30 | s 31 | .trim() 32 | .split("\n") 33 | .map((l) => l.trim()) 34 | .join("\n"); 35 | 36 | async function validPath(path: string) { 37 | try { 38 | await fs.access(path); 39 | return path; // Return the path if it is accessible 40 | } catch (e) { 41 | if (e instanceof Error && "code" in e && e.code === "ENOENT") { 42 | return null; // Return null when file is not found 43 | } 44 | throw e; 45 | } 46 | } 47 | 48 | async function readFile(path: string) { 49 | try { 50 | return await fs.readFile(path, { encoding: "utf-8" }); 51 | } catch (e) { 52 | if (e instanceof Error && "code" in e && e.code === "ENOENT") { 53 | return null; // Return null when file is not found 54 | } 55 | throw e; 56 | } 57 | } 58 | 59 | async function readDir(path: string) { 60 | try { 61 | return await fs.readdir(path, { withFileTypes: true }); 62 | } catch (e) { 63 | if (e instanceof Error && "code" in e && e.code === "ENOENT") { 64 | return []; // Return empty array when dir not found 65 | } 66 | throw e; 67 | } 68 | } 69 | 70 | const testFilters = process.argv.slice(2); 71 | 72 | const keepOutputIdx = testFilters.indexOf("--keep-output"); 73 | const keepOutput = keepOutputIdx !== -1; 74 | if (keepOutput) { 75 | testFilters.splice(keepOutputIdx, 1); 76 | } 77 | 78 | const tests = (await readDir("tests")) 79 | .filter((d) => d.isDirectory() && (!testFilters.length || testFilters.includes(d.name))) 80 | .map((d) => path.join(d.path, d.name)); 81 | 82 | if (!tests.length) { 83 | console.error("No tests found!"); 84 | process.exit(1); 85 | } 86 | 87 | // Get the length of the longest test name, so we can pad the output 88 | const longestName = Math.max(...tests.map((t) => t.length)); 89 | 90 | console.log("\nRunning tests..."); 91 | 92 | let hasErrors = false; 93 | 94 | for (const test of tests) { 95 | try { 96 | process.stdout.write(` ${test}${" ".repeat(longestName - test.length + 2)}`); 97 | 98 | const schema = await readFile(path.join(test, "schema.prisma")); 99 | if (!schema) { 100 | throw new Error(`Test ${test} has no schema.prisma!`); 101 | } 102 | 103 | let expectedError = await readFile(path.join(test, "expected-error.txt")); 104 | const typeTester = await validPath(path.join(test, "test-types.ts")); 105 | 106 | const expectedFiles: Map = new Map(); 107 | for (const entry of await readDir(path.join(test, "expected"))) { 108 | if (entry.isFile()) { 109 | expectedFiles.set(entry.name, await readFile(path.join(test, "expected", entry.name))); 110 | } 111 | } 112 | 113 | if (expectedFiles.size === 0 && !expectedError && !typeTester) { 114 | throw new Error(`Test ${test} has no expected files or errors!`); 115 | } 116 | 117 | const testDir = path.join(test, TEMP_TEST_DIRNAME); 118 | await rimraf(testDir); // Ensure test dir is clean before running 119 | await fs.mkdir(testDir, { recursive: true }); 120 | await fs.writeFile(path.join(testDir, "schema.prisma"), schema); 121 | 122 | try { 123 | await execAsync(`prisma generate --schema=${path.join(testDir, "schema.prisma")}`); 124 | } catch (e) { 125 | const error = e as { code: number; stdout: string; stderr: string }; 126 | if (expectedError && trimMultiLine(error.stderr) === trimMultiLine(expectedError)) { 127 | // Expected error occurred, set expectedError to null so we don't throw later 128 | expectedError = null; 129 | } else if (expectedError) { 130 | throw new Error("Stderr does not match expected error! Stderr:\n\n" + error.stderr); 131 | } else { 132 | throw new Error("Error running Prisma! Stderr:\n\n" + error.stderr); 133 | } 134 | } 135 | 136 | if (expectedError) { 137 | throw new Error("Expected error did not occur!"); 138 | } 139 | 140 | if (typeTester) { 141 | try { 142 | await execAsync(`tsc --pretty --noEmit --strict --module NodeNext ${typeTester}`); 143 | } catch (e) { 144 | const error = e as { code: number; stdout: string; stderr: string }; 145 | throw new Error( 146 | `Error validating types! tsc exited with code ${error.code}:\n\n${error.stdout}`, 147 | ); 148 | } 149 | } 150 | 151 | const errors: string[] = []; 152 | const uncheckedFileNames = new Set(expectedFiles.keys()); 153 | 154 | for (const entry of await readDir(testDir)) { 155 | if (!entry.isFile() || entry.name === "schema.prisma") { 156 | continue; 157 | } 158 | 159 | uncheckedFileNames.delete(entry.name); 160 | 161 | const filePath = path.join(testDir, entry.name); 162 | const fileContents = await readFile(filePath); 163 | const expectedContents = expectedFiles.get(entry.name); 164 | 165 | if (!expectedContents) { 166 | errors.push(`Unexpected file ${entry.name} in test output! See ${filePath}`); 167 | continue; 168 | } 169 | 170 | if (fileContents !== expectedContents) { 171 | errors.push( 172 | `Generated ${entry.name} does not match expected contents! Check the output in ${filePath}`, 173 | ); 174 | } 175 | } 176 | 177 | for (const file of uncheckedFileNames) { 178 | errors.push(`Expected file ${file} was not generated!`); 179 | } 180 | 181 | if (errors.length) { 182 | throw new Error("Errors:\n" + errors.map((e) => ` - ${e}`).join("\n")); 183 | } 184 | 185 | process.stdout.write(GREEN + " PASS " + RESET + "\n"); 186 | 187 | if (!keepOutput) { 188 | await rimraf(testDir); // Clean up test dir on success 189 | } 190 | } catch (e) { 191 | process.stdout.write(RED + " FAIL " + RESET + "\n\n"); 192 | console.error((e as Error).message, "\n"); 193 | hasErrors = true; 194 | } 195 | } 196 | 197 | if (hasErrors) { 198 | console.error("\nSome tests failed!"); 199 | process.exit(1); 200 | } else { 201 | console.log("\nAll tests passed!"); 202 | } 203 | -------------------------------------------------------------------------------- /tests/mongo-types/expected/mongoModelType.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type PhotoType = "Selfie" | "Profile" | "Tagged"; 6 | 7 | export type Person = { 8 | id: number; 9 | name: string; 10 | gender: Gender; 11 | addressId: number; 12 | address?: Address; 13 | photos: Photo[]; 14 | tags: Tag | null; 15 | }; 16 | 17 | export type Address = { 18 | id: number; 19 | addressText: string; 20 | people?: Person[]; 21 | }; 22 | 23 | export type Photo = { 24 | height: number; 25 | Width: number; 26 | url: string; 27 | type: PhotoType; 28 | }; 29 | 30 | export type Tag = { 31 | id: number; 32 | name: string; 33 | }; 34 | -------------------------------------------------------------------------------- /tests/mongo-types/expected/mongoOmitRelations.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type PhotoType = "Selfie" | "Profile" | "Tagged"; 6 | 7 | export interface Person { 8 | id: number; 9 | name: string; 10 | gender: Gender; 11 | addressId: number; 12 | photos: Photo[]; 13 | tags: Tag | null; 14 | } 15 | 16 | export interface Address { 17 | id: number; 18 | addressText: string; 19 | } 20 | 21 | export interface Photo { 22 | height: number; 23 | Width: number; 24 | url: string; 25 | type: PhotoType; 26 | } 27 | 28 | export interface Tag { 29 | id: number; 30 | name: string; 31 | } 32 | -------------------------------------------------------------------------------- /tests/mongo-types/expected/mongoTypes.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type PhotoType = "Selfie" | "Profile" | "Tagged"; 6 | 7 | export interface Person { 8 | id: number; 9 | name: string; 10 | gender: Gender; 11 | addressId: number; 12 | address?: Address; 13 | photos: Photo[]; 14 | tags: Tag | null; 15 | } 16 | 17 | export interface Address { 18 | id: number; 19 | addressText: string; 20 | people?: Person[]; 21 | } 22 | 23 | export interface Photo { 24 | height: number; 25 | Width: number; 26 | url: string; 27 | type: PhotoType; 28 | } 29 | 30 | export interface Tag { 31 | id: number; 32 | name: string; 33 | } 34 | -------------------------------------------------------------------------------- /tests/mongo-types/expected/prefixSuffix.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type PhotoType = "Selfie" | "Profile" | "Tagged"; 6 | 7 | export interface Person { 8 | id: number; 9 | name: string; 10 | gender: Gender; 11 | addressId: number; 12 | address?: Address; 13 | photos: typePhotoType[]; 14 | tags: typeTagType | null; 15 | } 16 | 17 | export interface Address { 18 | id: number; 19 | addressText: string; 20 | people?: Person[]; 21 | } 22 | 23 | export interface typePhotoType { 24 | height: number; 25 | Width: number; 26 | url: string; 27 | type: PhotoType; 28 | } 29 | 30 | export interface typeTagType { 31 | id: number; 32 | name: string; 33 | } 34 | -------------------------------------------------------------------------------- /tests/mongo-types/schema.prisma: -------------------------------------------------------------------------------- 1 | // Test against mongodb schema to allow testing composite types 2 | // https://www.prisma.io/docs/concepts/components/prisma-schema/data-model#defining-composite-types 3 | 4 | // ======================== 5 | // Generator Tests 6 | // ======================== 7 | 8 | generator mongoTypes { 9 | provider = "tsx generator.ts" 10 | output = "mongoTypes.ts" 11 | } 12 | 13 | // Ensure modelType = "type" also applies to `type` definitions 14 | generator mongoModelType { 15 | provider = "tsx generator.ts" 16 | output = "mongoModelType.ts" 17 | modelType = "type" 18 | } 19 | 20 | // Ensure omitRelations does not apply to `type` definitions (since they always exist on the object) 21 | generator mongoOmitRelations { 22 | provider = "tsx generator.ts" 23 | output = "mongoOmitRelations.ts" 24 | omitRelations = true 25 | } 26 | 27 | generator prefixSuffix { 28 | provider = "tsx generator.ts" 29 | output = "prefixSuffix.ts" 30 | typePrefix = "type" 31 | typeSuffix = "Type" 32 | } 33 | 34 | // ======================== 35 | // Prisma Schema 36 | // ======================== 37 | 38 | datasource db { 39 | provider = "mongodb" 40 | url = "" 41 | } 42 | 43 | enum Gender { 44 | Male 45 | Female 46 | Other 47 | } 48 | 49 | enum PhotoType { 50 | Selfie 51 | Profile 52 | Tagged 53 | } 54 | 55 | model Person { 56 | id Int @id @map("_id") 57 | name String 58 | gender Gender 59 | addressId Int 60 | address Address @relation(fields: [addressId], references: [id]) 61 | photos Photo[] 62 | tags Tag? 63 | } 64 | 65 | model Address { 66 | id Int @id @map("_id") 67 | addressText String 68 | people Person[] 69 | } 70 | 71 | type Photo { 72 | height Int 73 | Width Int 74 | url String 75 | type PhotoType 76 | } 77 | 78 | type Tag { 79 | id Int 80 | name String 81 | } 82 | -------------------------------------------------------------------------------- /tests/no-custom-types/expected/interfaces.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export interface User { 4 | id: string; 5 | name: string; 6 | email: string; 7 | createdAt: Date; 8 | updatedAt: Date; 9 | } 10 | -------------------------------------------------------------------------------- /tests/no-custom-types/schema.prisma: -------------------------------------------------------------------------------- 1 | // Test against a basic Prisma schema which does not use any types requiring custom type definitions 2 | // in the output (like Decimal or Json), to ensure that such definitions are omitted. 3 | 4 | // ======================== 5 | // Generator Tests 6 | // ======================== 7 | 8 | generator typescriptInterfaces { 9 | provider = "tsx generator.ts" 10 | } 11 | 12 | // ======================== 13 | // Prisma Schema 14 | // ======================== 15 | 16 | datasource db { 17 | provider = "postgresql" 18 | url = "" 19 | } 20 | 21 | model User { 22 | id String @id @default(cuid()) 23 | name String 24 | email String @unique 25 | createdAt DateTime @default(now()) 26 | updatedAt DateTime @updatedAt 27 | } 28 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/bytesArrayObject.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 6 | 7 | export interface Person { 8 | id: number; 9 | name: string; 10 | age: number; 11 | email: string | null; 12 | gender: Gender; 13 | addressId: number; 14 | address?: Address; 15 | friends?: Person[]; 16 | friendsOf?: Person[]; 17 | data?: Data | null; 18 | } 19 | 20 | export interface Address { 21 | id: number; 22 | streetNumber: number; 23 | streetName: string; 24 | city: string; 25 | isBilling: boolean; 26 | people?: Person[]; 27 | } 28 | 29 | export interface Data { 30 | id: string; 31 | stringField: string; 32 | booleanField: boolean; 33 | intField: number; 34 | bigIntField: bigint; 35 | floatField: number; 36 | decimalField: Decimal; 37 | dateField: Date; 38 | jsonField: JsonValue; 39 | bytesField: ArrayObject; 40 | enumField: DataTest; 41 | optionalStringField: string | null; 42 | optionalBooleanField: boolean | null; 43 | optionalIntField: number | null; 44 | optionalBigIntField: bigint | null; 45 | optionalFloatField: number | null; 46 | optionalDecimalField: Decimal | null; 47 | optionalDateField: Date | null; 48 | optionalJsonField: JsonValue | null; 49 | optionalBytesField: ArrayObject | null; 50 | optionalEnumField: DataTest | null; 51 | stringArrayField: string[]; 52 | booleanArrayField: boolean[]; 53 | intArrayField: number[]; 54 | bigIntArrayField: bigint[]; 55 | floatArrayField: number[]; 56 | decimalArrayField: Decimal[]; 57 | dateArrayField: Date[]; 58 | jsonArrayField: JsonValue[]; 59 | bytesArrayField: ArrayObject[]; 60 | enumArrayField: DataTest[]; 61 | personId: number; 62 | person?: Person; 63 | } 64 | 65 | type Decimal = { valueOf(): string }; 66 | 67 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 68 | 69 | type ArrayObject = { [index: number]: number } & { length?: never }; 70 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/bytesBuffer.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 6 | 7 | export interface Person { 8 | id: number; 9 | name: string; 10 | age: number; 11 | email: string | null; 12 | gender: Gender; 13 | addressId: number; 14 | address?: Address; 15 | friends?: Person[]; 16 | friendsOf?: Person[]; 17 | data?: Data | null; 18 | } 19 | 20 | export interface Address { 21 | id: number; 22 | streetNumber: number; 23 | streetName: string; 24 | city: string; 25 | isBilling: boolean; 26 | people?: Person[]; 27 | } 28 | 29 | export interface Data { 30 | id: string; 31 | stringField: string; 32 | booleanField: boolean; 33 | intField: number; 34 | bigIntField: bigint; 35 | floatField: number; 36 | decimalField: Decimal; 37 | dateField: Date; 38 | jsonField: JsonValue; 39 | bytesField: Buffer; 40 | enumField: DataTest; 41 | optionalStringField: string | null; 42 | optionalBooleanField: boolean | null; 43 | optionalIntField: number | null; 44 | optionalBigIntField: bigint | null; 45 | optionalFloatField: number | null; 46 | optionalDecimalField: Decimal | null; 47 | optionalDateField: Date | null; 48 | optionalJsonField: JsonValue | null; 49 | optionalBytesField: Buffer | null; 50 | optionalEnumField: DataTest | null; 51 | stringArrayField: string[]; 52 | booleanArrayField: boolean[]; 53 | intArrayField: number[]; 54 | bigIntArrayField: bigint[]; 55 | floatArrayField: number[]; 56 | decimalArrayField: Decimal[]; 57 | dateArrayField: Date[]; 58 | jsonArrayField: JsonValue[]; 59 | bytesArrayField: Buffer[]; 60 | enumArrayField: DataTest[]; 61 | personId: number; 62 | person?: Person; 63 | } 64 | 65 | type Decimal = { valueOf(): string }; 66 | 67 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 68 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/bytesBufferObject.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 6 | 7 | export interface Person { 8 | id: number; 9 | name: string; 10 | age: number; 11 | email: string | null; 12 | gender: Gender; 13 | addressId: number; 14 | address?: Address; 15 | friends?: Person[]; 16 | friendsOf?: Person[]; 17 | data?: Data | null; 18 | } 19 | 20 | export interface Address { 21 | id: number; 22 | streetNumber: number; 23 | streetName: string; 24 | city: string; 25 | isBilling: boolean; 26 | people?: Person[]; 27 | } 28 | 29 | export interface Data { 30 | id: string; 31 | stringField: string; 32 | booleanField: boolean; 33 | intField: number; 34 | bigIntField: bigint; 35 | floatField: number; 36 | decimalField: Decimal; 37 | dateField: Date; 38 | jsonField: JsonValue; 39 | bytesField: BufferObject; 40 | enumField: DataTest; 41 | optionalStringField: string | null; 42 | optionalBooleanField: boolean | null; 43 | optionalIntField: number | null; 44 | optionalBigIntField: bigint | null; 45 | optionalFloatField: number | null; 46 | optionalDecimalField: Decimal | null; 47 | optionalDateField: Date | null; 48 | optionalJsonField: JsonValue | null; 49 | optionalBytesField: BufferObject | null; 50 | optionalEnumField: DataTest | null; 51 | stringArrayField: string[]; 52 | booleanArrayField: boolean[]; 53 | intArrayField: number[]; 54 | bigIntArrayField: bigint[]; 55 | floatArrayField: number[]; 56 | decimalArrayField: Decimal[]; 57 | dateArrayField: Date[]; 58 | jsonArrayField: JsonValue[]; 59 | bytesArrayField: BufferObject[]; 60 | enumArrayField: DataTest[]; 61 | personId: number; 62 | person?: Person; 63 | } 64 | 65 | type Decimal = { valueOf(): string }; 66 | 67 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 68 | 69 | type BufferObject = { type: "Buffer"; data: number[] }; 70 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/customHeader.ts: -------------------------------------------------------------------------------- 1 | // This is a custom header 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 6 | 7 | export interface Person { 8 | id: number; 9 | name: string; 10 | age: number; 11 | email: string | null; 12 | gender: Gender; 13 | addressId: number; 14 | address?: Address; 15 | friends?: Person[]; 16 | friendsOf?: Person[]; 17 | data?: Data | null; 18 | } 19 | 20 | export interface Address { 21 | id: number; 22 | streetNumber: number; 23 | streetName: string; 24 | city: string; 25 | isBilling: boolean; 26 | people?: Person[]; 27 | } 28 | 29 | export interface Data { 30 | id: string; 31 | stringField: string; 32 | booleanField: boolean; 33 | intField: number; 34 | bigIntField: bigint; 35 | floatField: number; 36 | decimalField: Decimal; 37 | dateField: Date; 38 | jsonField: JsonValue; 39 | bytesField: Uint8Array; 40 | enumField: DataTest; 41 | optionalStringField: string | null; 42 | optionalBooleanField: boolean | null; 43 | optionalIntField: number | null; 44 | optionalBigIntField: bigint | null; 45 | optionalFloatField: number | null; 46 | optionalDecimalField: Decimal | null; 47 | optionalDateField: Date | null; 48 | optionalJsonField: JsonValue | null; 49 | optionalBytesField: Uint8Array | null; 50 | optionalEnumField: DataTest | null; 51 | stringArrayField: string[]; 52 | booleanArrayField: boolean[]; 53 | intArrayField: number[]; 54 | bigIntArrayField: bigint[]; 55 | floatArrayField: number[]; 56 | decimalArrayField: Decimal[]; 57 | dateArrayField: Date[]; 58 | jsonArrayField: JsonValue[]; 59 | bytesArrayField: Uint8Array[]; 60 | enumArrayField: DataTest[]; 61 | personId: number; 62 | person?: Person; 63 | } 64 | 65 | type Decimal = { valueOf(): string }; 66 | 67 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 68 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/customOutput.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 6 | 7 | export interface Person { 8 | id: number; 9 | name: string; 10 | age: number; 11 | email: string | null; 12 | gender: Gender; 13 | addressId: number; 14 | address?: Address; 15 | friends?: Person[]; 16 | friendsOf?: Person[]; 17 | data?: Data | null; 18 | } 19 | 20 | export interface Address { 21 | id: number; 22 | streetNumber: number; 23 | streetName: string; 24 | city: string; 25 | isBilling: boolean; 26 | people?: Person[]; 27 | } 28 | 29 | export interface Data { 30 | id: string; 31 | stringField: string; 32 | booleanField: boolean; 33 | intField: number; 34 | bigIntField: bigint; 35 | floatField: number; 36 | decimalField: Decimal; 37 | dateField: Date; 38 | jsonField: JsonValue; 39 | bytesField: Uint8Array; 40 | enumField: DataTest; 41 | optionalStringField: string | null; 42 | optionalBooleanField: boolean | null; 43 | optionalIntField: number | null; 44 | optionalBigIntField: bigint | null; 45 | optionalFloatField: number | null; 46 | optionalDecimalField: Decimal | null; 47 | optionalDateField: Date | null; 48 | optionalJsonField: JsonValue | null; 49 | optionalBytesField: Uint8Array | null; 50 | optionalEnumField: DataTest | null; 51 | stringArrayField: string[]; 52 | booleanArrayField: boolean[]; 53 | intArrayField: number[]; 54 | bigIntArrayField: bigint[]; 55 | floatArrayField: number[]; 56 | decimalArrayField: Decimal[]; 57 | dateArrayField: Date[]; 58 | jsonArrayField: JsonValue[]; 59 | bytesArrayField: Uint8Array[]; 60 | enumArrayField: DataTest[]; 61 | personId: number; 62 | person?: Person; 63 | } 64 | 65 | type Decimal = { valueOf(): string }; 66 | 67 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 68 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/defaultsSpecified.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 6 | 7 | export interface Person { 8 | id: number; 9 | name: string; 10 | age: number; 11 | email: string | null; 12 | gender: Gender; 13 | addressId: number; 14 | address?: Address; 15 | friends?: Person[]; 16 | friendsOf?: Person[]; 17 | data?: Data | null; 18 | } 19 | 20 | export interface Address { 21 | id: number; 22 | streetNumber: number; 23 | streetName: string; 24 | city: string; 25 | isBilling: boolean; 26 | people?: Person[]; 27 | } 28 | 29 | export interface Data { 30 | id: string; 31 | stringField: string; 32 | booleanField: boolean; 33 | intField: number; 34 | bigIntField: bigint; 35 | floatField: number; 36 | decimalField: Decimal; 37 | dateField: Date; 38 | jsonField: JsonValue; 39 | bytesField: Uint8Array; 40 | enumField: DataTest; 41 | optionalStringField: string | null; 42 | optionalBooleanField: boolean | null; 43 | optionalIntField: number | null; 44 | optionalBigIntField: bigint | null; 45 | optionalFloatField: number | null; 46 | optionalDecimalField: Decimal | null; 47 | optionalDateField: Date | null; 48 | optionalJsonField: JsonValue | null; 49 | optionalBytesField: Uint8Array | null; 50 | optionalEnumField: DataTest | null; 51 | stringArrayField: string[]; 52 | booleanArrayField: boolean[]; 53 | intArrayField: number[]; 54 | bigIntArrayField: bigint[]; 55 | floatArrayField: number[]; 56 | decimalArrayField: Decimal[]; 57 | dateArrayField: Date[]; 58 | jsonArrayField: JsonValue[]; 59 | bytesArrayField: Uint8Array[]; 60 | enumArrayField: DataTest[]; 61 | personId: number; 62 | person?: Person; 63 | } 64 | 65 | type Decimal = { valueOf(): string }; 66 | 67 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 68 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/enumExportFalse.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | enum Gender { 4 | Male = "Male", 5 | Female = "Female", 6 | Other = "Other" 7 | } 8 | 9 | enum DataTest { 10 | Apple = "Apple", 11 | Banana = "Banana", 12 | Orange = "Orange", 13 | Pear = "Pear" 14 | } 15 | 16 | export interface Person { 17 | id: number; 18 | name: string; 19 | age: number; 20 | email: string | null; 21 | gender: Gender; 22 | addressId: number; 23 | address?: Address; 24 | friends?: Person[]; 25 | friendsOf?: Person[]; 26 | data?: Data | null; 27 | } 28 | 29 | export interface Address { 30 | id: number; 31 | streetNumber: number; 32 | streetName: string; 33 | city: string; 34 | isBilling: boolean; 35 | people?: Person[]; 36 | } 37 | 38 | export interface Data { 39 | id: string; 40 | stringField: string; 41 | booleanField: boolean; 42 | intField: number; 43 | bigIntField: bigint; 44 | floatField: number; 45 | decimalField: Decimal; 46 | dateField: Date; 47 | jsonField: JsonValue; 48 | bytesField: Uint8Array; 49 | enumField: DataTest; 50 | optionalStringField: string | null; 51 | optionalBooleanField: boolean | null; 52 | optionalIntField: number | null; 53 | optionalBigIntField: bigint | null; 54 | optionalFloatField: number | null; 55 | optionalDecimalField: Decimal | null; 56 | optionalDateField: Date | null; 57 | optionalJsonField: JsonValue | null; 58 | optionalBytesField: Uint8Array | null; 59 | optionalEnumField: DataTest | null; 60 | stringArrayField: string[]; 61 | booleanArrayField: boolean[]; 62 | intArrayField: number[]; 63 | bigIntArrayField: bigint[]; 64 | floatArrayField: number[]; 65 | decimalArrayField: Decimal[]; 66 | dateArrayField: Date[]; 67 | jsonArrayField: JsonValue[]; 68 | bytesArrayField: Uint8Array[]; 69 | enumArrayField: DataTest[]; 70 | personId: number; 71 | person?: Person; 72 | } 73 | 74 | type Decimal = { valueOf(): string }; 75 | 76 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 77 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/enumExportFalseTypeObject.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | type Gender = "Male" | "Female" | "Other"; 4 | 5 | const Gender = { 6 | Male: "Male", 7 | Female: "Female", 8 | Other: "Other" 9 | } satisfies Record; 10 | 11 | type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 12 | 13 | const DataTest = { 14 | Apple: "Apple", 15 | Banana: "Banana", 16 | Orange: "Orange", 17 | Pear: "Pear" 18 | } satisfies Record; 19 | 20 | export interface Person { 21 | id: number; 22 | name: string; 23 | age: number; 24 | email: string | null; 25 | gender: Gender; 26 | addressId: number; 27 | address?: Address; 28 | friends?: Person[]; 29 | friendsOf?: Person[]; 30 | data?: Data | null; 31 | } 32 | 33 | export interface Address { 34 | id: number; 35 | streetNumber: number; 36 | streetName: string; 37 | city: string; 38 | isBilling: boolean; 39 | people?: Person[]; 40 | } 41 | 42 | export interface Data { 43 | id: string; 44 | stringField: string; 45 | booleanField: boolean; 46 | intField: number; 47 | bigIntField: bigint; 48 | floatField: number; 49 | decimalField: Decimal; 50 | dateField: Date; 51 | jsonField: JsonValue; 52 | bytesField: Uint8Array; 53 | enumField: DataTest; 54 | optionalStringField: string | null; 55 | optionalBooleanField: boolean | null; 56 | optionalIntField: number | null; 57 | optionalBigIntField: bigint | null; 58 | optionalFloatField: number | null; 59 | optionalDecimalField: Decimal | null; 60 | optionalDateField: Date | null; 61 | optionalJsonField: JsonValue | null; 62 | optionalBytesField: Uint8Array | null; 63 | optionalEnumField: DataTest | null; 64 | stringArrayField: string[]; 65 | booleanArrayField: boolean[]; 66 | intArrayField: number[]; 67 | bigIntArrayField: bigint[]; 68 | floatArrayField: number[]; 69 | decimalArrayField: Decimal[]; 70 | dateArrayField: Date[]; 71 | jsonArrayField: JsonValue[]; 72 | bytesArrayField: Uint8Array[]; 73 | enumArrayField: DataTest[]; 74 | personId: number; 75 | person?: Person; 76 | } 77 | 78 | type Decimal = { valueOf(): string }; 79 | 80 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 81 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/enumType.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export enum Gender { 4 | Male = "Male", 5 | Female = "Female", 6 | Other = "Other" 7 | } 8 | 9 | export enum DataTest { 10 | Apple = "Apple", 11 | Banana = "Banana", 12 | Orange = "Orange", 13 | Pear = "Pear" 14 | } 15 | 16 | export interface Person { 17 | id: number; 18 | name: string; 19 | age: number; 20 | email: string | null; 21 | gender: Gender; 22 | addressId: number; 23 | address?: Address; 24 | friends?: Person[]; 25 | friendsOf?: Person[]; 26 | data?: Data | null; 27 | } 28 | 29 | export interface Address { 30 | id: number; 31 | streetNumber: number; 32 | streetName: string; 33 | city: string; 34 | isBilling: boolean; 35 | people?: Person[]; 36 | } 37 | 38 | export interface Data { 39 | id: string; 40 | stringField: string; 41 | booleanField: boolean; 42 | intField: number; 43 | bigIntField: bigint; 44 | floatField: number; 45 | decimalField: Decimal; 46 | dateField: Date; 47 | jsonField: JsonValue; 48 | bytesField: Uint8Array; 49 | enumField: DataTest; 50 | optionalStringField: string | null; 51 | optionalBooleanField: boolean | null; 52 | optionalIntField: number | null; 53 | optionalBigIntField: bigint | null; 54 | optionalFloatField: number | null; 55 | optionalDecimalField: Decimal | null; 56 | optionalDateField: Date | null; 57 | optionalJsonField: JsonValue | null; 58 | optionalBytesField: Uint8Array | null; 59 | optionalEnumField: DataTest | null; 60 | stringArrayField: string[]; 61 | booleanArrayField: boolean[]; 62 | intArrayField: number[]; 63 | bigIntArrayField: bigint[]; 64 | floatArrayField: number[]; 65 | decimalArrayField: Decimal[]; 66 | dateArrayField: Date[]; 67 | jsonArrayField: JsonValue[]; 68 | bytesArrayField: Uint8Array[]; 69 | enumArrayField: DataTest[]; 70 | personId: number; 71 | person?: Person; 72 | } 73 | 74 | type Decimal = { valueOf(): string }; 75 | 76 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 77 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/enumTypeObject.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export const Gender = { 6 | Male: "Male", 7 | Female: "Female", 8 | Other: "Other" 9 | } satisfies Record; 10 | 11 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 12 | 13 | export const DataTest = { 14 | Apple: "Apple", 15 | Banana: "Banana", 16 | Orange: "Orange", 17 | Pear: "Pear" 18 | } satisfies Record; 19 | 20 | export interface Person { 21 | id: number; 22 | name: string; 23 | age: number; 24 | email: string | null; 25 | gender: Gender; 26 | addressId: number; 27 | address?: Address; 28 | friends?: Person[]; 29 | friendsOf?: Person[]; 30 | data?: Data | null; 31 | } 32 | 33 | export interface Address { 34 | id: number; 35 | streetNumber: number; 36 | streetName: string; 37 | city: string; 38 | isBilling: boolean; 39 | people?: Person[]; 40 | } 41 | 42 | export interface Data { 43 | id: string; 44 | stringField: string; 45 | booleanField: boolean; 46 | intField: number; 47 | bigIntField: bigint; 48 | floatField: number; 49 | decimalField: Decimal; 50 | dateField: Date; 51 | jsonField: JsonValue; 52 | bytesField: Uint8Array; 53 | enumField: DataTest; 54 | optionalStringField: string | null; 55 | optionalBooleanField: boolean | null; 56 | optionalIntField: number | null; 57 | optionalBigIntField: bigint | null; 58 | optionalFloatField: number | null; 59 | optionalDecimalField: Decimal | null; 60 | optionalDateField: Date | null; 61 | optionalJsonField: JsonValue | null; 62 | optionalBytesField: Uint8Array | null; 63 | optionalEnumField: DataTest | null; 64 | stringArrayField: string[]; 65 | booleanArrayField: boolean[]; 66 | intArrayField: number[]; 67 | bigIntArrayField: bigint[]; 68 | floatArrayField: number[]; 69 | decimalArrayField: Decimal[]; 70 | dateArrayField: Date[]; 71 | jsonArrayField: JsonValue[]; 72 | bytesArrayField: Uint8Array[]; 73 | enumArrayField: DataTest[]; 74 | personId: number; 75 | person?: Person; 76 | } 77 | 78 | type Decimal = { valueOf(): string }; 79 | 80 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 81 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/enumTypeObjectPrefixSuffix.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type eGenderEnum = "Male" | "Female" | "Other"; 4 | 5 | export const eGenderEnum = { 6 | Male: "Male", 7 | Female: "Female", 8 | Other: "Other" 9 | } satisfies Record; 10 | 11 | export type eDataTestEnum = "Apple" | "Banana" | "Orange" | "Pear"; 12 | 13 | export const eDataTestEnum = { 14 | Apple: "Apple", 15 | Banana: "Banana", 16 | Orange: "Orange", 17 | Pear: "Pear" 18 | } satisfies Record; 19 | 20 | export interface Person { 21 | id: number; 22 | name: string; 23 | age: number; 24 | email: string | null; 25 | gender: eGenderEnum; 26 | addressId: number; 27 | address?: Address; 28 | friends?: Person[]; 29 | friendsOf?: Person[]; 30 | data?: Data | null; 31 | } 32 | 33 | export interface Address { 34 | id: number; 35 | streetNumber: number; 36 | streetName: string; 37 | city: string; 38 | isBilling: boolean; 39 | people?: Person[]; 40 | } 41 | 42 | export interface Data { 43 | id: string; 44 | stringField: string; 45 | booleanField: boolean; 46 | intField: number; 47 | bigIntField: bigint; 48 | floatField: number; 49 | decimalField: Decimal; 50 | dateField: Date; 51 | jsonField: JsonValue; 52 | bytesField: Uint8Array; 53 | enumField: eDataTestEnum; 54 | optionalStringField: string | null; 55 | optionalBooleanField: boolean | null; 56 | optionalIntField: number | null; 57 | optionalBigIntField: bigint | null; 58 | optionalFloatField: number | null; 59 | optionalDecimalField: Decimal | null; 60 | optionalDateField: Date | null; 61 | optionalJsonField: JsonValue | null; 62 | optionalBytesField: Uint8Array | null; 63 | optionalEnumField: eDataTestEnum | null; 64 | stringArrayField: string[]; 65 | booleanArrayField: boolean[]; 66 | intArrayField: number[]; 67 | bigIntArrayField: bigint[]; 68 | floatArrayField: number[]; 69 | decimalArrayField: Decimal[]; 70 | dateArrayField: Date[]; 71 | jsonArrayField: JsonValue[]; 72 | bytesArrayField: Uint8Array[]; 73 | enumArrayField: eDataTestEnum[]; 74 | personId: number; 75 | person?: Person; 76 | } 77 | 78 | type Decimal = { valueOf(): string }; 79 | 80 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 81 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/enumTypeObjectValuePrefixSuffix.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type eGenderEnum = "Male" | "Female" | "Other"; 4 | 5 | export const $eGenderEnumObj = { 6 | Male: "Male", 7 | Female: "Female", 8 | Other: "Other" 9 | } satisfies Record; 10 | 11 | export type eDataTestEnum = "Apple" | "Banana" | "Orange" | "Pear"; 12 | 13 | export const $eDataTestEnumObj = { 14 | Apple: "Apple", 15 | Banana: "Banana", 16 | Orange: "Orange", 17 | Pear: "Pear" 18 | } satisfies Record; 19 | 20 | export interface Person { 21 | id: number; 22 | name: string; 23 | age: number; 24 | email: string | null; 25 | gender: eGenderEnum; 26 | addressId: number; 27 | address?: Address; 28 | friends?: Person[]; 29 | friendsOf?: Person[]; 30 | data?: Data | null; 31 | } 32 | 33 | export interface Address { 34 | id: number; 35 | streetNumber: number; 36 | streetName: string; 37 | city: string; 38 | isBilling: boolean; 39 | people?: Person[]; 40 | } 41 | 42 | export interface Data { 43 | id: string; 44 | stringField: string; 45 | booleanField: boolean; 46 | intField: number; 47 | bigIntField: bigint; 48 | floatField: number; 49 | decimalField: Decimal; 50 | dateField: Date; 51 | jsonField: JsonValue; 52 | bytesField: Uint8Array; 53 | enumField: eDataTestEnum; 54 | optionalStringField: string | null; 55 | optionalBooleanField: boolean | null; 56 | optionalIntField: number | null; 57 | optionalBigIntField: bigint | null; 58 | optionalFloatField: number | null; 59 | optionalDecimalField: Decimal | null; 60 | optionalDateField: Date | null; 61 | optionalJsonField: JsonValue | null; 62 | optionalBytesField: Uint8Array | null; 63 | optionalEnumField: eDataTestEnum | null; 64 | stringArrayField: string[]; 65 | booleanArrayField: boolean[]; 66 | intArrayField: number[]; 67 | bigIntArrayField: bigint[]; 68 | floatArrayField: number[]; 69 | decimalArrayField: Decimal[]; 70 | dateArrayField: Date[]; 71 | jsonArrayField: JsonValue[]; 72 | bytesArrayField: Uint8Array[]; 73 | enumArrayField: eDataTestEnum[]; 74 | personId: number; 75 | person?: Person; 76 | } 77 | 78 | type Decimal = { valueOf(): string }; 79 | 80 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 81 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/enumTypePrefixSuffix.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export enum eGenderEnum { 4 | Male = "Male", 5 | Female = "Female", 6 | Other = "Other" 7 | } 8 | 9 | export enum eDataTestEnum { 10 | Apple = "Apple", 11 | Banana = "Banana", 12 | Orange = "Orange", 13 | Pear = "Pear" 14 | } 15 | 16 | export interface Person { 17 | id: number; 18 | name: string; 19 | age: number; 20 | email: string | null; 21 | gender: eGenderEnum; 22 | addressId: number; 23 | address?: Address; 24 | friends?: Person[]; 25 | friendsOf?: Person[]; 26 | data?: Data | null; 27 | } 28 | 29 | export interface Address { 30 | id: number; 31 | streetNumber: number; 32 | streetName: string; 33 | city: string; 34 | isBilling: boolean; 35 | people?: Person[]; 36 | } 37 | 38 | export interface Data { 39 | id: string; 40 | stringField: string; 41 | booleanField: boolean; 42 | intField: number; 43 | bigIntField: bigint; 44 | floatField: number; 45 | decimalField: Decimal; 46 | dateField: Date; 47 | jsonField: JsonValue; 48 | bytesField: Uint8Array; 49 | enumField: eDataTestEnum; 50 | optionalStringField: string | null; 51 | optionalBooleanField: boolean | null; 52 | optionalIntField: number | null; 53 | optionalBigIntField: bigint | null; 54 | optionalFloatField: number | null; 55 | optionalDecimalField: Decimal | null; 56 | optionalDateField: Date | null; 57 | optionalJsonField: JsonValue | null; 58 | optionalBytesField: Uint8Array | null; 59 | optionalEnumField: eDataTestEnum | null; 60 | stringArrayField: string[]; 61 | booleanArrayField: boolean[]; 62 | intArrayField: number[]; 63 | bigIntArrayField: bigint[]; 64 | floatArrayField: number[]; 65 | decimalArrayField: Decimal[]; 66 | dateArrayField: Date[]; 67 | jsonArrayField: JsonValue[]; 68 | bytesArrayField: Uint8Array[]; 69 | enumArrayField: eDataTestEnum[]; 70 | personId: number; 71 | person?: Person; 72 | } 73 | 74 | type Decimal = { valueOf(): string }; 75 | 76 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 77 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/formatPrettier.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 6 | 7 | export interface Person { 8 | id: number; 9 | name: string; 10 | age: number; 11 | email: string | null; 12 | gender: Gender; 13 | addressId: number; 14 | address?: Address; 15 | friends?: Person[]; 16 | friendsOf?: Person[]; 17 | data?: Data | null; 18 | } 19 | 20 | export interface Address { 21 | id: number; 22 | streetNumber: number; 23 | streetName: string; 24 | city: string; 25 | isBilling: boolean; 26 | people?: Person[]; 27 | } 28 | 29 | export interface Data { 30 | id: string; 31 | stringField: string; 32 | booleanField: boolean; 33 | intField: number; 34 | bigIntField: bigint; 35 | floatField: number; 36 | decimalField: Decimal; 37 | dateField: Date; 38 | jsonField: JsonValue; 39 | bytesField: Uint8Array; 40 | enumField: DataTest; 41 | optionalStringField: string | null; 42 | optionalBooleanField: boolean | null; 43 | optionalIntField: number | null; 44 | optionalBigIntField: bigint | null; 45 | optionalFloatField: number | null; 46 | optionalDecimalField: Decimal | null; 47 | optionalDateField: Date | null; 48 | optionalJsonField: JsonValue | null; 49 | optionalBytesField: Uint8Array | null; 50 | optionalEnumField: DataTest | null; 51 | stringArrayField: string[]; 52 | booleanArrayField: boolean[]; 53 | intArrayField: number[]; 54 | bigIntArrayField: bigint[]; 55 | floatArrayField: number[]; 56 | decimalArrayField: Decimal[]; 57 | dateArrayField: Date[]; 58 | jsonArrayField: JsonValue[]; 59 | bytesArrayField: Uint8Array[]; 60 | enumArrayField: DataTest[]; 61 | personId: number; 62 | person?: Person; 63 | } 64 | 65 | type Decimal = { valueOf(): string }; 66 | 67 | type JsonValue = 68 | | string 69 | | number 70 | | boolean 71 | | { [key in string]?: JsonValue } 72 | | Array 73 | | null; 74 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/interfaces.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 6 | 7 | export interface Person { 8 | id: number; 9 | name: string; 10 | age: number; 11 | email: string | null; 12 | gender: Gender; 13 | addressId: number; 14 | address?: Address; 15 | friends?: Person[]; 16 | friendsOf?: Person[]; 17 | data?: Data | null; 18 | } 19 | 20 | export interface Address { 21 | id: number; 22 | streetNumber: number; 23 | streetName: string; 24 | city: string; 25 | isBilling: boolean; 26 | people?: Person[]; 27 | } 28 | 29 | export interface Data { 30 | id: string; 31 | stringField: string; 32 | booleanField: boolean; 33 | intField: number; 34 | bigIntField: bigint; 35 | floatField: number; 36 | decimalField: Decimal; 37 | dateField: Date; 38 | jsonField: JsonValue; 39 | bytesField: Uint8Array; 40 | enumField: DataTest; 41 | optionalStringField: string | null; 42 | optionalBooleanField: boolean | null; 43 | optionalIntField: number | null; 44 | optionalBigIntField: bigint | null; 45 | optionalFloatField: number | null; 46 | optionalDecimalField: Decimal | null; 47 | optionalDateField: Date | null; 48 | optionalJsonField: JsonValue | null; 49 | optionalBytesField: Uint8Array | null; 50 | optionalEnumField: DataTest | null; 51 | stringArrayField: string[]; 52 | booleanArrayField: boolean[]; 53 | intArrayField: number[]; 54 | bigIntArrayField: bigint[]; 55 | floatArrayField: number[]; 56 | decimalArrayField: Decimal[]; 57 | dateArrayField: Date[]; 58 | jsonArrayField: JsonValue[]; 59 | bytesArrayField: Uint8Array[]; 60 | enumArrayField: DataTest[]; 61 | personId: number; 62 | person?: Person; 63 | } 64 | 65 | type Decimal = { valueOf(): string }; 66 | 67 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 68 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/modelType.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 6 | 7 | export type Person = { 8 | id: number; 9 | name: string; 10 | age: number; 11 | email: string | null; 12 | gender: Gender; 13 | addressId: number; 14 | address?: Address; 15 | friends?: Person[]; 16 | friendsOf?: Person[]; 17 | data?: Data | null; 18 | }; 19 | 20 | export type Address = { 21 | id: number; 22 | streetNumber: number; 23 | streetName: string; 24 | city: string; 25 | isBilling: boolean; 26 | people?: Person[]; 27 | }; 28 | 29 | export type Data = { 30 | id: string; 31 | stringField: string; 32 | booleanField: boolean; 33 | intField: number; 34 | bigIntField: bigint; 35 | floatField: number; 36 | decimalField: Decimal; 37 | dateField: Date; 38 | jsonField: JsonValue; 39 | bytesField: Uint8Array; 40 | enumField: DataTest; 41 | optionalStringField: string | null; 42 | optionalBooleanField: boolean | null; 43 | optionalIntField: number | null; 44 | optionalBigIntField: bigint | null; 45 | optionalFloatField: number | null; 46 | optionalDecimalField: Decimal | null; 47 | optionalDateField: Date | null; 48 | optionalJsonField: JsonValue | null; 49 | optionalBytesField: Uint8Array | null; 50 | optionalEnumField: DataTest | null; 51 | stringArrayField: string[]; 52 | booleanArrayField: boolean[]; 53 | intArrayField: number[]; 54 | bigIntArrayField: bigint[]; 55 | floatArrayField: number[]; 56 | decimalArrayField: Decimal[]; 57 | dateArrayField: Date[]; 58 | jsonArrayField: JsonValue[]; 59 | bytesArrayField: Uint8Array[]; 60 | enumArrayField: DataTest[]; 61 | personId: number; 62 | person?: Person; 63 | }; 64 | 65 | type Decimal = { valueOf(): string }; 66 | 67 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 68 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/multilineHeader.ts: -------------------------------------------------------------------------------- 1 | // This is a multiline header 2 | // with a second line 3 | // and a third line indented 4 | // and emoji 🎉 5 | 6 | export type Gender = "Male" | "Female" | "Other"; 7 | 8 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 9 | 10 | export interface Person { 11 | id: number; 12 | name: string; 13 | age: number; 14 | email: string | null; 15 | gender: Gender; 16 | addressId: number; 17 | address?: Address; 18 | friends?: Person[]; 19 | friendsOf?: Person[]; 20 | data?: Data | null; 21 | } 22 | 23 | export interface Address { 24 | id: number; 25 | streetNumber: number; 26 | streetName: string; 27 | city: string; 28 | isBilling: boolean; 29 | people?: Person[]; 30 | } 31 | 32 | export interface Data { 33 | id: string; 34 | stringField: string; 35 | booleanField: boolean; 36 | intField: number; 37 | bigIntField: bigint; 38 | floatField: number; 39 | decimalField: Decimal; 40 | dateField: Date; 41 | jsonField: JsonValue; 42 | bytesField: Uint8Array; 43 | enumField: DataTest; 44 | optionalStringField: string | null; 45 | optionalBooleanField: boolean | null; 46 | optionalIntField: number | null; 47 | optionalBigIntField: bigint | null; 48 | optionalFloatField: number | null; 49 | optionalDecimalField: Decimal | null; 50 | optionalDateField: Date | null; 51 | optionalJsonField: JsonValue | null; 52 | optionalBytesField: Uint8Array | null; 53 | optionalEnumField: DataTest | null; 54 | stringArrayField: string[]; 55 | booleanArrayField: boolean[]; 56 | intArrayField: number[]; 57 | bigIntArrayField: bigint[]; 58 | floatArrayField: number[]; 59 | decimalArrayField: Decimal[]; 60 | dateArrayField: Date[]; 61 | jsonArrayField: JsonValue[]; 62 | bytesArrayField: Uint8Array[]; 63 | enumArrayField: DataTest[]; 64 | personId: number; 65 | person?: Person; 66 | } 67 | 68 | type Decimal = { valueOf(): string }; 69 | 70 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 71 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/noHeader.ts: -------------------------------------------------------------------------------- 1 | export type Gender = "Male" | "Female" | "Other"; 2 | 3 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 4 | 5 | export interface Person { 6 | id: number; 7 | name: string; 8 | age: number; 9 | email: string | null; 10 | gender: Gender; 11 | addressId: number; 12 | address?: Address; 13 | friends?: Person[]; 14 | friendsOf?: Person[]; 15 | data?: Data | null; 16 | } 17 | 18 | export interface Address { 19 | id: number; 20 | streetNumber: number; 21 | streetName: string; 22 | city: string; 23 | isBilling: boolean; 24 | people?: Person[]; 25 | } 26 | 27 | export interface Data { 28 | id: string; 29 | stringField: string; 30 | booleanField: boolean; 31 | intField: number; 32 | bigIntField: bigint; 33 | floatField: number; 34 | decimalField: Decimal; 35 | dateField: Date; 36 | jsonField: JsonValue; 37 | bytesField: Uint8Array; 38 | enumField: DataTest; 39 | optionalStringField: string | null; 40 | optionalBooleanField: boolean | null; 41 | optionalIntField: number | null; 42 | optionalBigIntField: bigint | null; 43 | optionalFloatField: number | null; 44 | optionalDecimalField: Decimal | null; 45 | optionalDateField: Date | null; 46 | optionalJsonField: JsonValue | null; 47 | optionalBytesField: Uint8Array | null; 48 | optionalEnumField: DataTest | null; 49 | stringArrayField: string[]; 50 | booleanArrayField: boolean[]; 51 | intArrayField: number[]; 52 | bigIntArrayField: bigint[]; 53 | floatArrayField: number[]; 54 | decimalArrayField: Decimal[]; 55 | dateArrayField: Date[]; 56 | jsonArrayField: JsonValue[]; 57 | bytesArrayField: Uint8Array[]; 58 | enumArrayField: DataTest[]; 59 | personId: number; 60 | person?: Person; 61 | } 62 | 63 | type Decimal = { valueOf(): string }; 64 | 65 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 66 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/numberTypes.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 6 | 7 | export interface Person { 8 | id: number; 9 | name: string; 10 | age: number; 11 | email: string | null; 12 | gender: Gender; 13 | addressId: number; 14 | address?: Address; 15 | friends?: Person[]; 16 | friendsOf?: Person[]; 17 | data?: Data | null; 18 | } 19 | 20 | export interface Address { 21 | id: number; 22 | streetNumber: number; 23 | streetName: string; 24 | city: string; 25 | isBilling: boolean; 26 | people?: Person[]; 27 | } 28 | 29 | export interface Data { 30 | id: string; 31 | stringField: string; 32 | booleanField: boolean; 33 | intField: number; 34 | bigIntField: number; 35 | floatField: number; 36 | decimalField: number; 37 | dateField: number; 38 | jsonField: JsonValue; 39 | bytesField: number[]; 40 | enumField: DataTest; 41 | optionalStringField: string | null; 42 | optionalBooleanField: boolean | null; 43 | optionalIntField: number | null; 44 | optionalBigIntField: number | null; 45 | optionalFloatField: number | null; 46 | optionalDecimalField: number | null; 47 | optionalDateField: number | null; 48 | optionalJsonField: JsonValue | null; 49 | optionalBytesField: number[] | null; 50 | optionalEnumField: DataTest | null; 51 | stringArrayField: string[]; 52 | booleanArrayField: boolean[]; 53 | intArrayField: number[]; 54 | bigIntArrayField: number[]; 55 | floatArrayField: number[]; 56 | decimalArrayField: number[]; 57 | dateArrayField: number[]; 58 | jsonArrayField: JsonValue[]; 59 | bytesArrayField: number[][]; 60 | enumArrayField: DataTest[]; 61 | personId: number; 62 | person?: Person; 63 | } 64 | 65 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 66 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/omitRelations.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 6 | 7 | export interface Person { 8 | id: number; 9 | name: string; 10 | age: number; 11 | email: string | null; 12 | gender: Gender; 13 | addressId: number; 14 | } 15 | 16 | export interface Address { 17 | id: number; 18 | streetNumber: number; 19 | streetName: string; 20 | city: string; 21 | isBilling: boolean; 22 | } 23 | 24 | export interface Data { 25 | id: string; 26 | stringField: string; 27 | booleanField: boolean; 28 | intField: number; 29 | bigIntField: bigint; 30 | floatField: number; 31 | decimalField: Decimal; 32 | dateField: Date; 33 | jsonField: JsonValue; 34 | bytesField: Uint8Array; 35 | enumField: DataTest; 36 | optionalStringField: string | null; 37 | optionalBooleanField: boolean | null; 38 | optionalIntField: number | null; 39 | optionalBigIntField: bigint | null; 40 | optionalFloatField: number | null; 41 | optionalDecimalField: Decimal | null; 42 | optionalDateField: Date | null; 43 | optionalJsonField: JsonValue | null; 44 | optionalBytesField: Uint8Array | null; 45 | optionalEnumField: DataTest | null; 46 | stringArrayField: string[]; 47 | booleanArrayField: boolean[]; 48 | intArrayField: number[]; 49 | bigIntArrayField: bigint[]; 50 | floatArrayField: number[]; 51 | decimalArrayField: Decimal[]; 52 | dateArrayField: Date[]; 53 | jsonArrayField: JsonValue[]; 54 | bytesArrayField: Uint8Array[]; 55 | enumArrayField: DataTest[]; 56 | personId: number; 57 | } 58 | 59 | type Decimal = { valueOf(): string }; 60 | 61 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 62 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/optionalNullables.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 6 | 7 | export interface Person { 8 | id: number; 9 | name: string; 10 | age: number; 11 | email?: string | null; 12 | gender: Gender; 13 | addressId: number; 14 | address?: Address; 15 | friends?: Person[]; 16 | friendsOf?: Person[]; 17 | data?: Data | null; 18 | } 19 | 20 | export interface Address { 21 | id: number; 22 | streetNumber: number; 23 | streetName: string; 24 | city: string; 25 | isBilling: boolean; 26 | people?: Person[]; 27 | } 28 | 29 | export interface Data { 30 | id: string; 31 | stringField: string; 32 | booleanField: boolean; 33 | intField: number; 34 | bigIntField: bigint; 35 | floatField: number; 36 | decimalField: Decimal; 37 | dateField: Date; 38 | jsonField: JsonValue; 39 | bytesField: Uint8Array; 40 | enumField: DataTest; 41 | optionalStringField?: string | null; 42 | optionalBooleanField?: boolean | null; 43 | optionalIntField?: number | null; 44 | optionalBigIntField?: bigint | null; 45 | optionalFloatField?: number | null; 46 | optionalDecimalField?: Decimal | null; 47 | optionalDateField?: Date | null; 48 | optionalJsonField?: JsonValue | null; 49 | optionalBytesField?: Uint8Array | null; 50 | optionalEnumField?: DataTest | null; 51 | stringArrayField: string[]; 52 | booleanArrayField: boolean[]; 53 | intArrayField: number[]; 54 | bigIntArrayField: bigint[]; 55 | floatArrayField: number[]; 56 | decimalArrayField: Decimal[]; 57 | dateArrayField: Date[]; 58 | jsonArrayField: JsonValue[]; 59 | bytesArrayField: Uint8Array[]; 60 | enumArrayField: DataTest[]; 61 | personId: number; 62 | person?: Person; 63 | } 64 | 65 | type Decimal = { valueOf(): string }; 66 | 67 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 68 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/optionalNullablesRequiredRelations.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 6 | 7 | export interface Person { 8 | id: number; 9 | name: string; 10 | age: number; 11 | email?: string | null; 12 | gender: Gender; 13 | addressId: number; 14 | address: Address; 15 | friends: Person[]; 16 | friendsOf: Person[]; 17 | data?: Data | null; 18 | } 19 | 20 | export interface Address { 21 | id: number; 22 | streetNumber: number; 23 | streetName: string; 24 | city: string; 25 | isBilling: boolean; 26 | people: Person[]; 27 | } 28 | 29 | export interface Data { 30 | id: string; 31 | stringField: string; 32 | booleanField: boolean; 33 | intField: number; 34 | bigIntField: bigint; 35 | floatField: number; 36 | decimalField: Decimal; 37 | dateField: Date; 38 | jsonField: JsonValue; 39 | bytesField: Uint8Array; 40 | enumField: DataTest; 41 | optionalStringField?: string | null; 42 | optionalBooleanField?: boolean | null; 43 | optionalIntField?: number | null; 44 | optionalBigIntField?: bigint | null; 45 | optionalFloatField?: number | null; 46 | optionalDecimalField?: Decimal | null; 47 | optionalDateField?: Date | null; 48 | optionalJsonField?: JsonValue | null; 49 | optionalBytesField?: Uint8Array | null; 50 | optionalEnumField?: DataTest | null; 51 | stringArrayField: string[]; 52 | booleanArrayField: boolean[]; 53 | intArrayField: number[]; 54 | bigIntArrayField: bigint[]; 55 | floatArrayField: number[]; 56 | decimalArrayField: Decimal[]; 57 | dateArrayField: Date[]; 58 | jsonArrayField: JsonValue[]; 59 | bytesArrayField: Uint8Array[]; 60 | enumArrayField: DataTest[]; 61 | personId: number; 62 | person: Person; 63 | } 64 | 65 | type Decimal = { valueOf(): string }; 66 | 67 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 68 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/prefixSuffix.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type enumGenderEnum = "Male" | "Female" | "Other"; 4 | 5 | export type enumDataTestEnum = "Apple" | "Banana" | "Orange" | "Pear"; 6 | 7 | export interface modelPersonModel { 8 | id: number; 9 | name: string; 10 | age: number; 11 | email: string | null; 12 | gender: enumGenderEnum; 13 | addressId: number; 14 | address?: modelAddressModel; 15 | friends?: modelPersonModel[]; 16 | friendsOf?: modelPersonModel[]; 17 | data?: modelDataModel | null; 18 | } 19 | 20 | export interface modelAddressModel { 21 | id: number; 22 | streetNumber: number; 23 | streetName: string; 24 | city: string; 25 | isBilling: boolean; 26 | people?: modelPersonModel[]; 27 | } 28 | 29 | export interface modelDataModel { 30 | id: string; 31 | stringField: string; 32 | booleanField: boolean; 33 | intField: number; 34 | bigIntField: bigint; 35 | floatField: number; 36 | decimalField: Decimal; 37 | dateField: Date; 38 | jsonField: JsonValue; 39 | bytesField: Uint8Array; 40 | enumField: enumDataTestEnum; 41 | optionalStringField: string | null; 42 | optionalBooleanField: boolean | null; 43 | optionalIntField: number | null; 44 | optionalBigIntField: bigint | null; 45 | optionalFloatField: number | null; 46 | optionalDecimalField: Decimal | null; 47 | optionalDateField: Date | null; 48 | optionalJsonField: JsonValue | null; 49 | optionalBytesField: Uint8Array | null; 50 | optionalEnumField: enumDataTestEnum | null; 51 | stringArrayField: string[]; 52 | booleanArrayField: boolean[]; 53 | intArrayField: number[]; 54 | bigIntArrayField: bigint[]; 55 | floatArrayField: number[]; 56 | decimalArrayField: Decimal[]; 57 | dateArrayField: Date[]; 58 | jsonArrayField: JsonValue[]; 59 | bytesArrayField: Uint8Array[]; 60 | enumArrayField: enumDataTestEnum[]; 61 | personId: number; 62 | person?: modelPersonModel; 63 | } 64 | 65 | type Decimal = { valueOf(): string }; 66 | 67 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 68 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/requiredRelations.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 6 | 7 | export interface Person { 8 | id: number; 9 | name: string; 10 | age: number; 11 | email: string | null; 12 | gender: Gender; 13 | addressId: number; 14 | address: Address; 15 | friends: Person[]; 16 | friendsOf: Person[]; 17 | data: Data | null; 18 | } 19 | 20 | export interface Address { 21 | id: number; 22 | streetNumber: number; 23 | streetName: string; 24 | city: string; 25 | isBilling: boolean; 26 | people: Person[]; 27 | } 28 | 29 | export interface Data { 30 | id: string; 31 | stringField: string; 32 | booleanField: boolean; 33 | intField: number; 34 | bigIntField: bigint; 35 | floatField: number; 36 | decimalField: Decimal; 37 | dateField: Date; 38 | jsonField: JsonValue; 39 | bytesField: Uint8Array; 40 | enumField: DataTest; 41 | optionalStringField: string | null; 42 | optionalBooleanField: boolean | null; 43 | optionalIntField: number | null; 44 | optionalBigIntField: bigint | null; 45 | optionalFloatField: number | null; 46 | optionalDecimalField: Decimal | null; 47 | optionalDateField: Date | null; 48 | optionalJsonField: JsonValue | null; 49 | optionalBytesField: Uint8Array | null; 50 | optionalEnumField: DataTest | null; 51 | stringArrayField: string[]; 52 | booleanArrayField: boolean[]; 53 | intArrayField: number[]; 54 | bigIntArrayField: bigint[]; 55 | floatArrayField: number[]; 56 | decimalArrayField: Decimal[]; 57 | dateArrayField: Date[]; 58 | jsonArrayField: JsonValue[]; 59 | bytesArrayField: Uint8Array[]; 60 | enumArrayField: DataTest[]; 61 | personId: number; 62 | person: Person; 63 | } 64 | 65 | type Decimal = { valueOf(): string }; 66 | 67 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 68 | -------------------------------------------------------------------------------- /tests/options-behavior/expected/stringTypes.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Gender = "Male" | "Female" | "Other"; 4 | 5 | export type DataTest = "Apple" | "Banana" | "Orange" | "Pear"; 6 | 7 | export interface Person { 8 | id: number; 9 | name: string; 10 | age: number; 11 | email: string | null; 12 | gender: Gender; 13 | addressId: number; 14 | address?: Address; 15 | friends?: Person[]; 16 | friendsOf?: Person[]; 17 | data?: Data | null; 18 | } 19 | 20 | export interface Address { 21 | id: number; 22 | streetNumber: number; 23 | streetName: string; 24 | city: string; 25 | isBilling: boolean; 26 | people?: Person[]; 27 | } 28 | 29 | export interface Data { 30 | id: string; 31 | stringField: string; 32 | booleanField: boolean; 33 | intField: number; 34 | bigIntField: string; 35 | floatField: number; 36 | decimalField: string; 37 | dateField: string; 38 | jsonField: JsonValue; 39 | bytesField: string; 40 | enumField: DataTest; 41 | optionalStringField: string | null; 42 | optionalBooleanField: boolean | null; 43 | optionalIntField: number | null; 44 | optionalBigIntField: string | null; 45 | optionalFloatField: number | null; 46 | optionalDecimalField: string | null; 47 | optionalDateField: string | null; 48 | optionalJsonField: JsonValue | null; 49 | optionalBytesField: string | null; 50 | optionalEnumField: DataTest | null; 51 | stringArrayField: string[]; 52 | booleanArrayField: boolean[]; 53 | intArrayField: number[]; 54 | bigIntArrayField: string[]; 55 | floatArrayField: number[]; 56 | decimalArrayField: string[]; 57 | dateArrayField: string[]; 58 | jsonArrayField: JsonValue[]; 59 | bytesArrayField: string[]; 60 | enumArrayField: DataTest[]; 61 | personId: number; 62 | person?: Person; 63 | } 64 | 65 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 66 | -------------------------------------------------------------------------------- /tests/options-behavior/schema.prisma: -------------------------------------------------------------------------------- 1 | // These tests cover most of the generator's options 2 | 3 | // ======================== 4 | // Generator Tests 5 | // ======================== 6 | 7 | // Unlike other tests, this one should output to the default "interfaces.ts" 8 | generator noOptions { 9 | provider = "tsx generator.ts" 10 | } 11 | 12 | generator customOutput { 13 | provider = "tsx generator.ts" 14 | output = "customOutput.ts" 15 | } 16 | 17 | generator defaultsSpecified { 18 | provider = "tsx generator.ts" 19 | output = "defaultsSpecified.ts" 20 | modelType = "interface" 21 | enumType = "stringUnion" 22 | dateType = "Date" 23 | bigIntType = "bigint" 24 | decimalType = "Decimal" 25 | bytesType = "Uint8Array" 26 | } 27 | 28 | generator customHeader { 29 | provider = "tsx generator.ts" 30 | output = "customHeader.ts" 31 | headerComment = "This is a custom header" 32 | } 33 | 34 | generator noHeader { 35 | provider = "tsx generator.ts" 36 | output = "noHeader.ts" 37 | headerComment = "" 38 | } 39 | 40 | generator multilineHeader { 41 | provider = "tsx generator.ts" 42 | output = "multilineHeader.ts" 43 | headerComment = "This is a multiline header\nwith a second line\n and a third line indented\nand emoji 🎉" 44 | } 45 | 46 | generator formatPrettier { 47 | provider = "tsx generator.ts" 48 | output = "formatPrettier.ts" 49 | prettier = true 50 | } 51 | 52 | generator requiredRelations { 53 | provider = "tsx generator.ts" 54 | output = "requiredRelations.ts" 55 | optionalRelations = false 56 | } 57 | 58 | generator omitRelations { 59 | provider = "tsx generator.ts" 60 | output = "omitRelations.ts" 61 | omitRelations = true 62 | } 63 | 64 | generator optionalNullables { 65 | provider = "tsx generator.ts" 66 | output = "optionalNullables.ts" 67 | optionalNullables = true 68 | } 69 | 70 | // Note that optionalNullables takes priority for a nullable relation. 71 | generator optionalNullablesRequiredRelations { 72 | provider = "tsx generator.ts" 73 | output = "optionalNullablesRequiredRelations.ts" 74 | optionalNullables = true 75 | optionalRelations = false 76 | } 77 | 78 | generator prefixSuffix { 79 | provider = "tsx generator.ts" 80 | output = "prefixSuffix.ts" 81 | enumPrefix = "enum" 82 | enumSuffix = "Enum" 83 | modelPrefix = "model" 84 | modelSuffix = "Model" 85 | } 86 | 87 | generator stringTypes { 88 | provider = "tsx generator.ts" 89 | output = "stringTypes.ts" 90 | dateType = "string" 91 | bigIntType = "string" 92 | decimalType = "string" 93 | bytesType = "string" 94 | } 95 | 96 | generator numberTypes { 97 | provider = "tsx generator.ts" 98 | output = "numberTypes.ts" 99 | dateType = "number" 100 | bigIntType = "number" 101 | decimalType = "number" 102 | bytesType = "number[]" 103 | } 104 | 105 | generator bytesBuffer { 106 | provider = "tsx generator.ts" 107 | output = "bytesBuffer.ts" 108 | bytesType = "Buffer" 109 | } 110 | 111 | generator bytesBufferObject { 112 | provider = "tsx generator.ts" 113 | output = "bytesBufferObject.ts" 114 | bytesType = "BufferObject" 115 | } 116 | 117 | generator bytesArrayObject { 118 | provider = "tsx generator.ts" 119 | output = "bytesArrayObject.ts" 120 | bytesType = "ArrayObject" 121 | } 122 | 123 | generator enumType { 124 | provider = "tsx generator.ts" 125 | output = "enumType.ts" 126 | enumType = "enum" 127 | } 128 | 129 | generator enumExportFalse { 130 | provider = "tsx generator.ts" 131 | output = "enumExportFalse.ts" 132 | enumType = "enum" 133 | exportEnums = false 134 | } 135 | 136 | generator enumTypePrefixSuffix { 137 | provider = "tsx generator.ts" 138 | output = "enumTypePrefixSuffix.ts" 139 | enumType = "enum" 140 | enumPrefix = "e" 141 | enumSuffix = "Enum" 142 | } 143 | 144 | generator enumTypeObject { 145 | provider = "tsx generator.ts" 146 | output = "enumTypeObject.ts" 147 | enumType = "object" 148 | } 149 | 150 | generator enumExportFalseTypeObject { 151 | provider = "tsx generator.ts" 152 | output = "enumExportFalseTypeObject.ts" 153 | enumType = "object" 154 | exportEnums = false 155 | } 156 | 157 | generator enumTypeObjectPrefixSuffix { 158 | provider = "tsx generator.ts" 159 | output = "enumTypeObjectPrefixSuffix.ts" 160 | enumType = "object" 161 | enumPrefix = "e" 162 | enumSuffix = "Enum" 163 | } 164 | 165 | generator enumTypeObjectValuePrefixSuffix { 166 | provider = "tsx generator.ts" 167 | output = "enumTypeObjectValuePrefixSuffix.ts" 168 | enumType = "object" 169 | enumPrefix = "e" 170 | enumSuffix = "Enum" 171 | enumObjectPrefix = "$" 172 | enumObjectSuffix = "Obj" 173 | } 174 | 175 | generator modelType { 176 | provider = "tsx generator.ts" 177 | output = "modelType.ts" 178 | modelType = "type" 179 | } 180 | 181 | // ======================== 182 | // Prisma Schema 183 | // ======================== 184 | 185 | datasource db { 186 | provider = "postgresql" 187 | url = "" 188 | } 189 | 190 | enum Gender { 191 | Male 192 | Female 193 | Other 194 | } 195 | 196 | enum DataTest { 197 | Apple 198 | Banana 199 | Orange 200 | Pear 201 | } 202 | 203 | model Person { 204 | id Int @id @default(autoincrement()) 205 | name String 206 | age Int 207 | email String? 208 | gender Gender 209 | addressId Int 210 | address Address @relation(fields: [addressId], references: [id]) 211 | friends Person[] @relation("Friends") 212 | friendsOf Person[] @relation("Friends") 213 | data Data? 214 | } 215 | 216 | model Address { 217 | id Int @id 218 | streetNumber Int 219 | streetName String 220 | city String 221 | isBilling Boolean 222 | people Person[] 223 | } 224 | 225 | model Data { 226 | id String @id @default(uuid()) @db.Uuid 227 | stringField String 228 | booleanField Boolean 229 | intField Int 230 | bigIntField BigInt 231 | floatField Float 232 | decimalField Decimal 233 | dateField DateTime 234 | jsonField Json 235 | bytesField Bytes 236 | enumField DataTest 237 | 238 | optionalStringField String? 239 | optionalBooleanField Boolean? 240 | optionalIntField Int? 241 | optionalBigIntField BigInt? 242 | optionalFloatField Float? 243 | optionalDecimalField Decimal? 244 | optionalDateField DateTime? 245 | optionalJsonField Json? 246 | optionalBytesField Bytes? 247 | optionalEnumField DataTest? 248 | 249 | stringArrayField String[] 250 | booleanArrayField Boolean[] 251 | intArrayField Int[] 252 | bigIntArrayField BigInt[] 253 | floatArrayField Float[] 254 | decimalArrayField Decimal[] 255 | dateArrayField DateTime[] 256 | jsonArrayField Json[] 257 | bytesArrayField Bytes[] 258 | enumArrayField DataTest[] 259 | 260 | personId Int @unique 261 | person Person @relation(fields: [personId], references: [id]) 262 | } 263 | -------------------------------------------------------------------------------- /tests/prettier-options/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "tabWidth": 4 4 | } 5 | -------------------------------------------------------------------------------- /tests/prettier-options/expected/withConfig.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export interface User { 4 | id: string 5 | name: string 6 | email: string 7 | createdAt: Date 8 | updatedAt: Date 9 | } 10 | -------------------------------------------------------------------------------- /tests/prettier-options/expected/withoutConfig.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export interface User { 4 | id: string; 5 | name: string; 6 | email: string; 7 | createdAt: Date; 8 | updatedAt: Date; 9 | } 10 | -------------------------------------------------------------------------------- /tests/prettier-options/schema.prisma: -------------------------------------------------------------------------------- 1 | // Test if generator uses prettier config file when using prettier option 2 | 3 | // ======================== 4 | // Generator Tests 5 | // ======================== 6 | 7 | generator withConfig { 8 | provider = "tsx generator.ts" 9 | output = "withConfig.ts" 10 | prettier = true 11 | } 12 | 13 | generator withoutConfig { 14 | provider = "tsx generator.ts" 15 | output = "withoutConfig.ts" 16 | prettier = true 17 | resolvePrettierConfig = false 18 | } 19 | 20 | // ======================== 21 | // Prisma Schema 22 | // ======================== 23 | 24 | datasource db { 25 | provider = "postgresql" 26 | url = "" 27 | } 28 | 29 | model User { 30 | id String @id @default(cuid()) 31 | name String 32 | email String @unique 33 | createdAt DateTime @default(now()) 34 | updatedAt DateTime @updatedAt 35 | } 36 | -------------------------------------------------------------------------------- /tests/type-compatible/expected/interfaces.ts: -------------------------------------------------------------------------------- 1 | // This file was auto-generated by prisma-generator-typescript-interfaces 2 | 3 | export type Fruits = "Apple" | "Banana" | "Orange" | "Pear"; 4 | 5 | export interface Data { 6 | id: number; 7 | stringField: string; 8 | booleanField: boolean; 9 | intField: number; 10 | bigIntField: bigint; 11 | floatField: number; 12 | decimalField: Decimal; 13 | dateField: Date; 14 | jsonField: JsonValue; 15 | bytesField: Uint8Array; 16 | enumField: Fruits; 17 | relationId: number; 18 | relationField?: RelationA; 19 | optionalStringField: string | null; 20 | optionalBooleanField: boolean | null; 21 | optionalIntField: number | null; 22 | optionalBigIntField: bigint | null; 23 | optionalFloatField: number | null; 24 | optionalDecimalField: Decimal | null; 25 | optionalDateField: Date | null; 26 | optionalJsonField: JsonValue | null; 27 | optionalBytesField: Uint8Array | null; 28 | optionalEnumField: Fruits | null; 29 | optionalRelationField?: RelationB | null; 30 | stringArrayField: string[]; 31 | booleanArrayField: boolean[]; 32 | intArrayField: number[]; 33 | bigIntArrayField: bigint[]; 34 | floatArrayField: number[]; 35 | decimalArrayField: Decimal[]; 36 | dateArrayField: Date[]; 37 | jsonArrayField: JsonValue[]; 38 | bytesArrayField: Uint8Array[]; 39 | enumArrayField: Fruits[]; 40 | relationArrayField?: RelationC[]; 41 | } 42 | 43 | export interface RelationA { 44 | id: number; 45 | fieldA: string; 46 | data?: Data[]; 47 | } 48 | 49 | export interface RelationB { 50 | id: number; 51 | fieldB: string; 52 | dataId: number; 53 | data?: Data; 54 | } 55 | 56 | export interface RelationC { 57 | id: number; 58 | fieldC: string; 59 | dataId: number; 60 | data?: Data; 61 | } 62 | 63 | type Decimal = { valueOf(): string }; 64 | 65 | type JsonValue = string | number | boolean | { [key in string]?: JsonValue } | Array | null; 66 | -------------------------------------------------------------------------------- /tests/type-compatible/schema.prisma: -------------------------------------------------------------------------------- 1 | // ======================== 2 | // Generator Tests 3 | // ======================== 4 | 5 | generator client { 6 | provider = "prisma-client-js" 7 | output = "client" 8 | } 9 | 10 | generator typescriptInterfaces { 11 | provider = "tsx generator.ts" 12 | } 13 | 14 | // ======================== 15 | // Prisma Schema 16 | // ======================== 17 | 18 | datasource db { 19 | provider = "postgresql" 20 | url = "" 21 | } 22 | 23 | enum Fruits { 24 | Apple 25 | Banana 26 | Orange 27 | Pear 28 | } 29 | 30 | model Data { 31 | id Int @id 32 | stringField String 33 | booleanField Boolean 34 | intField Int 35 | bigIntField BigInt 36 | floatField Float 37 | decimalField Decimal 38 | dateField DateTime 39 | jsonField Json 40 | bytesField Bytes 41 | enumField Fruits 42 | relationId Int 43 | relationField RelationA @relation(fields: [relationId], references: [id]) 44 | 45 | optionalStringField String? 46 | optionalBooleanField Boolean? 47 | optionalIntField Int? 48 | optionalBigIntField BigInt? 49 | optionalFloatField Float? 50 | optionalDecimalField Decimal? 51 | optionalDateField DateTime? 52 | optionalJsonField Json? 53 | optionalBytesField Bytes? 54 | optionalEnumField Fruits? 55 | optionalRelationField RelationB? 56 | 57 | stringArrayField String[] 58 | booleanArrayField Boolean[] 59 | intArrayField Int[] 60 | bigIntArrayField BigInt[] 61 | floatArrayField Float[] 62 | decimalArrayField Decimal[] 63 | dateArrayField DateTime[] 64 | jsonArrayField Json[] 65 | bytesArrayField Bytes[] 66 | enumArrayField Fruits[] 67 | relationArrayField RelationC[] 68 | } 69 | 70 | model RelationA { 71 | id Int @id 72 | fieldA String 73 | data Data[] 74 | } 75 | 76 | model RelationB { 77 | id Int @id 78 | fieldB String 79 | dataId Int @unique 80 | data Data @relation(fields: [dataId], references: [id]) 81 | } 82 | 83 | model RelationC { 84 | id Int @id 85 | fieldC String 86 | dataId Int 87 | data Data @relation(fields: [dataId], references: [id]) 88 | } 89 | -------------------------------------------------------------------------------- /tests/type-compatible/test-types.ts: -------------------------------------------------------------------------------- 1 | // This test verifies that the generated types are type-compatible with the Prisma client types. 2 | // When this test runs, this file will get type-checked by typescript to ensure there are no errors 3 | 4 | import * as Interfaces from "./__TEST_TMP__/interfaces.js"; 5 | import * as Prisma from "./__TEST_TMP__/client/index.js"; 6 | 7 | // Check that all the types are type-compatible 8 | const fruits: Interfaces.Fruits = {} as Prisma.Fruits; 9 | const relationA: Interfaces.RelationA = {} as Prisma.RelationA; 10 | const relationB: Interfaces.RelationB = {} as Prisma.RelationB; 11 | const relationC: Interfaces.RelationC = {} as Prisma.RelationC; 12 | const data: Interfaces.Data = {} as Prisma.Data; 13 | 14 | // The above should catch all issues, but we'll also do a sanity check here to ensure that the 15 | // result of a query for Data is also compatible with the generated interface 16 | const client = new Prisma.PrismaClient(); 17 | const queryResult = await client.data.findUnique({ where: { id: 1 }, include: { 18 | relationField: true, 19 | optionalRelationField: true, 20 | relationArrayField: true, 21 | }}); 22 | 23 | const castedResult: Interfaces.Data = queryResult!; 24 | -------------------------------------------------------------------------------- /tests/validation-errors/expected-error.txt: -------------------------------------------------------------------------------- 1 | Error: 2 | Invalid modelType: bad 3 | Invalid enumType: incorrect 4 | Invalid dateType: wrong 5 | Invalid bigIntType: values 6 | Invalid decimalType: go 7 | Invalid bytesType: here 8 | -------------------------------------------------------------------------------- /tests/validation-errors/schema.prisma: -------------------------------------------------------------------------------- 1 | // ======================== 2 | // Generator Tests 3 | // ======================== 4 | 5 | generator typescriptInterfaces { 6 | provider = "tsx generator.ts" 7 | modelType = "bad" 8 | enumType = "incorrect" 9 | dateType = "wrong" 10 | bigIntType = "values" 11 | decimalType = "go" 12 | bytesType = "here" 13 | } 14 | 15 | // ======================== 16 | // Prisma Schema 17 | // ======================== 18 | 19 | datasource db { 20 | provider = "postgresql" 21 | url = "" 22 | } 23 | 24 | model User { 25 | id Int @id 26 | } 27 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["generator.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2021", 4 | "strict": true, 5 | "module": "NodeNext", 6 | "moduleResolution": "NodeNext" 7 | }, 8 | "include": ["**/*.ts"] 9 | } 10 | --------------------------------------------------------------------------------