├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md └── workflows │ └── test.yml ├── .gitignore ├── .vscode ├── launch.json └── settings.json ├── README.md ├── SECURITY.md ├── banner.png ├── bin ├── cli.ts └── prisma-codemod.ts ├── jest.config.js ├── package.json ├── tests ├── __fixtures__ │ ├── findUnique │ │ └── inputs │ │ │ ├── custom-interface.ts │ │ │ ├── instanceNames.ts │ │ │ ├── issue-20.ts │ │ │ ├── minimal.ts │ │ │ └── nexus-schema.ts │ ├── namespace │ │ ├── inputs │ │ │ ├── decimal.js │ │ │ ├── decimal.ts │ │ │ ├── dot-prisma.ts │ │ │ ├── errorImports.ts │ │ │ ├── issue-5.ts │ │ │ ├── issue-9.ts │ │ │ ├── keyof.ts │ │ │ ├── minimal-idempotent.ts │ │ │ ├── minimal.ts │ │ │ ├── nextjs.tsx │ │ │ └── sql.ts │ │ └── projects │ │ │ ├── custom-output │ │ │ ├── generated │ │ │ │ └── client │ │ │ │ │ ├── index.js │ │ │ │ │ ├── package.json │ │ │ │ │ ├── query-engine-debian-openssl-1.1.x │ │ │ │ │ ├── runtime │ │ │ │ │ └── index.js │ │ │ │ │ └── schema.prisma │ │ │ ├── l1.ts │ │ │ ├── l2 │ │ │ │ └── l1.ts │ │ │ ├── package.json │ │ │ └── prisma │ │ │ │ └── schema.prisma │ │ │ └── minimal │ │ │ ├── issue-5.ts │ │ │ ├── l1.ts │ │ │ ├── l2 │ │ │ └── l1.ts │ │ │ ├── package.json │ │ │ └── prisma │ │ │ └── schema.prisma │ ├── to$ │ │ └── inputs │ │ │ └── minimal.ts │ └── update-2.12 │ │ ├── inputs │ │ ├── issue-5.ts │ │ ├── issue-6.ts │ │ └── minimal.ts │ │ └── projects │ │ ├── custom-output │ │ ├── .gitignore │ │ ├── generated │ │ │ └── client │ │ │ │ ├── index.js │ │ │ │ ├── package.json │ │ │ │ ├── query-engine-debian-openssl-1.1.x │ │ │ │ ├── runtime │ │ │ │ └── index.js │ │ │ │ └── schema.prisma │ │ ├── l1.ts │ │ ├── l2 │ │ │ └── l1.ts │ │ ├── package.json │ │ └── prisma │ │ │ └── schema.prisma │ │ ├── issues │ │ ├── .gitignore │ │ ├── issue-18.ts │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ └── yarn.lock │ │ ├── prisma-codemods-issue-6-main │ │ ├── .gitignore │ │ ├── index.js │ │ ├── local-file.js │ │ ├── package.json │ │ ├── prisma │ │ │ └── schema.prisma │ │ ├── readme.md │ │ └── yarn.lock │ │ └── throw-missing-schema │ │ ├── index.js │ │ ├── local-file.js │ │ ├── package.json │ │ ├── readme.md │ │ └── yarn.lock ├── __snapshots__ │ ├── findUnique │ │ └── input │ │ │ ├── custom-interface.ts │ │ │ ├── instanceNames.ts │ │ │ ├── issue-20.ts │ │ │ ├── minimal.ts │ │ │ └── nexus-schema.ts │ ├── namespace │ │ ├── input │ │ │ ├── decimal.js │ │ │ ├── decimal.ts │ │ │ ├── dot-prisma.ts │ │ │ ├── errorImports.ts │ │ │ ├── issue-5.ts │ │ │ ├── issue-9.ts │ │ │ ├── keyof.ts │ │ │ ├── minimal-idempotent.ts │ │ │ ├── minimal.ts │ │ │ ├── nextjs.tsx │ │ │ └── sql.ts │ │ └── projects │ │ │ ├── custom-output │ │ │ ├── l1.ts.ssnap │ │ │ ├── l2 │ │ │ │ └── l1.ts.ssnap │ │ │ ├── package.json.ssnap │ │ │ └── prisma │ │ │ │ └── schema.prisma.ssnap │ │ │ └── minimal │ │ │ ├── issue-5.ts.ssnap │ │ │ ├── l1.ts.ssnap │ │ │ ├── l2 │ │ │ └── l1.ts.ssnap │ │ │ ├── package.json.ssnap │ │ │ └── prisma │ │ │ └── schema.prisma.ssnap │ ├── to$ │ │ └── input │ │ │ └── minimal.ts │ ├── update-2.12.test.ts.snap │ └── update-2.12 │ │ ├── input │ │ ├── issue-5.ts │ │ ├── issue-6.ts │ │ └── minimal.ts │ │ └── projects │ │ ├── custom-output │ │ ├── .gitignore.ssnap │ │ ├── ignore-me │ │ │ └── l1.ts.ssnap │ │ ├── l1.ts.ssnap │ │ ├── l2 │ │ │ └── l1.ts.ssnap │ │ ├── package.json.ssnap │ │ └── prisma │ │ │ └── schema.prisma.ssnap │ │ ├── issues │ │ ├── .gitignore.ssnap │ │ ├── issue-18.ts.ssnap │ │ ├── package.json.ssnap │ │ ├── prisma │ │ │ └── schema.prisma.ssnap │ │ └── yarn.lock.ssnap │ │ ├── prisma-codemods-issue-6-main │ │ ├── .gitignore.ssnap │ │ ├── index.js.ssnap │ │ ├── local-file.js.ssnap │ │ ├── package.json.ssnap │ │ ├── prisma │ │ │ └── schema.prisma.ssnap │ │ ├── readme.md.ssnap │ │ └── yarn.lock.ssnap │ │ └── throw-missing-schema │ │ ├── .gitignore.ssnap │ │ ├── index.js.ssnap │ │ ├── local-file.js.ssnap │ │ ├── package.json.ssnap │ │ ├── readme.md.ssnap │ │ └── yarn.lock.ssnap ├── findUnique.test.ts ├── namespace.test.ts ├── to$.test.ts ├── update-2.12.test.ts └── utils │ ├── buildTest.ts │ └── snapshotSerializer.ts ├── transforms ├── findUnique.ts ├── namespace.ts └── to$.ts ├── tsconfig.json ├── utils ├── getCustomImportPath.ts ├── helpers.ts └── runner.ts └── yarn.lock /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | 12 | **Before the codemod** 13 | ``` 14 | 15 | ``` 16 | 17 | **After the codemod** 18 | ``` 19 | 20 | ``` 21 | 22 | **Expected output** 23 | ``` 24 | 25 | ``` 26 | 27 | **Additional context** 28 | Add any other context about the problem here. 29 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | test: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | node-version: [10.x, 12.x] 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v1 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | - run: yarn --frozen-lockfile 21 | - run: yarn build 22 | - run: yarn test 23 | env: 24 | CI: true 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | lib 14 | 15 | # Directory for instrumented libs generated by jscoverage/JSCover 16 | lib-cov 17 | 18 | # Coverage directory used by tools like istanbul 19 | coverage 20 | 21 | # nyc test coverage 22 | .nyc_output 23 | 24 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 25 | .grunt 26 | 27 | # Bower dependency directory (https://bower.io/) 28 | bower_components 29 | 30 | # node-waf configuration 31 | .lock-wscript 32 | 33 | # Compiled binary addons (http://nodejs.org/api/addons.html) 34 | build/Release 35 | 36 | # Dependency directories 37 | node_modules/ 38 | jspm_packages/ 39 | 40 | # Typescript v1 declaration files 41 | typings/ 42 | 43 | # Optional npm cache directory 44 | .npm 45 | 46 | # Optional eslint cache 47 | .eslintcache 48 | 49 | # Optional REPL history 50 | .node_repl_history 51 | 52 | # Output of 'npm pack' 53 | *.tgz 54 | 55 | # Yarn Integrity file 56 | .yarn-integrity 57 | 58 | # dotenv environment variables file 59 | .env 60 | 61 | *.d.ts 62 | *.js 63 | *.js.map 64 | !tests/**/*.js 65 | -------------------------------------------------------------------------------- /.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": "launch", 10 | "name": "Jest Tests", 11 | "program": "${workspaceFolder}/node_modules/.bin/jest", 12 | "args": [], 13 | "internalConsoleOptions": "openOnSessionStart" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![npm](./banner.png) 2 | 3 | ![npm](https://img.shields.io/npm/v/@prisma/codemods?style=flat-square) 4 | 5 | A Collection of Codemods for Prisma 6 | 7 | ## Usage 8 | 9 | Usage 10 | 11 | ```shell 12 | $ npx @prisma/codemods <...options> 13 | ``` 14 | 15 | ```shell 16 | transform One of the choices from https://github.com/prisma/codemods#transforms 17 | path Directory of your app. i.e ./my-awesome-project 18 | ``` 19 | 20 | ```shell 21 | Options 22 | -(-f)orce Bypass Git safety checks and forcibly run codemods 23 | -(-s)chemaPath Specify a path to your ./prisma/schema.prisma 24 | -(-d)ry Dry run (no changes are made to files) 25 | -(-p)rint Print transformed files to your terminal 26 | --instanceNames=myClient Useful when importing an already instantiated client (i.e import myClient from './myClient') 27 | ``` 28 | 29 | ### Transforms 30 | 31 | | \ | Description | Example | 32 | | ------------- | ----------------------------------------------------------- | ----------------------------------------------- | 33 | | `namespace` | Codemod for `@prisma/client` namespace change | `npx @prisma/codemods namespace ./my-project` | 34 | | `findUnique` | Converts `prisma.x.findOne` to `prisma.x.findUnique` | `npx @prisma/codemods findUnique ./my-project` | 35 | | `to$` | to\$: Converts deprecated `prisma.x` methods to `prisma.$x` | `npx @prisma/codemods to$ ./my-project` | 36 | | `update-2.12` | Includes `namespace`/`findUnique`/`to$` | `npx @prisma/codemods update-2.12 ./my-project` | 37 | 38 | ## Development 39 | 40 | ```shell 41 | git clone https://github.com/prisma/codemods.git 42 | cd codemods 43 | ``` 44 | 45 | ```shell 46 | yarn cli --help 47 | ``` 48 | 49 | ### Testing 50 | 51 | If you make changes be sure to use `yarn watch` or `yarn build` before running your tests 52 | 53 | ```shell 54 | yarn test 55 | ``` 56 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | If you have a security issue to report, please contact us at [security@prisma.io](mailto:security@prisma.io). 4 | -------------------------------------------------------------------------------- /banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prisma/codemods/db3fea927c79ef4c48a3df3876d1724e4e451e78/banner.png -------------------------------------------------------------------------------- /bin/cli.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | */ 8 | // Based on https://github.com/reactjs/react-codemod/blob/dd8671c9a470a2c342b221ec903c574cf31e9f57/bin/cli.js 9 | // @next/codemod optional-name-of-transform optional/path/to/src [...options] 10 | 11 | import chalk from "chalk"; 12 | import inquirer from "inquirer"; 13 | // @ts-ignore 14 | import isGitClean from "is-git-clean"; 15 | import meow from "meow"; 16 | import { getCustomImportPath } from "../utils/getCustomImportPath"; 17 | import { 18 | jscodeshiftExecutable, 19 | runTransform, 20 | transformerDirectory, 21 | } from "../utils/runner"; 22 | 23 | function checkGitStatus(force?: boolean) { 24 | let clean = false; 25 | let errorMessage = "Unable to determine if git directory is clean"; 26 | try { 27 | clean = isGitClean.sync(process.cwd()); 28 | errorMessage = "Git directory is not clean"; 29 | } catch (err) { 30 | if (err && err.stderr && err.stderr.indexOf("Not a git repository") >= 0) { 31 | clean = true; 32 | } 33 | } 34 | 35 | if (!clean) { 36 | if (force) { 37 | console.log(`WARNING: ${errorMessage}. Forcibly continuing.`); 38 | } else { 39 | console.log("Thank you for using @prisma/codemods!"); 40 | console.log( 41 | chalk.yellow( 42 | "\nBut before we continue, please stash or commit your git changes." 43 | ) 44 | ); 45 | console.log( 46 | "\nYou may use the --force flag to override this safety check." 47 | ); 48 | process.exit(1); 49 | } 50 | } 51 | } 52 | 53 | const TRANSFORMER_INQUIRER_CHOICES = [ 54 | { 55 | name: "update-2.12: Runs namespace/findUnique/to$ transforms", 56 | value: "update-2.12", 57 | }, 58 | { 59 | name: "namespace: Codemod for @prisma/client namespace change", 60 | value: "namespace", 61 | }, 62 | { 63 | name: "to$: Converts deprecated prisma.x methods to prisma.$x", 64 | value: "to$", 65 | }, 66 | { 67 | name: 68 | "findUnique: Codemod for @prisma/client that converts findOne to findUnique", 69 | value: "findUnique", 70 | }, 71 | ]; 72 | 73 | function run() { 74 | const cli = meow( 75 | ` 76 | Usage 77 | $ npx @prisma/codemods <...options> 78 | transform One of the choices from https://github.com/prisma/codemods#transforms 79 | path Directory of your app. i.e ./my-awesome-project 80 | Options 81 | --force Bypass Git safety checks and forcibly run codemods 82 | --schemaPath Specify a path to your ./prisma/schema.prisma 83 | --dry Dry run (no changes are made to files) 84 | --print Print transformed files to your terminal 85 | --instanceNames=client Useful when importing an already instantiated (i.e import client from './client') 86 | `, 87 | { 88 | autoHelp: true, 89 | flags: { 90 | instanceNames: { 91 | type: 'string', 92 | }, 93 | schemaPath: { 94 | type: "string", 95 | isRequired: false, 96 | }, 97 | force: { 98 | alias: "f", 99 | type: "boolean", 100 | }, 101 | dry: { 102 | alias: "d", 103 | type: "boolean", 104 | }, 105 | print: { 106 | alias: "p", 107 | type: "boolean", 108 | }, 109 | runInBand: { 110 | type: "boolean", 111 | }, 112 | help: { 113 | alias: "h", 114 | type: "boolean", 115 | }, 116 | }, 117 | } 118 | ); 119 | if (!cli.flags.dry) { 120 | checkGitStatus(cli.flags.force); 121 | } 122 | 123 | if ( 124 | cli.input[0] && 125 | !TRANSFORMER_INQUIRER_CHOICES.find((x) => x.value === cli.input[0]) 126 | ) { 127 | console.error("Invalid transform choice, pick one of:"); 128 | console.error( 129 | TRANSFORMER_INQUIRER_CHOICES.map((x) => "- " + x.value).join("\n") 130 | ); 131 | process.exit(1); 132 | } 133 | 134 | inquirer 135 | .prompt([ 136 | { 137 | type: "input", 138 | name: "dir", 139 | message: "On which directory should the codemods be applied?", 140 | when: !cli.input[1], 141 | default: ".", 142 | // validate: () => 143 | filter: (files) => files.trim(), 144 | }, 145 | { 146 | type: "list", 147 | name: "transformer", 148 | message: "Which transform would you like to apply?", 149 | when: !cli.input[0], 150 | pageSize: TRANSFORMER_INQUIRER_CHOICES.length, 151 | choices: TRANSFORMER_INQUIRER_CHOICES, 152 | }, 153 | ]) 154 | .then(async (answers) => { 155 | const { dir, transformer } = answers; 156 | 157 | const dirPath = cli.input[1] || dir; 158 | 159 | const selectedTransformer = cli.input[0] || transformer; 160 | 161 | process.env.PRISMA_CUSTOM_IMPORT_PATH = await getCustomImportPath({ 162 | schemaPathFromArgs: cli.flags.schemaPath, 163 | cwd: dirPath, 164 | }); 165 | const baseOptions = { 166 | projectDir: dirPath, 167 | flags: cli.flags, 168 | customImportPath: process.env.PRISMA_CUSTOM_IMPORT_PATH, 169 | }; 170 | if (selectedTransformer === "update-2.12") { 171 | await runTransform({ 172 | ...baseOptions, 173 | transformer: "namespace", 174 | }); 175 | await runTransform({ 176 | ...baseOptions, 177 | transformer: "findUnique", 178 | }); 179 | await runTransform({ 180 | ...baseOptions, 181 | transformer: "to$", 182 | }); 183 | } else { 184 | return runTransform({ 185 | ...baseOptions, 186 | transformer: selectedTransformer, 187 | }); 188 | } 189 | }); 190 | } 191 | 192 | module.exports = { 193 | run: run, 194 | runTransform: runTransform, 195 | checkGitStatus: checkGitStatus, 196 | jscodeshiftExecutable: jscodeshiftExecutable, 197 | transformerDirectory: transformerDirectory, 198 | }; 199 | -------------------------------------------------------------------------------- /bin/prisma-codemod.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Copyright 2015-present, Facebook, Inc. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | * 9 | */ 10 | // Based on https://github.com/reactjs/react-codemod/blob/dd8671c9a470a2c342b221ec903c574cf31e9f57/bin/react-codemod.js 11 | // next-codemod optional-name-of-transform optional/path/to/src [...options] 12 | 13 | require('./cli').run() -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | }; 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@prisma/codemods", 3 | "version": "0.7.0", 4 | "description": "A collection of codemods for prisma", 5 | "repository": "https://github.com/prisma/codemods.git", 6 | "author": "William Luke ", 7 | "license": "Apache-2.0", 8 | "bin": "./bin/prisma-codemod.js", 9 | "scripts": { 10 | "watch": "yarn tsc -d -w -p tsconfig.json", 11 | "cli": "yarn build && ts-node ./bin/prisma-codemod.ts", 12 | "prepublish": "yarn build", 13 | "publish:dev": "yarn publish --tag next", 14 | "build": "yarn tsc -d -p tsconfig.json", 15 | "test": "jest" 16 | }, 17 | "devDependencies": { 18 | "@types/inquirer": "^7.3.1", 19 | "@types/jest": "26.0.18", 20 | "@types/jscodeshift": "0.7.2", 21 | "@types/node": "14.14.12", 22 | "directory-tree": "^2.2.5", 23 | "jest": "26.6.3", 24 | "jest-specific-snapshot": "^4.0.0", 25 | "prettier": "2.2.1", 26 | "strip-ansi": "6.0.0", 27 | "ts-jest": "26.4.4", 28 | "ts-node": "^9.1.1", 29 | "typescript": "4.1.2" 30 | }, 31 | "dependencies": { 32 | "@apexearth/copy": "^1.4.5", 33 | "@prisma/sdk": "2.13.0", 34 | "chalk": "4.1.0", 35 | "execa": "5.0.0", 36 | "globby": "11.0.1", 37 | "inquirer": "7.3.3", 38 | "is-git-clean": "1.1.0", 39 | "jscodeshift": "0.11.0", 40 | "meow": "8.0.0", 41 | "tempy": "^1.0.0" 42 | }, 43 | "engines": { 44 | "node": ">=10.0.0" 45 | }, 46 | "files": [ 47 | "transforms/*.js", 48 | "bin/*.js", 49 | "utils/*.js" 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /tests/__fixtures__/findUnique/inputs/custom-interface.ts: -------------------------------------------------------------------------------- 1 | export interface IPrismaSession { 2 | data: string | null; 3 | expires: Date; 4 | id: string; 5 | sid: string; 6 | } 7 | interface ICreatePrismaSession extends IPrismaSession { 8 | data: string; 9 | } 10 | interface IFindOneArgs { 11 | select?: { 12 | expires?: boolean; 13 | sid?: boolean; 14 | }; 15 | where: { 16 | sid: string; 17 | }; 18 | } 19 | interface IFindManyArgs { 20 | select?: { 21 | data?: boolean; 22 | expires?: boolean; 23 | sid?: boolean; 24 | }; 25 | where?: { 26 | sid?: string; 27 | }; 28 | } 29 | interface ICreateArgs { 30 | data: ICreatePrismaSession; 31 | } 32 | interface IUpdateArgs { 33 | data: Partial; 34 | where: { sid: string }; 35 | } 36 | interface IDeleteArgs { 37 | where: { sid: string }; 38 | } 39 | export interface IPrisma { 40 | session: { 41 | create(args: ICreateArgs): Promise; 42 | delete(args: IDeleteArgs): Promise; 43 | deleteMany(args?: unknown): Promise; 44 | findMany(args?: IFindManyArgs): Promise; 45 | findOne(args: IFindOneArgs): Promise; 46 | update(args: IUpdateArgs): Promise; 47 | }; 48 | $connect(): Promise; 49 | $disconnect(): Promise; 50 | } -------------------------------------------------------------------------------- /tests/__fixtures__/findUnique/inputs/instanceNames.ts: -------------------------------------------------------------------------------- 1 | import whatEverYouWant from './where/ever/you/want' 2 | import another from './somewhere/else' 3 | 4 | 5 | whatEverYouWant.x.findOne({ where: { id: 'test' } }); 6 | another.x.findOne({ where: { id: 'test' } }); -------------------------------------------------------------------------------- /tests/__fixtures__/findUnique/inputs/issue-20.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient } from '@prisma/client' 2 | 3 | const client = new PrismaClient(); 4 | const anotherOne = new PrismaClient(); 5 | 6 | client.x.findOne({ where: { id: 'test' } }); 7 | anotherOne.x.findOne({ where: { id: 'test' } }); -------------------------------------------------------------------------------- /tests/__fixtures__/findUnique/inputs/minimal.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient } from '@prisma/client' 2 | 3 | const prisma = new PrismaClient() 4 | 5 | function main(){ 6 | const user = prisma.user.findOne({ 7 | where: { 8 | id: "test" 9 | } 10 | }) 11 | } 12 | const findOne = 'findOne' 13 | const func = findOne() 14 | const obj = user.findOne() 15 | 16 | async function f(){ 17 | let output = await this.prisma.genUser.findOne({ 18 | where:{} 19 | }); 20 | } -------------------------------------------------------------------------------- /tests/__fixtures__/findUnique/inputs/nexus-schema.ts: -------------------------------------------------------------------------------- 1 | export const login = mutationField('login', { 2 | type: 'User', 3 | args: { 4 | email: stringArg({ required: true }), 5 | password: stringArg({ required: true }), 6 | }, 7 | async resolve(parent, { email, password }, context) { 8 | const user = await context.prisma.user.findOne({ 9 | where: { email }, 10 | }) 11 | return user 12 | } 13 | }) -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/inputs/decimal.js: -------------------------------------------------------------------------------- 1 | import { PrismaClient, JsonValue, Decimal } from '@prisma/client' 2 | 3 | async function main() { 4 | const prisma = new PrismaClient() 5 | 6 | const a = await prisma.a.findFirst() 7 | const b = await prisma.b.findFirst({ 8 | where: { 9 | decFloat: new Decimal('1.23') 10 | } 11 | }) 12 | const c = await prisma.c.findFirst() 13 | const d = await prisma.d.findFirst() 14 | const e = await prisma.e.findFirst() 15 | 16 | } 17 | 18 | main() 19 | -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/inputs/decimal.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient, JsonValue, Decimal } from '@prisma/client' 2 | 3 | async function main() { 4 | const prisma = new PrismaClient() 5 | 6 | const a: null | { 7 | id: string 8 | email: string 9 | name: string | null 10 | int: number 11 | sInt: number 12 | bInt: BigInt 13 | serial: number 14 | sSerial: number 15 | bSerial: number 16 | inc_int: number 17 | inc_sInt: number 18 | inc_bInt: BigInt 19 | } = await prisma.a.findFirst() 20 | const b = await prisma.b.findFirst({ 21 | where: { 22 | decFloat: new Decimal('1.23') 23 | } 24 | }) 25 | const c = await prisma.c.findFirst() 26 | const d: null | { 27 | id: string 28 | bool: boolean 29 | byteA: Buffer 30 | xml: string 31 | json: JsonValue 32 | jsonb: JsonValue 33 | } = await prisma.d.findFirst() 34 | const e = await prisma.e.findFirst() 35 | 36 | } 37 | 38 | main() 39 | -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/inputs/dot-prisma.ts: -------------------------------------------------------------------------------- 1 | import AWS from 'aws-sdk' 2 | import { 3 | User, 4 | Thread, 5 | Comment, 6 | Post, 7 | PostComment, 8 | BadgeType, 9 | } from '.prisma/client' 10 | import { makeEmail } from '../../lib/mail' 11 | 12 | AWS.config.credentials = new AWS.Credentials( 13 | process.env.JAWS_ACCESS_KEY_ID!, 14 | process.env.JAWS_SECRET_ACCESS_KEY!, 15 | ) 16 | const sqs = new AWS.SQS({ region: 'us-east-2' }) 17 | 18 | type SendCommentNotificationArgs = { 19 | post: Post 20 | thread: Thread 21 | comment: Comment 22 | commentAuthor: User 23 | user: User 24 | } 25 | 26 | type SendCommentThanksNotificationArgs = { 27 | post: Post 28 | thread: Thread 29 | comment: Comment 30 | commentAuthor: User 31 | commentThanksAuthor: User 32 | } 33 | 34 | type SendPostCommentNotificationArgs = { 35 | post: Post 36 | postAuthor: User 37 | postComment: PostComment 38 | postCommentAuthor: User 39 | } 40 | 41 | type sendPasswordResetTokenEmailArgs = { 42 | user: User 43 | resetToken: string 44 | } 45 | 46 | type sendNewBadgeEmailArgs = { 47 | badgeType: BadgeType 48 | user: User 49 | } 50 | 51 | type EmailParams = { 52 | from: string 53 | to: string 54 | subject: string 55 | html: string 56 | } 57 | 58 | type SqsParams = { 59 | MessageBody: string 60 | QueueUrl: string 61 | } 62 | 63 | export const sendJmail = (emailParams: EmailParams) => { 64 | if (!process.env.JMAIL_QUEUE_URL) { 65 | if (process.env.NODE_ENV === 'production') { 66 | throw new Error('NODE_ENV is prod, but no JMAIL_QUEUE_URL is specified. Something is probably very wrong.') 67 | } 68 | 69 | // We don't have a jmail queue url, so let's just spit this out to the 70 | // console for debugging 71 | console.info('Would have sent the follwing email data to the jmail queue if I had a JMAIL_QUEUE_URL:') 72 | console.info(emailParams) 73 | return new Promise(res => res()) 74 | } 75 | 76 | const params: SqsParams = { 77 | MessageBody: JSON.stringify(emailParams), 78 | QueueUrl: process.env.JMAIL_QUEUE_URL!, 79 | } 80 | 81 | return new Promise((res, rej) => { 82 | sqs.sendMessage(params, function (err, data) { 83 | if (err) { 84 | rej(err) 85 | } else { 86 | res(data) 87 | } 88 | }) 89 | }) 90 | } 91 | 92 | export const sendCommentNotification = ({ 93 | post, 94 | thread, 95 | comment, 96 | commentAuthor, 97 | user, 98 | }: SendCommentNotificationArgs) => { 99 | return sendJmail({ 100 | from: 'robin@journaly.com', 101 | to: user.email, 102 | subject: `New activity on a thread in ${post.title}`, 103 | html: makeEmail(` 104 |

Heads up! @${commentAuthor.handle} commented on a post you're subscribed to!

105 |

Journal entry: ${post.title}

106 |

Comment thread: "${thread.highlightedContent}"

107 |

Comment: "${comment.body}"

108 |

Click here to go to your journal entry!

109 | `), 110 | }) 111 | } 112 | 113 | export const sendCommentThanksNotification = ({ 114 | post, 115 | thread, 116 | comment, 117 | commentAuthor, 118 | commentThanksAuthor, 119 | }: SendCommentThanksNotificationArgs) => { 120 | const commentThanksAuthorDisplayName = commentThanksAuthor.name || commentThanksAuthor.handle 121 | 122 | return sendJmail({ 123 | from: 'robin@journaly.com', 124 | to: commentAuthor.email, 125 | subject: `${commentThanksAuthorDisplayName} said thank you!`, 126 | html: makeEmail(` 127 |

Heads up! @${commentThanksAuthorDisplayName} said thank you for your comment on their post!

128 |

Journal entry: ${post.title}

129 |

Comment thread: "${thread.highlightedContent}"

130 |

Comment: "${comment.body}"

131 |

Click here to go to your journal entry!

132 | `), 133 | }) 134 | } 135 | 136 | export const sendPostCommentNotification = ({ 137 | post, 138 | postAuthor, 139 | postComment, 140 | postCommentAuthor, 141 | }: SendPostCommentNotificationArgs) => { 142 | return sendJmail({ 143 | from: 'robin@journaly.com', 144 | to: postAuthor.email, 145 | subject: "You've got feedback!", 146 | html: makeEmail(` 147 |

Great news! @${postCommentAuthor.handle} left you some feedback!

148 |

Journal entry: ${post.title}

149 |

Comment: "${postComment.body}"

150 |

Click here to go to your journal entry!

151 | `), 152 | }) 153 | } 154 | 155 | export const sendPasswordResetTokenEmail = ({ 156 | user, 157 | resetToken, 158 | }: sendPasswordResetTokenEmailArgs) => { 159 | return sendJmail({ 160 | from: 'robin@journaly.com', 161 | to: user.email, 162 | subject: 'Your Password Reset Link', 163 | html: makeEmail(` 164 |

I heard you were having some trouble logging in. 165 |

Click here to reset your password!

166 |

Please note that the link will expire in 1 hour.

167 |

Warmly,

168 | `), 169 | }) 170 | } 171 | 172 | const assertUnreachable = (x: never): never => { 173 | throw new Error(`Didn't expect to get here ${x}`) 174 | } 175 | 176 | const getBadgeName = (badgeType: BadgeType): string => { 177 | switch (badgeType) { 178 | case BadgeType.ALPHA_USER: 179 | return 'Alpha User' 180 | case BadgeType.BETA_USER: 181 | return 'Beta User' 182 | case BadgeType.TEN_POSTS: 183 | return '10 Posts' 184 | case BadgeType.ONEHUNDRED_POSTS: 185 | return '100 Posts' 186 | case BadgeType.CODE_CONTRIBUTOR: 187 | return 'Code Contributor' 188 | } 189 | 190 | return assertUnreachable(badgeType) 191 | } 192 | 193 | export const sendNewBadgeEmail = ({ 194 | user, 195 | badgeType, 196 | }: sendNewBadgeEmailArgs) => { 197 | return sendJmail({ 198 | from: 'robin@journaly.com', 199 | to: user.email, 200 | subject: 'You earned a new badge!', 201 | html: makeEmail(` 202 |

Congratulations! You just earned the "${getBadgeName(badgeType)}" badge on Journaly.

203 |

This badge will now be displayed on your profile page.

204 | `), 205 | }) 206 | } 207 | -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/inputs/errorImports.ts: -------------------------------------------------------------------------------- 1 | const { 2 | PrismaClient, 3 | PrismaClientValidationError, 4 | PrismaClientKnownRequestError, 5 | prismaVersion, 6 | sql, 7 | raw, 8 | join, 9 | empty, 10 | } = require('./node_modules/@prisma/client') 11 | 12 | test('blog', async () => { 13 | const requests: any[] = [] 14 | const db = new PrismaClient({ 15 | errorFormat: 'colorless', 16 | __internal: { 17 | hooks: { 18 | beforeRequest: (request) => requests.push(request), 19 | }, 20 | }, 21 | }) 22 | 23 | if (!prismaVersion || !prismaVersion.client) { 24 | throw new Error(`prismaVersion missing: ${JSON.stringify(prismaVersion)}`) 25 | } 26 | 27 | // Test connecting and disconnecting all the time 28 | await db.user.findMany() 29 | const posts = await db.user 30 | .findOne({ 31 | where: { 32 | email: 'a@a.de', 33 | }, 34 | }) 35 | .posts() 36 | 37 | expect(posts.length).toBe(0) 38 | db.$disconnect() 39 | expect(requests.length).toBe(2) 40 | 41 | await db.user.findMany() 42 | db.$disconnect() 43 | expect(requests.length).toBe(3) 44 | 45 | const count = await db.user.count() 46 | expect(typeof count === 'number').toBe(true) 47 | 48 | const paramCount = await db.user.count({ 49 | take: 10000, 50 | }) 51 | 52 | expect(typeof paramCount === 'number').toBe(true) 53 | 54 | db.$connect() 55 | await db.$disconnect() 56 | 57 | await new Promise((r) => setTimeout(r, 200)) 58 | db.$connect() 59 | 60 | const userPromise = db.user.findMany() 61 | await userPromise 62 | // @ts-ignore 63 | 64 | await db.$disconnect() 65 | 66 | await db.$connect() 67 | 68 | /** 69 | * queryRaw 70 | */ 71 | 72 | // Test queryRaw(string) 73 | const rawQuery = await db.$queryRaw('SELECT 1') 74 | expect(rawQuery[0]['1']).toBe(1) 75 | 76 | // Test queryRaw(string, values) 77 | const rawQueryWithValues = await db.$queryRaw( 78 | 'SELECT $1 AS name, $2 AS id', 79 | 'Alice', 80 | 42, 81 | ) 82 | 83 | expect(rawQueryWithValues[0]).toEqual({ 84 | name: 'Alice', 85 | id: 42, 86 | }) 87 | 88 | // Test queryRaw`` 89 | const rawQueryTemplate = await db.$queryRaw`SELECT 1` 90 | expect(rawQueryTemplate[0]['1']).toBe(1) 91 | 92 | // Test queryRaw`` with ${param} 93 | const rawQueryTemplateWithParams = await db.$queryRaw`SELECT * FROM User WHERE name = ${'Alice'}` 94 | expect(rawQueryTemplateWithParams[0].name).toBe('Alice') 95 | 96 | // Test queryRaw`` with prisma.sql`` 97 | const rawQueryTemplateFromSqlTemplate = await db.$queryRaw( 98 | sql` 99 | SELECT ${join([raw('email'), raw('id'), raw('name')])} 100 | FROM ${raw('User')} 101 | ${sql`WHERE name = ${'Alice'}`} 102 | ${empty} 103 | `, 104 | ) 105 | expect(rawQueryTemplateFromSqlTemplate[0].name).toBe('Alice') 106 | 107 | /** 108 | * .$executeRaw( 109 | */ 110 | 111 | // Test .$executeRaw((string) 112 | const executeRaw = await db.$executeRaw( 113 | 'UPDATE User SET name = $1 WHERE id = $2', 114 | 'name', 115 | 'id', 116 | ) 117 | expect(executeRaw).toBe(0) 118 | 119 | // Test .$executeRaw((string, values) 120 | const executeRawWithValues = await db.$executeRaw( 121 | 'UPDATE User SET name = $1 WHERE id = $2', 122 | 'Alice', 123 | 'id', 124 | ) 125 | expect(executeRawWithValues).toBe(0) 126 | 127 | // Test $executeRaw 128 | const $executeRawTemplate = await db.$executeRaw`UPDATE User SET name = ${'name'} WHERE id = ${'id'}` 129 | expect($executeRawTemplate).toBe(0) 130 | 131 | // Test validation errors 132 | let validationError 133 | try { 134 | await db.post.create({ 135 | data: {}, 136 | }) 137 | } catch (e) { 138 | validationError = e 139 | } finally { 140 | if ( 141 | !validationError || 142 | !(validationError instanceof PrismaClientValidationError) 143 | ) { 144 | throw new Error(`Validation error is incorrect`) 145 | } 146 | } 147 | 148 | // Test known request error 149 | let knownRequestError 150 | try { 151 | const result = await db.user.create({ 152 | data: { 153 | email: 'a@a.de', 154 | name: 'Alice', 155 | }, 156 | }) 157 | } catch (e) { 158 | knownRequestError = e 159 | } finally { 160 | if ( 161 | !knownRequestError || 162 | !(knownRequestError instanceof PrismaClientKnownRequestError) 163 | ) { 164 | throw new Error(`Known request error is incorrect`) 165 | } else { 166 | if (!knownRequestError.message.includes('.user.create()')) { 167 | throw new Error(`Invalid error: ${knownRequestError.message}`) 168 | } 169 | } 170 | } 171 | 172 | // relation query where not null 173 | const relationWhereNotNull = await db.user.findMany({ 174 | where: { 175 | profile: { 176 | bio: { not: null }, 177 | }, 178 | }, 179 | }) 180 | expect(relationWhereNotNull).toEqual([]) 181 | 182 | db.$disconnect() 183 | }) 184 | -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/inputs/issue-5.ts: -------------------------------------------------------------------------------- 1 | import { User as PrismaUser } from '@prisma/client' 2 | import { User } from '../users/UserModel' 3 | 4 | export type UserLike = User | PrismaUser // TypeORM or Prisma user -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/inputs/issue-9.ts: -------------------------------------------------------------------------------- 1 | // this one 2 | import { PrismaClient, Prisma as PrismaTypes } from "@prisma/client"; 3 | // will be 4 | 5 | // and 6 | 7 | class Prisma extends PrismaClient { 8 | constructor(options?: PrismaTypes.PrismaClientOptions) { 9 | super(options); 10 | } 11 | 12 | async onDelete(args: onDeleteArgs) { 13 | const prismaDelete = new PrismaDelete(this); 14 | await prismaDelete.onDelete(args); 15 | } 16 | } -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/inputs/keyof.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient, AggregatePost, UserArgs } from '@prisma/client' 2 | type X = Required 3 | type Y = { 4 | hello: UserArgs 5 | } 6 | type Z = { 7 | [T in keyof UserArgs]: UserArgs[T] 8 | }[keyof UserArgs] 9 | 10 | function a(a: UserArgs): UserArgs { 11 | return null as any 12 | } 13 | function b() { 14 | } 15 | -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/inputs/minimal-idempotent.ts: -------------------------------------------------------------------------------- 1 | import { Prisma, PrismaClient } from '@prisma/client' 2 | import * as fs from 'fs' 3 | function test(){ 4 | const why = fs 5 | } 6 | // in the code 7 | const args: Prisma.UserArgs -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/inputs/minimal.ts: -------------------------------------------------------------------------------- 1 | import { UserArgs, PrismaClient } from '@prisma/client' 2 | import * as fs from 'fs' 3 | function test(){ 4 | const why = fs 5 | } 6 | // in the code 7 | const args: UserArgs -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/inputs/nextjs.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { GetServerSideProps } from "next"; 3 | import ReactMarkdown from "react-markdown"; 4 | import Layout from "../../components/Layout"; 5 | import Router from "next/router"; 6 | import { PostProps } from "../../components/Post"; 7 | import { PrismaClient, UserArgs, sql } from "@prisma/client"; 8 | import { useSession } from "next-auth/client"; 9 | 10 | const prisma = new PrismaClient(); 11 | 12 | export const getServerSideProps: GetServerSideProps = async ({ params }) => { 13 | let args: UserArgs; 14 | const test = sql.raw("SELECT") 15 | const post = await prisma.post.findOne({ 16 | where: { 17 | id: Number(params?.id) || -1, 18 | }, 19 | include: { 20 | author: { 21 | select: { name: true, email: true }, 22 | }, 23 | }, 24 | }); 25 | return { 26 | props: post, 27 | }; 28 | }; 29 | 30 | async function publishPost(id: number): Promise { 31 | await fetch(`http://localhost:3000/api/publish/${id}`, { 32 | method: "PUT", 33 | }); 34 | await Router.push("/"); 35 | } 36 | 37 | async function deletePost(id: number): Promise { 38 | await fetch(`http://localhost:3000/api/post/${id}`, { 39 | method: "DELETE", 40 | }); 41 | Router.push("/"); 42 | } 43 | 44 | const Post: React.FC = (props) => { 45 | const [session, loading] = useSession(); 46 | if (loading) { 47 | return
Authenticating ...
; 48 | } 49 | const userHasValidSession = Boolean(session); 50 | const postBelongsToUser = session?.user?.email === props.author?.email; 51 | let title = props.title; 52 | if (!props.published) { 53 | title = `${title} (Draft)`; 54 | } 55 | 56 | return ( 57 | 58 |
59 |

{title}

60 |

By {props?.author?.name || "Unknown author"}

61 | 62 | {!props.published && userHasValidSession && postBelongsToUser && ( 63 | 64 | )} 65 | {userHasValidSession && postBelongsToUser && ( 66 | 67 | )} 68 |
69 | 90 |
91 | ); 92 | }; 93 | 94 | export default Post; 95 | -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/inputs/sql.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PrismaClient, 3 | Post, 4 | User, 5 | prismaVersion, 6 | FindManyMachineDataArgs, 7 | LikeUpdateManyArgs, 8 | sql, 9 | join, 10 | empty, 11 | raw, 12 | Sql 13 | } from '@prisma/client' 14 | 15 | // tslint:disable 16 | 17 | // This file will not be executed, just compiled to check if the typings are valid 18 | async function main() { 19 | const prisma = new PrismaClient({ 20 | log: [ 21 | { 22 | emit: 'event', 23 | level: 'query', 24 | }, 25 | ], 26 | datasources: { 27 | db: { 28 | url: 'file:dev.db', 29 | }, 30 | }, 31 | }) 32 | 33 | prisma.on('query', (a) => { 34 | // 35 | }) 36 | 37 | prismaVersion.client 38 | 39 | const x: Sql = sql`SELECT * FROM ${raw('User')} WHERE 'id' in ${join([ 40 | 1, 41 | 2, 42 | 3, 43 | ])} ${empty} ` 44 | 45 | const queryRaw1 = await prisma.$queryRaw`SELECT * FROM User WHERE id = 1` 46 | const queryRaw2 = await prisma.$queryRaw`SELECT * FROM User WHERE id = ${1}` 47 | const queryRaw3 = await prisma.$queryRaw( 48 | `SELECT * FROM User WHERE id = $1`, 49 | 2, 50 | ) 51 | const queryRaw4 = await prisma.$queryRaw( 52 | sql`SELECT * FROM User WHERE id = ${1}`, 53 | ) 54 | const queryRaw5 = await prisma.$queryRaw( 55 | sql`SELECT * FROM User ${sql`WHERE id = ${1}`}`, 56 | ) 57 | 58 | const executeRaw1 = await prisma.$executeRaw`SELECT * FROM User WHERE id = 1` 59 | const executeRaw2 = await prisma.$executeRaw`SELECT * FROM User WHERE id = ${1}` 60 | const executeRaw3 = await prisma.$executeRaw( 61 | `SELECT * FROM User WHERE id = $1`, 62 | 2, 63 | ) 64 | const executeRaw4 = await prisma.$executeRaw( 65 | sql`SELECT * FROM User WHERE id = ${1}`, 66 | ) 67 | const executeRaw5 = await prisma.$executeRaw( 68 | sql`SELECT * FROM User ${sql`WHERE id = ${1}`}`, 69 | ) 70 | 71 | const result1 = await prisma.user.findMany({ 72 | where: { 73 | posts: { 74 | some: { 75 | author: { 76 | AND: { 77 | id: '5', 78 | posts: { 79 | some: { 80 | author: { 81 | posts: { 82 | some: { 83 | title: '5', 84 | }, 85 | }, 86 | }, 87 | }, 88 | }, 89 | }, 90 | }, 91 | }, 92 | }, 93 | }, 94 | }) 95 | 96 | result1[0]!.email 97 | result1[0]!.id 98 | result1[0]!.name 99 | 100 | const result2: { 101 | id: string 102 | createdAt: Date 103 | updatedAt: Date 104 | published: boolean 105 | title: string 106 | content: string | null 107 | author: User | null 108 | } | null = await prisma.post.findOne({ 109 | where: { 110 | id: '', 111 | }, 112 | include: { 113 | author: true, 114 | }, 115 | }) 116 | 117 | const result3: 'Please either choose `select` or `include`' = await prisma.post.findMany( 118 | { 119 | select: {}, 120 | include: {}, 121 | }, 122 | ) 123 | 124 | const result4: Array<{ 125 | id: string 126 | author: { 127 | name: string | null 128 | } | null 129 | }> = await prisma.post.findMany({ 130 | select: { 131 | id: true, 132 | author: { 133 | select: { 134 | name: true, 135 | }, 136 | }, 137 | }, 138 | }) 139 | 140 | const result5: Post = await prisma.post.create({ 141 | data: { 142 | published: false, 143 | title: 'Title', 144 | }, 145 | }) 146 | 147 | await prisma.post.delete({ 148 | where: { 149 | id: '', 150 | }, 151 | }) 152 | 153 | await prisma.post.upsert({ 154 | create: { 155 | published: false, 156 | title: 'Title', 157 | }, 158 | update: { 159 | published: true, 160 | }, 161 | where: { 162 | id: '6', 163 | }, 164 | }) 165 | 166 | await prisma.post.updateMany({ 167 | data: { 168 | published: false, 169 | }, 170 | }) 171 | 172 | const count: number = await prisma.post.count({ 173 | where: { 174 | published: false, 175 | }, 176 | }) 177 | 178 | const $disconnect: Promise = prisma.$disconnect() 179 | 180 | // Trick to define a "positive" test, if "include" is NOT in "FindManyMachineDataArgs" 181 | type X = keyof FindManyMachineDataArgs 182 | type Y = 'include' extends X ? number : string 183 | const y: Y = 'string' 184 | 185 | // Test for https://github.com/prisma/prisma-client-js/issues/615 186 | const users = await prisma.user.findMany({ 187 | include: { 188 | posts: { 189 | include: { 190 | author: true, 191 | }, 192 | orderBy: { 193 | title: 'asc', 194 | }, 195 | }, 196 | }, 197 | }) 198 | 199 | const id = users[0].posts[0].author?.id 200 | 201 | const like = await prisma.like.findOne({ 202 | where: { 203 | userId_postId: { 204 | postId: '', 205 | userId: '', 206 | }, 207 | }, 208 | include: { post: true }, 209 | }) 210 | 211 | like!.post 212 | 213 | const like2 = await prisma.like.upsert({ 214 | where: { 215 | userId_postId: { 216 | userId: '', 217 | postId: '', 218 | }, 219 | }, 220 | create: { 221 | post: { connect: { id: '' } }, 222 | user: { connect: { id: '' } }, 223 | }, 224 | update: {}, 225 | include: { post: true }, 226 | }) 227 | 228 | like2!.post 229 | 230 | // make sure, that null is not allowed for this type 231 | type LikeUpdateIdType = LikeUpdateManyArgs['data']['id'] 232 | type AllowsNull = null extends LikeUpdateIdType ? true : false 233 | const allowsNull: AllowsNull = false 234 | 235 | // check if listing of `set` is done in nested relations 236 | // https://github.com/prisma/prisma/issues/3497 237 | await prisma.user.update({ 238 | where: { 239 | id: '6', 240 | }, 241 | data: { 242 | posts: { 243 | update: { 244 | data: { 245 | title: 'something', 246 | }, 247 | where: { 248 | id: 'whatever', 249 | }, 250 | }, 251 | }, 252 | }, 253 | }) 254 | 255 | await prisma.user.update({ 256 | where: { 257 | id: '6', 258 | }, 259 | data: { 260 | posts: { 261 | updateMany: { 262 | data: { 263 | title: 'something', 264 | }, 265 | where: { 266 | id: 'whatever', 267 | }, 268 | }, 269 | }, 270 | }, 271 | }) 272 | 273 | await prisma.post.update({ 274 | where: { 275 | id: '6', 276 | }, 277 | data: { 278 | author: { 279 | update: { 280 | name: 'something', 281 | }, 282 | }, 283 | }, 284 | }) 285 | } 286 | 287 | main().catch((e) => { 288 | console.error(e) 289 | }) 290 | -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/projects/custom-output/generated/client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": ".prisma/client", 3 | "main": "index.js", 4 | "types": "index.d.ts" 5 | } -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/projects/custom-output/generated/client/query-engine-debian-openssl-1.1.x: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prisma/codemods/db3fea927c79ef4c48a3df3876d1724e4e451e78/tests/__fixtures__/namespace/projects/custom-output/generated/client/query-engine-debian-openssl-1.1.x -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/projects/custom-output/generated/client/schema.prisma: -------------------------------------------------------------------------------- 1 | generator client { 2 | provider = "prisma-client-js" 3 | output = "../generated/client" 4 | } 5 | 6 | datasource db { 7 | provider = "sqlite" 8 | url = env("DOTENV_ROOT_PRISMA_SHOULD_WORK") 9 | } 10 | 11 | model Post { 12 | id Int @default(autoincrement()) @id 13 | createdAt DateTime @default(now()) 14 | title String 15 | content String? 16 | published Boolean @default(false) 17 | author User @relation(fields: [authorId], references: [id]) 18 | authorId Int 19 | } 20 | 21 | model Profile { 22 | id Int @default(autoincrement()) @id 23 | bio String? 24 | user User @relation(fields: [userId], references: [id]) 25 | userId Int @unique 26 | } 27 | 28 | model User { 29 | id Int @default(autoincrement()) @id 30 | email String @unique 31 | name String? 32 | posts Post[] 33 | profile Profile? 34 | } -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/projects/custom-output/l1.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PrismaClient, 3 | Post, 4 | User, 5 | prismaVersion, 6 | FindManyMachineDataArgs, 7 | LikeUpdateManyArgs, 8 | sql, 9 | join, 10 | empty, 11 | raw, 12 | Sql 13 | } from './generated/client' 14 | 15 | // tslint:disable 16 | 17 | // This file will not be executed, just compiled to check if the typings are valid 18 | async function main() { 19 | const prisma = new PrismaClient({ 20 | log: [ 21 | { 22 | emit: 'event', 23 | level: 'query', 24 | }, 25 | ], 26 | datasources: { 27 | db: { 28 | url: 'file:dev.db', 29 | }, 30 | }, 31 | }) 32 | 33 | prisma.on('query', (a) => { 34 | // 35 | }) 36 | 37 | prismaVersion.client 38 | 39 | const x: Sql = sql`SELECT * FROM ${raw('User')} WHERE 'id' in ${join([ 40 | 1, 41 | 2, 42 | 3, 43 | ])} ${empty} ` 44 | 45 | const queryRaw1 = await prisma.$queryRaw`SELECT * FROM User WHERE id = 1` 46 | const queryRaw2 = await prisma.$queryRaw`SELECT * FROM User WHERE id = ${1}` 47 | const queryRaw3 = await prisma.$queryRaw( 48 | `SELECT * FROM User WHERE id = $1`, 49 | 2, 50 | ) 51 | const queryRaw4 = await prisma.$queryRaw( 52 | sql`SELECT * FROM User WHERE id = ${1}`, 53 | ) 54 | const queryRaw5 = await prisma.$queryRaw( 55 | sql`SELECT * FROM User ${sql`WHERE id = ${1}`}`, 56 | ) 57 | 58 | const executeRaw1 = await prisma.$executeRaw`SELECT * FROM User WHERE id = 1` 59 | const executeRaw2 = await prisma.$executeRaw`SELECT * FROM User WHERE id = ${1}` 60 | const executeRaw3 = await prisma.$executeRaw( 61 | `SELECT * FROM User WHERE id = $1`, 62 | 2, 63 | ) 64 | const executeRaw4 = await prisma.$executeRaw( 65 | sql`SELECT * FROM User WHERE id = ${1}`, 66 | ) 67 | const executeRaw5 = await prisma.$executeRaw( 68 | sql`SELECT * FROM User ${sql`WHERE id = ${1}`}`, 69 | ) 70 | 71 | const result1 = await prisma.user.findMany({ 72 | where: { 73 | posts: { 74 | some: { 75 | author: { 76 | AND: { 77 | id: '5', 78 | posts: { 79 | some: { 80 | author: { 81 | posts: { 82 | some: { 83 | title: '5', 84 | }, 85 | }, 86 | }, 87 | }, 88 | }, 89 | }, 90 | }, 91 | }, 92 | }, 93 | }, 94 | }) 95 | 96 | result1[0]!.email 97 | result1[0]!.id 98 | result1[0]!.name 99 | 100 | const result2: { 101 | id: string 102 | createdAt: Date 103 | updatedAt: Date 104 | published: boolean 105 | title: string 106 | content: string | null 107 | author: User | null 108 | } | null = await prisma.post.findOne({ 109 | where: { 110 | id: '', 111 | }, 112 | include: { 113 | author: true, 114 | }, 115 | }) 116 | 117 | const result3: 'Please either choose `select` or `include`' = await prisma.post.findMany( 118 | { 119 | select: {}, 120 | include: {}, 121 | }, 122 | ) 123 | 124 | const result4: Array<{ 125 | id: string 126 | author: { 127 | name: string | null 128 | } | null 129 | }> = await prisma.post.findMany({ 130 | select: { 131 | id: true, 132 | author: { 133 | select: { 134 | name: true, 135 | }, 136 | }, 137 | }, 138 | }) 139 | 140 | const result5: Post = await prisma.post.create({ 141 | data: { 142 | published: false, 143 | title: 'Title', 144 | }, 145 | }) 146 | 147 | await prisma.post.delete({ 148 | where: { 149 | id: '', 150 | }, 151 | }) 152 | 153 | await prisma.post.upsert({ 154 | create: { 155 | published: false, 156 | title: 'Title', 157 | }, 158 | update: { 159 | published: true, 160 | }, 161 | where: { 162 | id: '6', 163 | }, 164 | }) 165 | 166 | await prisma.post.updateMany({ 167 | data: { 168 | published: false, 169 | }, 170 | }) 171 | 172 | const count: number = await prisma.post.count({ 173 | where: { 174 | published: false, 175 | }, 176 | }) 177 | 178 | const $disconnect: Promise = prisma.$disconnect() 179 | 180 | // Trick to define a "positive" test, if "include" is NOT in "FindManyMachineDataArgs" 181 | type X = keyof FindManyMachineDataArgs 182 | type Y = 'include' extends X ? number : string 183 | const y: Y = 'string' 184 | 185 | // Test for https://github.com/prisma/prisma-client-js/issues/615 186 | const users = await prisma.user.findMany({ 187 | include: { 188 | posts: { 189 | include: { 190 | author: true, 191 | }, 192 | orderBy: { 193 | title: 'asc', 194 | }, 195 | }, 196 | }, 197 | }) 198 | 199 | const id = users[0].posts[0].author?.id 200 | 201 | const like = await prisma.like.findOne({ 202 | where: { 203 | userId_postId: { 204 | postId: '', 205 | userId: '', 206 | }, 207 | }, 208 | include: { post: true }, 209 | }) 210 | 211 | like!.post 212 | 213 | const like2 = await prisma.like.upsert({ 214 | where: { 215 | userId_postId: { 216 | userId: '', 217 | postId: '', 218 | }, 219 | }, 220 | create: { 221 | post: { connect: { id: '' } }, 222 | user: { connect: { id: '' } }, 223 | }, 224 | update: {}, 225 | include: { post: true }, 226 | }) 227 | 228 | like2!.post 229 | 230 | // make sure, that null is not allowed for this type 231 | type LikeUpdateIdType = LikeUpdateManyArgs['data']['id'] 232 | type AllowsNull = null extends LikeUpdateIdType ? true : false 233 | const allowsNull: AllowsNull = false 234 | 235 | // check if listing of `set` is done in nested relations 236 | // https://github.com/prisma/prisma/issues/3497 237 | await prisma.user.update({ 238 | where: { 239 | id: '6', 240 | }, 241 | data: { 242 | posts: { 243 | update: { 244 | data: { 245 | title: 'something', 246 | }, 247 | where: { 248 | id: 'whatever', 249 | }, 250 | }, 251 | }, 252 | }, 253 | }) 254 | 255 | await prisma.user.update({ 256 | where: { 257 | id: '6', 258 | }, 259 | data: { 260 | posts: { 261 | updateMany: { 262 | data: { 263 | title: 'something', 264 | }, 265 | where: { 266 | id: 'whatever', 267 | }, 268 | }, 269 | }, 270 | }, 271 | }) 272 | 273 | await prisma.post.update({ 274 | where: { 275 | id: '6', 276 | }, 277 | data: { 278 | author: { 279 | update: { 280 | name: 'something', 281 | }, 282 | }, 283 | }, 284 | }) 285 | } 286 | 287 | main().catch((e) => { 288 | console.error(e) 289 | }) 290 | -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/projects/custom-output/l2/l1.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PrismaClient, 3 | Post, 4 | User, 5 | prismaVersion, 6 | FindManyMachineDataArgs, 7 | LikeUpdateManyArgs, 8 | sql, 9 | join, 10 | empty, 11 | raw, 12 | Sql 13 | } from '../generated/client' 14 | 15 | // tslint:disable 16 | 17 | // This file will not be executed, just compiled to check if the typings are valid 18 | async function main() { 19 | const prisma = new PrismaClient({ 20 | log: [ 21 | { 22 | emit: 'event', 23 | level: 'query', 24 | }, 25 | ], 26 | datasources: { 27 | db: { 28 | url: 'file:dev.db', 29 | }, 30 | }, 31 | }) 32 | 33 | prisma.on('query', (a) => { 34 | // 35 | }) 36 | 37 | prismaVersion.client 38 | 39 | const x: Sql = sql`SELECT * FROM ${raw('User')} WHERE 'id' in ${join([ 40 | 1, 41 | 2, 42 | 3, 43 | ])} ${empty} ` 44 | 45 | const queryRaw1 = await prisma.$queryRaw`SELECT * FROM User WHERE id = 1` 46 | const queryRaw2 = await prisma.$queryRaw`SELECT * FROM User WHERE id = ${1}` 47 | const queryRaw3 = await prisma.$queryRaw( 48 | `SELECT * FROM User WHERE id = $1`, 49 | 2, 50 | ) 51 | const queryRaw4 = await prisma.$queryRaw( 52 | sql`SELECT * FROM User WHERE id = ${1}`, 53 | ) 54 | const queryRaw5 = await prisma.$queryRaw( 55 | sql`SELECT * FROM User ${sql`WHERE id = ${1}`}`, 56 | ) 57 | 58 | const executeRaw1 = await prisma.$executeRaw`SELECT * FROM User WHERE id = 1` 59 | const executeRaw2 = await prisma.$executeRaw`SELECT * FROM User WHERE id = ${1}` 60 | const executeRaw3 = await prisma.$executeRaw( 61 | `SELECT * FROM User WHERE id = $1`, 62 | 2, 63 | ) 64 | const executeRaw4 = await prisma.$executeRaw( 65 | sql`SELECT * FROM User WHERE id = ${1}`, 66 | ) 67 | const executeRaw5 = await prisma.$executeRaw( 68 | sql`SELECT * FROM User ${sql`WHERE id = ${1}`}`, 69 | ) 70 | 71 | const result1 = await prisma.user.findMany({ 72 | where: { 73 | posts: { 74 | some: { 75 | author: { 76 | AND: { 77 | id: '5', 78 | posts: { 79 | some: { 80 | author: { 81 | posts: { 82 | some: { 83 | title: '5', 84 | }, 85 | }, 86 | }, 87 | }, 88 | }, 89 | }, 90 | }, 91 | }, 92 | }, 93 | }, 94 | }) 95 | 96 | result1[0]!.email 97 | result1[0]!.id 98 | result1[0]!.name 99 | 100 | const result2: { 101 | id: string 102 | createdAt: Date 103 | updatedAt: Date 104 | published: boolean 105 | title: string 106 | content: string | null 107 | author: User | null 108 | } | null = await prisma.post.findOne({ 109 | where: { 110 | id: '', 111 | }, 112 | include: { 113 | author: true, 114 | }, 115 | }) 116 | 117 | const result3: 'Please either choose `select` or `include`' = await prisma.post.findMany( 118 | { 119 | select: {}, 120 | include: {}, 121 | }, 122 | ) 123 | 124 | const result4: Array<{ 125 | id: string 126 | author: { 127 | name: string | null 128 | } | null 129 | }> = await prisma.post.findMany({ 130 | select: { 131 | id: true, 132 | author: { 133 | select: { 134 | name: true, 135 | }, 136 | }, 137 | }, 138 | }) 139 | 140 | const result5: Post = await prisma.post.create({ 141 | data: { 142 | published: false, 143 | title: 'Title', 144 | }, 145 | }) 146 | 147 | await prisma.post.delete({ 148 | where: { 149 | id: '', 150 | }, 151 | }) 152 | 153 | await prisma.post.upsert({ 154 | create: { 155 | published: false, 156 | title: 'Title', 157 | }, 158 | update: { 159 | published: true, 160 | }, 161 | where: { 162 | id: '6', 163 | }, 164 | }) 165 | 166 | await prisma.post.updateMany({ 167 | data: { 168 | published: false, 169 | }, 170 | }) 171 | 172 | const count: number = await prisma.post.count({ 173 | where: { 174 | published: false, 175 | }, 176 | }) 177 | 178 | const $disconnect: Promise = prisma.$disconnect() 179 | 180 | // Trick to define a "positive" test, if "include" is NOT in "FindManyMachineDataArgs" 181 | type X = keyof FindManyMachineDataArgs 182 | type Y = 'include' extends X ? number : string 183 | const y: Y = 'string' 184 | 185 | // Test for https://github.com/prisma/prisma-client-js/issues/615 186 | const users = await prisma.user.findMany({ 187 | include: { 188 | posts: { 189 | include: { 190 | author: true, 191 | }, 192 | orderBy: { 193 | title: 'asc', 194 | }, 195 | }, 196 | }, 197 | }) 198 | 199 | const id = users[0].posts[0].author?.id 200 | 201 | const like = await prisma.like.findOne({ 202 | where: { 203 | userId_postId: { 204 | postId: '', 205 | userId: '', 206 | }, 207 | }, 208 | include: { post: true }, 209 | }) 210 | 211 | like!.post 212 | 213 | const like2 = await prisma.like.upsert({ 214 | where: { 215 | userId_postId: { 216 | userId: '', 217 | postId: '', 218 | }, 219 | }, 220 | create: { 221 | post: { connect: { id: '' } }, 222 | user: { connect: { id: '' } }, 223 | }, 224 | update: {}, 225 | include: { post: true }, 226 | }) 227 | 228 | like2!.post 229 | 230 | // make sure, that null is not allowed for this type 231 | type LikeUpdateIdType = LikeUpdateManyArgs['data']['id'] 232 | type AllowsNull = null extends LikeUpdateIdType ? true : false 233 | const allowsNull: AllowsNull = false 234 | 235 | // check if listing of `set` is done in nested relations 236 | // https://github.com/prisma/prisma/issues/3497 237 | await prisma.user.update({ 238 | where: { 239 | id: '6', 240 | }, 241 | data: { 242 | posts: { 243 | update: { 244 | data: { 245 | title: 'something', 246 | }, 247 | where: { 248 | id: 'whatever', 249 | }, 250 | }, 251 | }, 252 | }, 253 | }) 254 | 255 | await prisma.user.update({ 256 | where: { 257 | id: '6', 258 | }, 259 | data: { 260 | posts: { 261 | updateMany: { 262 | data: { 263 | title: 'something', 264 | }, 265 | where: { 266 | id: 'whatever', 267 | }, 268 | }, 269 | }, 270 | }, 271 | }) 272 | 273 | await prisma.post.update({ 274 | where: { 275 | id: '6', 276 | }, 277 | data: { 278 | author: { 279 | update: { 280 | name: 'something', 281 | }, 282 | }, 283 | }, 284 | }) 285 | } 286 | 287 | main().catch((e) => { 288 | console.error(e) 289 | }) 290 | -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/projects/custom-output/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal", 3 | "dependencies": { 4 | "@prisma/cli": "^2.10.2", 5 | "@prisma/client": "^2.10.2" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/projects/custom-output/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | generator client { 2 | provider = "prisma-client-js" 3 | output = "../generated/client" 4 | } 5 | 6 | datasource db { 7 | provider = "sqlite" 8 | url = env("DOTENV_ROOT_PRISMA_SHOULD_WORK") 9 | } 10 | 11 | model Post { 12 | id Int @default(autoincrement()) @id 13 | createdAt DateTime @default(now()) 14 | title String 15 | content String? 16 | published Boolean @default(false) 17 | author User @relation(fields: [authorId], references: [id]) 18 | authorId Int 19 | } 20 | 21 | model Profile { 22 | id Int @default(autoincrement()) @id 23 | bio String? 24 | user User @relation(fields: [userId], references: [id]) 25 | userId Int @unique 26 | } 27 | 28 | model User { 29 | id Int @default(autoincrement()) @id 30 | email String @unique 31 | name String? 32 | posts Post[] 33 | profile Profile? 34 | } -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/projects/minimal/issue-5.ts: -------------------------------------------------------------------------------- 1 | import { User as PrismaUser } from '@prisma/client' 2 | import { User } from '../users/UserModel' 3 | 4 | export type UserLike = User | PrismaUser // TypeORM or Prisma user -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/projects/minimal/l1.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PrismaClient, 3 | Post, 4 | User, 5 | prismaVersion, 6 | FindManyMachineDataArgs, 7 | LikeUpdateManyArgs, 8 | sql, 9 | join, 10 | empty, 11 | raw, 12 | Sql 13 | } from '@prisma/client' 14 | 15 | // tslint:disable 16 | 17 | // This file will not be executed, just compiled to check if the typings are valid 18 | async function main() { 19 | const prisma = new PrismaClient({ 20 | log: [ 21 | { 22 | emit: 'event', 23 | level: 'query', 24 | }, 25 | ], 26 | datasources: { 27 | db: { 28 | url: 'file:dev.db', 29 | }, 30 | }, 31 | }) 32 | 33 | prisma.on('query', (a) => { 34 | // 35 | }) 36 | 37 | prismaVersion.client 38 | 39 | const x: Sql = sql`SELECT * FROM ${raw('User')} WHERE 'id' in ${join([ 40 | 1, 41 | 2, 42 | 3, 43 | ])} ${empty} ` 44 | 45 | const queryRaw1 = await prisma.$queryRaw`SELECT * FROM User WHERE id = 1` 46 | const queryRaw2 = await prisma.$queryRaw`SELECT * FROM User WHERE id = ${1}` 47 | const queryRaw3 = await prisma.$queryRaw( 48 | `SELECT * FROM User WHERE id = $1`, 49 | 2, 50 | ) 51 | const queryRaw4 = await prisma.$queryRaw( 52 | sql`SELECT * FROM User WHERE id = ${1}`, 53 | ) 54 | const queryRaw5 = await prisma.$queryRaw( 55 | sql`SELECT * FROM User ${sql`WHERE id = ${1}`}`, 56 | ) 57 | 58 | const executeRaw1 = await prisma.$executeRaw`SELECT * FROM User WHERE id = 1` 59 | const executeRaw2 = await prisma.$executeRaw`SELECT * FROM User WHERE id = ${1}` 60 | const executeRaw3 = await prisma.$executeRaw( 61 | `SELECT * FROM User WHERE id = $1`, 62 | 2, 63 | ) 64 | const executeRaw4 = await prisma.$executeRaw( 65 | sql`SELECT * FROM User WHERE id = ${1}`, 66 | ) 67 | const executeRaw5 = await prisma.$executeRaw( 68 | sql`SELECT * FROM User ${sql`WHERE id = ${1}`}`, 69 | ) 70 | 71 | const result1 = await prisma.user.findMany({ 72 | where: { 73 | posts: { 74 | some: { 75 | author: { 76 | AND: { 77 | id: '5', 78 | posts: { 79 | some: { 80 | author: { 81 | posts: { 82 | some: { 83 | title: '5', 84 | }, 85 | }, 86 | }, 87 | }, 88 | }, 89 | }, 90 | }, 91 | }, 92 | }, 93 | }, 94 | }) 95 | 96 | result1[0]!.email 97 | result1[0]!.id 98 | result1[0]!.name 99 | 100 | const result2: { 101 | id: string 102 | createdAt: Date 103 | updatedAt: Date 104 | published: boolean 105 | title: string 106 | content: string | null 107 | author: User | null 108 | } | null = await prisma.post.findOne({ 109 | where: { 110 | id: '', 111 | }, 112 | include: { 113 | author: true, 114 | }, 115 | }) 116 | 117 | const result3: 'Please either choose `select` or `include`' = await prisma.post.findMany( 118 | { 119 | select: {}, 120 | include: {}, 121 | }, 122 | ) 123 | 124 | const result4: Array<{ 125 | id: string 126 | author: { 127 | name: string | null 128 | } | null 129 | }> = await prisma.post.findMany({ 130 | select: { 131 | id: true, 132 | author: { 133 | select: { 134 | name: true, 135 | }, 136 | }, 137 | }, 138 | }) 139 | 140 | const result5: Post = await prisma.post.create({ 141 | data: { 142 | published: false, 143 | title: 'Title', 144 | }, 145 | }) 146 | 147 | await prisma.post.delete({ 148 | where: { 149 | id: '', 150 | }, 151 | }) 152 | 153 | await prisma.post.upsert({ 154 | create: { 155 | published: false, 156 | title: 'Title', 157 | }, 158 | update: { 159 | published: true, 160 | }, 161 | where: { 162 | id: '6', 163 | }, 164 | }) 165 | 166 | await prisma.post.updateMany({ 167 | data: { 168 | published: false, 169 | }, 170 | }) 171 | 172 | const count: number = await prisma.post.count({ 173 | where: { 174 | published: false, 175 | }, 176 | }) 177 | 178 | const $disconnect: Promise = prisma.$disconnect() 179 | 180 | // Trick to define a "positive" test, if "include" is NOT in "FindManyMachineDataArgs" 181 | type X = keyof FindManyMachineDataArgs 182 | type Y = 'include' extends X ? number : string 183 | const y: Y = 'string' 184 | 185 | // Test for https://github.com/prisma/prisma-client-js/issues/615 186 | const users = await prisma.user.findMany({ 187 | include: { 188 | posts: { 189 | include: { 190 | author: true, 191 | }, 192 | orderBy: { 193 | title: 'asc', 194 | }, 195 | }, 196 | }, 197 | }) 198 | 199 | const id = users[0].posts[0].author?.id 200 | 201 | const like = await prisma.like.findOne({ 202 | where: { 203 | userId_postId: { 204 | postId: '', 205 | userId: '', 206 | }, 207 | }, 208 | include: { post: true }, 209 | }) 210 | 211 | like!.post 212 | 213 | const like2 = await prisma.like.upsert({ 214 | where: { 215 | userId_postId: { 216 | userId: '', 217 | postId: '', 218 | }, 219 | }, 220 | create: { 221 | post: { connect: { id: '' } }, 222 | user: { connect: { id: '' } }, 223 | }, 224 | update: {}, 225 | include: { post: true }, 226 | }) 227 | 228 | like2!.post 229 | 230 | // make sure, that null is not allowed for this type 231 | type LikeUpdateIdType = LikeUpdateManyArgs['data']['id'] 232 | type AllowsNull = null extends LikeUpdateIdType ? true : false 233 | const allowsNull: AllowsNull = false 234 | 235 | // check if listing of `set` is done in nested relations 236 | // https://github.com/prisma/prisma/issues/3497 237 | await prisma.user.update({ 238 | where: { 239 | id: '6', 240 | }, 241 | data: { 242 | posts: { 243 | update: { 244 | data: { 245 | title: 'something', 246 | }, 247 | where: { 248 | id: 'whatever', 249 | }, 250 | }, 251 | }, 252 | }, 253 | }) 254 | 255 | await prisma.user.update({ 256 | where: { 257 | id: '6', 258 | }, 259 | data: { 260 | posts: { 261 | updateMany: { 262 | data: { 263 | title: 'something', 264 | }, 265 | where: { 266 | id: 'whatever', 267 | }, 268 | }, 269 | }, 270 | }, 271 | }) 272 | 273 | await prisma.post.update({ 274 | where: { 275 | id: '6', 276 | }, 277 | data: { 278 | author: { 279 | update: { 280 | name: 'something', 281 | }, 282 | }, 283 | }, 284 | }) 285 | } 286 | 287 | main().catch((e) => { 288 | console.error(e) 289 | }) 290 | -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/projects/minimal/l2/l1.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PrismaClient, 3 | Post, 4 | User, 5 | prismaVersion, 6 | FindManyMachineDataArgs, 7 | LikeUpdateManyArgs, 8 | sql, 9 | join, 10 | empty, 11 | raw, 12 | Sql 13 | } from '@prisma/client' 14 | 15 | // tslint:disable 16 | 17 | // This file will not be executed, just compiled to check if the typings are valid 18 | async function main() { 19 | const prisma = new PrismaClient({ 20 | log: [ 21 | { 22 | emit: 'event', 23 | level: 'query', 24 | }, 25 | ], 26 | datasources: { 27 | db: { 28 | url: 'file:dev.db', 29 | }, 30 | }, 31 | }) 32 | 33 | prisma.on('query', (a) => { 34 | // 35 | }) 36 | 37 | prismaVersion.client 38 | 39 | const x: Sql = sql`SELECT * FROM ${raw('User')} WHERE 'id' in ${join([ 40 | 1, 41 | 2, 42 | 3, 43 | ])} ${empty} ` 44 | 45 | const queryRaw1 = await prisma.$queryRaw`SELECT * FROM User WHERE id = 1` 46 | const queryRaw2 = await prisma.$queryRaw`SELECT * FROM User WHERE id = ${1}` 47 | const queryRaw3 = await prisma.$queryRaw( 48 | `SELECT * FROM User WHERE id = $1`, 49 | 2, 50 | ) 51 | const queryRaw4 = await prisma.$queryRaw( 52 | sql`SELECT * FROM User WHERE id = ${1}`, 53 | ) 54 | const queryRaw5 = await prisma.$queryRaw( 55 | sql`SELECT * FROM User ${sql`WHERE id = ${1}`}`, 56 | ) 57 | 58 | const executeRaw1 = await prisma.$executeRaw`SELECT * FROM User WHERE id = 1` 59 | const executeRaw2 = await prisma.$executeRaw`SELECT * FROM User WHERE id = ${1}` 60 | const executeRaw3 = await prisma.$executeRaw( 61 | `SELECT * FROM User WHERE id = $1`, 62 | 2, 63 | ) 64 | const executeRaw4 = await prisma.$executeRaw( 65 | sql`SELECT * FROM User WHERE id = ${1}`, 66 | ) 67 | const executeRaw5 = await prisma.$executeRaw( 68 | sql`SELECT * FROM User ${sql`WHERE id = ${1}`}`, 69 | ) 70 | 71 | const result1 = await prisma.user.findMany({ 72 | where: { 73 | posts: { 74 | some: { 75 | author: { 76 | AND: { 77 | id: '5', 78 | posts: { 79 | some: { 80 | author: { 81 | posts: { 82 | some: { 83 | title: '5', 84 | }, 85 | }, 86 | }, 87 | }, 88 | }, 89 | }, 90 | }, 91 | }, 92 | }, 93 | }, 94 | }) 95 | 96 | result1[0]!.email 97 | result1[0]!.id 98 | result1[0]!.name 99 | 100 | const result2: { 101 | id: string 102 | createdAt: Date 103 | updatedAt: Date 104 | published: boolean 105 | title: string 106 | content: string | null 107 | author: User | null 108 | } | null = await prisma.post.findOne({ 109 | where: { 110 | id: '', 111 | }, 112 | include: { 113 | author: true, 114 | }, 115 | }) 116 | 117 | const result3: 'Please either choose `select` or `include`' = await prisma.post.findMany( 118 | { 119 | select: {}, 120 | include: {}, 121 | }, 122 | ) 123 | 124 | const result4: Array<{ 125 | id: string 126 | author: { 127 | name: string | null 128 | } | null 129 | }> = await prisma.post.findMany({ 130 | select: { 131 | id: true, 132 | author: { 133 | select: { 134 | name: true, 135 | }, 136 | }, 137 | }, 138 | }) 139 | 140 | const result5: Post = await prisma.post.create({ 141 | data: { 142 | published: false, 143 | title: 'Title', 144 | }, 145 | }) 146 | 147 | await prisma.post.delete({ 148 | where: { 149 | id: '', 150 | }, 151 | }) 152 | 153 | await prisma.post.upsert({ 154 | create: { 155 | published: false, 156 | title: 'Title', 157 | }, 158 | update: { 159 | published: true, 160 | }, 161 | where: { 162 | id: '6', 163 | }, 164 | }) 165 | 166 | await prisma.post.updateMany({ 167 | data: { 168 | published: false, 169 | }, 170 | }) 171 | 172 | const count: number = await prisma.post.count({ 173 | where: { 174 | published: false, 175 | }, 176 | }) 177 | 178 | const $disconnect: Promise = prisma.$disconnect() 179 | 180 | // Trick to define a "positive" test, if "include" is NOT in "FindManyMachineDataArgs" 181 | type X = keyof FindManyMachineDataArgs 182 | type Y = 'include' extends X ? number : string 183 | const y: Y = 'string' 184 | 185 | // Test for https://github.com/prisma/prisma-client-js/issues/615 186 | const users = await prisma.user.findMany({ 187 | include: { 188 | posts: { 189 | include: { 190 | author: true, 191 | }, 192 | orderBy: { 193 | title: 'asc', 194 | }, 195 | }, 196 | }, 197 | }) 198 | 199 | const id = users[0].posts[0].author?.id 200 | 201 | const like = await prisma.like.findOne({ 202 | where: { 203 | userId_postId: { 204 | postId: '', 205 | userId: '', 206 | }, 207 | }, 208 | include: { post: true }, 209 | }) 210 | 211 | like!.post 212 | 213 | const like2 = await prisma.like.upsert({ 214 | where: { 215 | userId_postId: { 216 | userId: '', 217 | postId: '', 218 | }, 219 | }, 220 | create: { 221 | post: { connect: { id: '' } }, 222 | user: { connect: { id: '' } }, 223 | }, 224 | update: {}, 225 | include: { post: true }, 226 | }) 227 | 228 | like2!.post 229 | 230 | // make sure, that null is not allowed for this type 231 | type LikeUpdateIdType = LikeUpdateManyArgs['data']['id'] 232 | type AllowsNull = null extends LikeUpdateIdType ? true : false 233 | const allowsNull: AllowsNull = false 234 | 235 | // check if listing of `set` is done in nested relations 236 | // https://github.com/prisma/prisma/issues/3497 237 | await prisma.user.update({ 238 | where: { 239 | id: '6', 240 | }, 241 | data: { 242 | posts: { 243 | update: { 244 | data: { 245 | title: 'something', 246 | }, 247 | where: { 248 | id: 'whatever', 249 | }, 250 | }, 251 | }, 252 | }, 253 | }) 254 | 255 | await prisma.user.update({ 256 | where: { 257 | id: '6', 258 | }, 259 | data: { 260 | posts: { 261 | updateMany: { 262 | data: { 263 | title: 'something', 264 | }, 265 | where: { 266 | id: 'whatever', 267 | }, 268 | }, 269 | }, 270 | }, 271 | }) 272 | 273 | await prisma.post.update({ 274 | where: { 275 | id: '6', 276 | }, 277 | data: { 278 | author: { 279 | update: { 280 | name: 'something', 281 | }, 282 | }, 283 | }, 284 | }) 285 | } 286 | 287 | main().catch((e) => { 288 | console.error(e) 289 | }) 290 | -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/projects/minimal/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal", 3 | "dependencies": { 4 | "@prisma/cli": "^2.10.2", 5 | "@prisma/client": "^2.10.2" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/__fixtures__/namespace/projects/minimal/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | generator client { 2 | provider = "prisma-client-js" 3 | } 4 | 5 | datasource db { 6 | provider = "sqlite" 7 | url = env("DOTENV_ROOT_PRISMA_SHOULD_WORK") 8 | } 9 | 10 | model Post { 11 | id Int @default(autoincrement()) @id 12 | createdAt DateTime @default(now()) 13 | title String 14 | content String? 15 | published Boolean @default(false) 16 | author User @relation(fields: [authorId], references: [id]) 17 | authorId Int 18 | } 19 | 20 | model Profile { 21 | id Int @default(autoincrement()) @id 22 | bio String? 23 | user User @relation(fields: [userId], references: [id]) 24 | userId Int @unique 25 | } 26 | 27 | model User { 28 | id Int @default(autoincrement()) @id 29 | email String @unique 30 | name String? 31 | posts Post[] 32 | profile Profile? 33 | } -------------------------------------------------------------------------------- /tests/__fixtures__/to$/inputs/minimal.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient } from '@prisma/client' 2 | 3 | const prisma = new PrismaClient() 4 | 5 | function main(){ 6 | prisma.transaction() 7 | prisma.connect() 8 | prisma.disconnect() 9 | prisma.executeRaw() 10 | prisma.on() 11 | prisma.use() 12 | prisma.queryRaw() 13 | 14 | prisma.$transaction() 15 | prisma.$connect() 16 | prisma.$disconnect() 17 | prisma.$executeRaw() 18 | prisma.$on() 19 | prisma.$use() 20 | prisma.$queryRaw() 21 | // For the people with a transaction table 22 | prisma.transaction.create() 23 | } 24 | 25 | const transaction = "transaction" 26 | const connect = "connect" 27 | const disconnect = "disconnect" 28 | const executeRaw = "executeRaw" 29 | const on = "on" 30 | const use = "use" 31 | const queryRaw = "queryRaw" 32 | 33 | test.transaction() 34 | test.connect() 35 | test.disconnect() 36 | test.executeRaw() 37 | test.on() 38 | test.use() 39 | test.queryRaw() -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/inputs/issue-5.ts: -------------------------------------------------------------------------------- 1 | import { User as PrismaUser } from '@prisma/client' 2 | import { User } from '../users/UserModel' 3 | 4 | export type UserLike = User | PrismaUser // TypeORM or Prisma user -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/inputs/issue-6.ts: -------------------------------------------------------------------------------- 1 | import { Person as LocalPerson } from "./local-file"; 2 | import { Person } from "@prisma/client"; -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/inputs/minimal.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient, UserArgs } from '@prisma/client' 2 | 3 | const prisma = new PrismaClient() 4 | 5 | function main(){ 6 | const user = prisma.user.findOne({ 7 | where: { 8 | id: "test" 9 | } 10 | }) 11 | } 12 | const findOne = 'findOne' 13 | const func = findOne() 14 | const obj = user.findOne() 15 | 16 | function test(){ 17 | const args: UserArgs; 18 | } 19 | 20 | function dollar(){ 21 | prisma.transaction() 22 | prisma.connect() 23 | prisma.disconnect() 24 | prisma.executeRaw() 25 | prisma.on() 26 | prisma.use() 27 | prisma.queryRaw() 28 | 29 | prisma.$transaction() 30 | prisma.$connect() 31 | prisma.$disconnect() 32 | prisma.$executeRaw() 33 | prisma.$on() 34 | prisma.$use() 35 | prisma.$queryRaw() 36 | } 37 | 38 | const transaction = "transaction" 39 | const connect = "connect" 40 | const disconnect = "disconnect" 41 | const executeRaw = "executeRaw" 42 | const on = "on" 43 | const use = "use" 44 | const queryRaw = "queryRaw" 45 | 46 | test.transaction() 47 | test.connect() 48 | test.disconnect() 49 | test.executeRaw() 50 | test.on() 51 | test.use() 52 | test.queryRaw() 53 | // in the code -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/custom-output/.gitignore: -------------------------------------------------------------------------------- 1 | ignore-me -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/custom-output/generated/client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": ".prisma/client", 3 | "main": "index.js", 4 | "types": "index.d.ts" 5 | } -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/custom-output/generated/client/query-engine-debian-openssl-1.1.x: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prisma/codemods/db3fea927c79ef4c48a3df3876d1724e4e451e78/tests/__fixtures__/update-2.12/projects/custom-output/generated/client/query-engine-debian-openssl-1.1.x -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/custom-output/generated/client/schema.prisma: -------------------------------------------------------------------------------- 1 | generator client { 2 | provider = "prisma-client-js" 3 | output = "../generated/client" 4 | } 5 | 6 | datasource db { 7 | provider = "sqlite" 8 | url = env("DOTENV_ROOT_PRISMA_SHOULD_WORK") 9 | } 10 | 11 | model Post { 12 | id Int @default(autoincrement()) @id 13 | createdAt DateTime @default(now()) 14 | title String 15 | content String? 16 | published Boolean @default(false) 17 | author User @relation(fields: [authorId], references: [id]) 18 | authorId Int 19 | } 20 | 21 | model Profile { 22 | id Int @default(autoincrement()) @id 23 | bio String? 24 | user User @relation(fields: [userId], references: [id]) 25 | userId Int @unique 26 | } 27 | 28 | model User { 29 | id Int @default(autoincrement()) @id 30 | email String @unique 31 | name String? 32 | posts Post[] 33 | profile Profile? 34 | } -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/custom-output/l1.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PrismaClient, 3 | Post, 4 | User, 5 | prismaVersion, 6 | FindManyMachineDataArgs, 7 | LikeUpdateManyArgs, 8 | sql, 9 | join, 10 | empty, 11 | raw, 12 | Sql 13 | } from './generated/client' 14 | 15 | // tslint:disable 16 | 17 | // This file will not be executed, just compiled to check if the typings are valid 18 | async function main() { 19 | const prisma = new PrismaClient({ 20 | log: [ 21 | { 22 | emit: 'event', 23 | level: 'query', 24 | }, 25 | ], 26 | datasources: { 27 | db: { 28 | url: 'file:dev.db', 29 | }, 30 | }, 31 | }) 32 | const user = prisma.user.findOne({ 33 | where: { 34 | id: "tests" 35 | } 36 | }) 37 | 38 | prisma.on('query', (a) => { 39 | // 40 | }) 41 | 42 | prismaVersion.client 43 | 44 | const x: Sql = sql`SELECT * FROM ${raw('User')} WHERE 'id' in ${join([ 45 | 1, 46 | 2, 47 | 3, 48 | ])} ${empty} ` 49 | 50 | const queryRaw1 = await prisma.$queryRaw`SELECT * FROM User WHERE id = 1` 51 | const queryRaw2 = await prisma.$queryRaw`SELECT * FROM User WHERE id = ${1}` 52 | const queryRaw3 = await prisma.$queryRaw( 53 | `SELECT * FROM User WHERE id = $1`, 54 | 2, 55 | ) 56 | const queryRaw4 = await prisma.$queryRaw( 57 | sql`SELECT * FROM User WHERE id = ${1}`, 58 | ) 59 | const queryRaw5 = await prisma.$queryRaw( 60 | sql`SELECT * FROM User ${sql`WHERE id = ${1}`}`, 61 | ) 62 | 63 | const executeRaw1 = await prisma.$executeRaw`SELECT * FROM User WHERE id = 1` 64 | const executeRaw2 = await prisma.$executeRaw`SELECT * FROM User WHERE id = ${1}` 65 | const executeRaw3 = await prisma.$executeRaw( 66 | `SELECT * FROM User WHERE id = $1`, 67 | 2, 68 | ) 69 | const executeRaw4 = await prisma.$executeRaw( 70 | sql`SELECT * FROM User WHERE id = ${1}`, 71 | ) 72 | const executeRaw5 = await prisma.$executeRaw( 73 | sql`SELECT * FROM User ${sql`WHERE id = ${1}`}`, 74 | ) 75 | 76 | const result1 = await prisma.user.findMany({ 77 | where: { 78 | posts: { 79 | some: { 80 | author: { 81 | AND: { 82 | id: '5', 83 | posts: { 84 | some: { 85 | author: { 86 | posts: { 87 | some: { 88 | title: '5', 89 | }, 90 | }, 91 | }, 92 | }, 93 | }, 94 | }, 95 | }, 96 | }, 97 | }, 98 | }, 99 | }) 100 | 101 | result1[0]!.email 102 | result1[0]!.id 103 | result1[0]!.name 104 | 105 | const result2: { 106 | id: string 107 | createdAt: Date 108 | updatedAt: Date 109 | published: boolean 110 | title: string 111 | content: string | null 112 | author: User | null 113 | } | null = await prisma.post.findOne({ 114 | where: { 115 | id: '', 116 | }, 117 | include: { 118 | author: true, 119 | }, 120 | }) 121 | 122 | const result3: 'Please either choose `select` or `include`' = await prisma.post.findMany( 123 | { 124 | select: {}, 125 | include: {}, 126 | }, 127 | ) 128 | 129 | const result4: Array<{ 130 | id: string 131 | author: { 132 | name: string | null 133 | } | null 134 | }> = await prisma.post.findMany({ 135 | select: { 136 | id: true, 137 | author: { 138 | select: { 139 | name: true, 140 | }, 141 | }, 142 | }, 143 | }) 144 | 145 | const result5: Post = await prisma.post.create({ 146 | data: { 147 | published: false, 148 | title: 'Title', 149 | }, 150 | }) 151 | 152 | await prisma.post.delete({ 153 | where: { 154 | id: '', 155 | }, 156 | }) 157 | 158 | await prisma.post.upsert({ 159 | create: { 160 | published: false, 161 | title: 'Title', 162 | }, 163 | update: { 164 | published: true, 165 | }, 166 | where: { 167 | id: '6', 168 | }, 169 | }) 170 | 171 | await prisma.post.updateMany({ 172 | data: { 173 | published: false, 174 | }, 175 | }) 176 | 177 | const count: number = await prisma.post.count({ 178 | where: { 179 | published: false, 180 | }, 181 | }) 182 | 183 | const $disconnect: Promise = prisma.$disconnect() 184 | 185 | // Trick to define a "positive" test, if "include" is NOT in "FindManyMachineDataArgs" 186 | type X = keyof FindManyMachineDataArgs 187 | type Y = 'include' extends X ? number : string 188 | const y: Y = 'string' 189 | 190 | // Test for https://github.com/prisma/prisma-client-js/issues/615 191 | const users = await prisma.user.findMany({ 192 | include: { 193 | posts: { 194 | include: { 195 | author: true, 196 | }, 197 | orderBy: { 198 | title: 'asc', 199 | }, 200 | }, 201 | }, 202 | }) 203 | 204 | const id = users[0].posts[0].author?.id 205 | 206 | const like = await prisma.like.findOne({ 207 | where: { 208 | userId_postId: { 209 | postId: '', 210 | userId: '', 211 | }, 212 | }, 213 | include: { post: true }, 214 | }) 215 | 216 | like!.post 217 | 218 | const like2 = await prisma.like.upsert({ 219 | where: { 220 | userId_postId: { 221 | userId: '', 222 | postId: '', 223 | }, 224 | }, 225 | create: { 226 | post: { connect: { id: '' } }, 227 | user: { connect: { id: '' } }, 228 | }, 229 | update: {}, 230 | include: { post: true }, 231 | }) 232 | 233 | like2!.post 234 | 235 | // make sure, that null is not allowed for this type 236 | type LikeUpdateIdType = LikeUpdateManyArgs['data']['id'] 237 | type AllowsNull = null extends LikeUpdateIdType ? true : false 238 | const allowsNull: AllowsNull = false 239 | 240 | // check if listing of `set` is done in nested relations 241 | // https://github.com/prisma/prisma/issues/3497 242 | await prisma.user.update({ 243 | where: { 244 | id: '6', 245 | }, 246 | data: { 247 | posts: { 248 | update: { 249 | data: { 250 | title: 'something', 251 | }, 252 | where: { 253 | id: 'whatever', 254 | }, 255 | }, 256 | }, 257 | }, 258 | }) 259 | 260 | await prisma.user.update({ 261 | where: { 262 | id: '6', 263 | }, 264 | data: { 265 | posts: { 266 | updateMany: { 267 | data: { 268 | title: 'something', 269 | }, 270 | where: { 271 | id: 'whatever', 272 | }, 273 | }, 274 | }, 275 | }, 276 | }) 277 | 278 | await prisma.post.update({ 279 | where: { 280 | id: '6', 281 | }, 282 | data: { 283 | author: { 284 | update: { 285 | name: 'something', 286 | }, 287 | }, 288 | }, 289 | }) 290 | } 291 | 292 | main().catch((e) => { 293 | console.error(e) 294 | }) 295 | 296 | function dollar(){ 297 | prisma.transaction() 298 | prisma.connect() 299 | prisma.disconnect() 300 | prisma.executeRaw() 301 | prisma.on() 302 | prisma.use() 303 | prisma.queryRaw() 304 | 305 | prisma.$transaction() 306 | prisma.$connect() 307 | prisma.$disconnect() 308 | prisma.$executeRaw() 309 | prisma.$on() 310 | prisma.$use() 311 | prisma.$queryRaw() 312 | } 313 | 314 | const transaction = "transaction" 315 | const connect = "connect" 316 | const disconnect = "disconnect" 317 | const executeRaw = "executeRaw" 318 | const on = "on" 319 | const use = "use" 320 | const queryRaw = "queryRaw" 321 | 322 | test.transaction() 323 | test.connect() 324 | test.disconnect() 325 | test.executeRaw() 326 | test.on() 327 | test.use() 328 | test.queryRaw() -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/custom-output/l2/l1.ts: -------------------------------------------------------------------------------- 1 | import { 2 | PrismaClient, 3 | Post, 4 | User, 5 | prismaVersion, 6 | FindManyMachineDataArgs, 7 | LikeUpdateManyArgs, 8 | sql, 9 | join, 10 | empty, 11 | raw, 12 | Sql 13 | } from '../generated/client' 14 | 15 | // tslint:disable 16 | 17 | // This file will not be executed, just compiled to check if the typings are valid 18 | async function main() { 19 | const prisma = new PrismaClient({ 20 | log: [ 21 | { 22 | emit: 'event', 23 | level: 'query', 24 | }, 25 | ], 26 | datasources: { 27 | db: { 28 | url: 'file:dev.db', 29 | }, 30 | }, 31 | }) 32 | const user = prisma.user.findOne({ 33 | where: { 34 | id: "tests" 35 | } 36 | }) 37 | prisma.on('query', (a) => { 38 | // 39 | }) 40 | 41 | prismaVersion.client 42 | 43 | const x: Sql = sql`SELECT * FROM ${raw('User')} WHERE 'id' in ${join([ 44 | 1, 45 | 2, 46 | 3, 47 | ])} ${empty} ` 48 | 49 | const queryRaw1 = await prisma.$queryRaw`SELECT * FROM User WHERE id = 1` 50 | const queryRaw2 = await prisma.$queryRaw`SELECT * FROM User WHERE id = ${1}` 51 | const queryRaw3 = await prisma.$queryRaw( 52 | `SELECT * FROM User WHERE id = $1`, 53 | 2, 54 | ) 55 | const queryRaw4 = await prisma.$queryRaw( 56 | sql`SELECT * FROM User WHERE id = ${1}`, 57 | ) 58 | const queryRaw5 = await prisma.$queryRaw( 59 | sql`SELECT * FROM User ${sql`WHERE id = ${1}`}`, 60 | ) 61 | 62 | const executeRaw1 = await prisma.$executeRaw`SELECT * FROM User WHERE id = 1` 63 | const executeRaw2 = await prisma.$executeRaw`SELECT * FROM User WHERE id = ${1}` 64 | const executeRaw3 = await prisma.$executeRaw( 65 | `SELECT * FROM User WHERE id = $1`, 66 | 2, 67 | ) 68 | const executeRaw4 = await prisma.$executeRaw( 69 | sql`SELECT * FROM User WHERE id = ${1}`, 70 | ) 71 | const executeRaw5 = await prisma.$executeRaw( 72 | sql`SELECT * FROM User ${sql`WHERE id = ${1}`}`, 73 | ) 74 | 75 | const result1 = await prisma.user.findMany({ 76 | where: { 77 | posts: { 78 | some: { 79 | author: { 80 | AND: { 81 | id: '5', 82 | posts: { 83 | some: { 84 | author: { 85 | posts: { 86 | some: { 87 | title: '5', 88 | }, 89 | }, 90 | }, 91 | }, 92 | }, 93 | }, 94 | }, 95 | }, 96 | }, 97 | }, 98 | }) 99 | 100 | result1[0]!.email 101 | result1[0]!.id 102 | result1[0]!.name 103 | 104 | const result2: { 105 | id: string 106 | createdAt: Date 107 | updatedAt: Date 108 | published: boolean 109 | title: string 110 | content: string | null 111 | author: User | null 112 | } | null = await prisma.post.findOne({ 113 | where: { 114 | id: '', 115 | }, 116 | include: { 117 | author: true, 118 | }, 119 | }) 120 | 121 | const result3: 'Please either choose `select` or `include`' = await prisma.post.findMany( 122 | { 123 | select: {}, 124 | include: {}, 125 | }, 126 | ) 127 | 128 | const result4: Array<{ 129 | id: string 130 | author: { 131 | name: string | null 132 | } | null 133 | }> = await prisma.post.findMany({ 134 | select: { 135 | id: true, 136 | author: { 137 | select: { 138 | name: true, 139 | }, 140 | }, 141 | }, 142 | }) 143 | 144 | const result5: Post = await prisma.post.create({ 145 | data: { 146 | published: false, 147 | title: 'Title', 148 | }, 149 | }) 150 | 151 | await prisma.post.delete({ 152 | where: { 153 | id: '', 154 | }, 155 | }) 156 | 157 | await prisma.post.upsert({ 158 | create: { 159 | published: false, 160 | title: 'Title', 161 | }, 162 | update: { 163 | published: true, 164 | }, 165 | where: { 166 | id: '6', 167 | }, 168 | }) 169 | 170 | await prisma.post.updateMany({ 171 | data: { 172 | published: false, 173 | }, 174 | }) 175 | 176 | const count: number = await prisma.post.count({ 177 | where: { 178 | published: false, 179 | }, 180 | }) 181 | 182 | const $disconnect: Promise = prisma.$disconnect() 183 | 184 | // Trick to define a "positive" test, if "include" is NOT in "FindManyMachineDataArgs" 185 | type X = keyof FindManyMachineDataArgs 186 | type Y = 'include' extends X ? number : string 187 | const y: Y = 'string' 188 | 189 | // Test for https://github.com/prisma/prisma-client-js/issues/615 190 | const users = await prisma.user.findMany({ 191 | include: { 192 | posts: { 193 | include: { 194 | author: true, 195 | }, 196 | orderBy: { 197 | title: 'asc', 198 | }, 199 | }, 200 | }, 201 | }) 202 | 203 | const id = users[0].posts[0].author?.id 204 | 205 | const like = await prisma.like.findOne({ 206 | where: { 207 | userId_postId: { 208 | postId: '', 209 | userId: '', 210 | }, 211 | }, 212 | include: { post: true }, 213 | }) 214 | 215 | like!.post 216 | 217 | const like2 = await prisma.like.upsert({ 218 | where: { 219 | userId_postId: { 220 | userId: '', 221 | postId: '', 222 | }, 223 | }, 224 | create: { 225 | post: { connect: { id: '' } }, 226 | user: { connect: { id: '' } }, 227 | }, 228 | update: {}, 229 | include: { post: true }, 230 | }) 231 | 232 | like2!.post 233 | 234 | // make sure, that null is not allowed for this type 235 | type LikeUpdateIdType = LikeUpdateManyArgs['data']['id'] 236 | type AllowsNull = null extends LikeUpdateIdType ? true : false 237 | const allowsNull: AllowsNull = false 238 | 239 | // check if listing of `set` is done in nested relations 240 | // https://github.com/prisma/prisma/issues/3497 241 | await prisma.user.update({ 242 | where: { 243 | id: '6', 244 | }, 245 | data: { 246 | posts: { 247 | update: { 248 | data: { 249 | title: 'something', 250 | }, 251 | where: { 252 | id: 'whatever', 253 | }, 254 | }, 255 | }, 256 | }, 257 | }) 258 | 259 | await prisma.user.update({ 260 | where: { 261 | id: '6', 262 | }, 263 | data: { 264 | posts: { 265 | updateMany: { 266 | data: { 267 | title: 'something', 268 | }, 269 | where: { 270 | id: 'whatever', 271 | }, 272 | }, 273 | }, 274 | }, 275 | }) 276 | 277 | await prisma.post.update({ 278 | where: { 279 | id: '6', 280 | }, 281 | data: { 282 | author: { 283 | update: { 284 | name: 'something', 285 | }, 286 | }, 287 | }, 288 | }) 289 | } 290 | 291 | main().catch((e) => { 292 | console.error(e) 293 | }) 294 | -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/custom-output/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "minimal", 3 | "dependencies": { 4 | "@prisma/cli": "^2.10.2", 5 | "@prisma/client": "^2.10.2" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/custom-output/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | generator client { 2 | provider = "prisma-client-js" 3 | output = "../generated/client" 4 | } 5 | 6 | datasource db { 7 | provider = "sqlite" 8 | url = env("DOTENV_ROOT_PRISMA_SHOULD_WORK") 9 | } 10 | 11 | model Post { 12 | id Int @default(autoincrement()) @id 13 | createdAt DateTime @default(now()) 14 | title String 15 | content String? 16 | published Boolean @default(false) 17 | author User @relation(fields: [authorId], references: [id]) 18 | authorId Int 19 | } 20 | 21 | model Profile { 22 | id Int @default(autoincrement()) @id 23 | bio String? 24 | user User @relation(fields: [userId], references: [id]) 25 | userId Int @unique 26 | } 27 | 28 | model User { 29 | id Int @default(autoincrement()) @id 30 | email String @unique 31 | name String? 32 | posts Post[] 33 | profile Profile? 34 | } -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/issues/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/issues/issue-18.ts: -------------------------------------------------------------------------------- 1 | import { Person } from "@prisma/client"; 2 | 3 | const person = {where: { 4 | Person: { id: personId }, 5 | expiresAt: { gt: new Date() } 6 | }, 7 | } 8 | console.log(person); 9 | -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/issues/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "@prisma/cli": "^2.12.0", 4 | "@prisma/codemods": "^0.5.1" 5 | }, 6 | "dependencies": { 7 | "@prisma/client": "^2.12.0" 8 | }, 9 | "type": "module", 10 | "scripts": { 11 | "test": "codemods namespace ./index.js" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/issues/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | // This is your Prisma schema file, 2 | // learn more about it in the docs: https://pris.ly/d/prisma-schema 3 | 4 | datasource db { 5 | provider = "sqlite" 6 | url = "file:./dev.db" 7 | } 8 | 9 | generator client { 10 | provider = "prisma-client-js" 11 | } 12 | 13 | model Person { 14 | name String @id 15 | } 16 | -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/prisma-codemods-issue-6-main/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/prisma-codemods-issue-6-main/index.js: -------------------------------------------------------------------------------- 1 | import { Person as LocalPerson } from "./local-file"; 2 | import { Person } from "@prisma/client"; 3 | 4 | /** @type {Person} */ 5 | const person = new LocalPerson(); 6 | 7 | console.log(person); 8 | -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/prisma-codemods-issue-6-main/local-file.js: -------------------------------------------------------------------------------- 1 | export class Person { 2 | constructor() { 3 | console.log("hello, everything is good"); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/prisma-codemods-issue-6-main/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "@prisma/cli": "^2.12.0", 4 | "@prisma/codemods": "^0.5.1" 5 | }, 6 | "dependencies": { 7 | "@prisma/client": "^2.12.0" 8 | }, 9 | "type": "module", 10 | "scripts": { 11 | "test": "codemods namespace ./index.js" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/prisma-codemods-issue-6-main/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | // This is your Prisma schema file, 2 | // learn more about it in the docs: https://pris.ly/d/prisma-schema 3 | 4 | datasource db { 5 | provider = "sqlite" 6 | url = "file:./dev.db" 7 | } 8 | 9 | generator client { 10 | provider = "prisma-client-js" 11 | } 12 | 13 | model Person { 14 | name String @id 15 | } 16 | -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/prisma-codemods-issue-6-main/readme.md: -------------------------------------------------------------------------------- 1 | # @prisma/codemods issue #6 2 | 3 | ## Reproduction 4 | 5 | 1. Clone repo 6 | 2. Run `yarn` (other package managers may also work) 7 | 3. Run `yarn test` or `npm test` 8 | 4. Observe if the imports are valid (`Person as LocalPerson` from `./local-file` should not be changed) 9 | -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/throw-missing-schema/index.js: -------------------------------------------------------------------------------- 1 | import { Person as LocalPerson } from "./local-file"; 2 | import { Person } from "@prisma/client"; 3 | 4 | /** @type {Person} */ 5 | const person = new LocalPerson(); 6 | 7 | console.log(person); 8 | -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/throw-missing-schema/local-file.js: -------------------------------------------------------------------------------- 1 | export class Person { 2 | constructor() { 3 | console.log("hello, everything is good"); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/throw-missing-schema/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "@prisma/cli": "^2.12.0", 4 | "@prisma/codemods": "^0.5.1" 5 | }, 6 | "dependencies": { 7 | "@prisma/client": "^2.12.0" 8 | }, 9 | "type": "module", 10 | "scripts": { 11 | "test": "codemods namespace ./index.js" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/__fixtures__/update-2.12/projects/throw-missing-schema/readme.md: -------------------------------------------------------------------------------- 1 | # @prisma/codemods issue #6 2 | 3 | ## Reproduction 4 | 5 | 1. Clone repo 6 | 2. Run `yarn` (other package managers may also work) 7 | 3. Run `yarn test` or `npm test` 8 | 4. Observe if the imports are valid (`Person as LocalPerson` from `./local-file` should not be changed) 9 | -------------------------------------------------------------------------------- /tests/__snapshots__/findUnique/input/custom-interface.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`findUnique inputs custom-interface.ts 1`] = ` 4 | export interface IPrismaSession { 5 | data: string | null; 6 | expires: Date; 7 | id: string; 8 | sid: string; 9 | } 10 | interface ICreatePrismaSession extends IPrismaSession { 11 | data: string; 12 | } 13 | interface IFindOneArgs { 14 | select?: { 15 | expires?: boolean; 16 | sid?: boolean; 17 | }; 18 | where: { 19 | sid: string; 20 | }; 21 | } 22 | interface IFindManyArgs { 23 | select?: { 24 | data?: boolean; 25 | expires?: boolean; 26 | sid?: boolean; 27 | }; 28 | where?: { 29 | sid?: string; 30 | }; 31 | } 32 | interface ICreateArgs { 33 | data: ICreatePrismaSession; 34 | } 35 | interface IUpdateArgs { 36 | data: Partial; 37 | where: { sid: string }; 38 | } 39 | interface IDeleteArgs { 40 | where: { sid: string }; 41 | } 42 | export interface IPrisma { 43 | session: { 44 | create(args: ICreateArgs): Promise; 45 | delete(args: IDeleteArgs): Promise; 46 | deleteMany(args?: unknown): Promise; 47 | findMany(args?: IFindManyArgs): Promise; 48 | findOne(args: IFindOneArgs): Promise; 49 | update(args: IUpdateArgs): Promise; 50 | }; 51 | $connect(): Promise; 52 | $disconnect(): Promise; 53 | } 54 | `; 55 | -------------------------------------------------------------------------------- /tests/__snapshots__/findUnique/input/instanceNames.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`findUnique inputs instanceNames.ts 1`] = ` 4 | import whatEverYouWant from './where/ever/you/want' 5 | import another from './somewhere/else' 6 | 7 | 8 | whatEverYouWant.x.findUnique({ where: { id: 'test' } }); 9 | another.x.findUnique({ where: { id: 'test' } }); 10 | `; 11 | -------------------------------------------------------------------------------- /tests/__snapshots__/findUnique/input/issue-20.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`findUnique inputs issue-20.ts 1`] = ` 4 | import { PrismaClient } from '@prisma/client' 5 | 6 | const client = new PrismaClient(); 7 | const anotherOne = new PrismaClient(); 8 | 9 | client.x.findUnique({ where: { id: 'test' } }); 10 | anotherOne.x.findUnique({ where: { id: 'test' } }); 11 | `; 12 | -------------------------------------------------------------------------------- /tests/__snapshots__/findUnique/input/minimal.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`findUnique inputs minimal.ts 1`] = ` 4 | import { PrismaClient } from '@prisma/client' 5 | 6 | const prisma = new PrismaClient() 7 | 8 | function main(){ 9 | const user = prisma.user.findUnique({ 10 | where: { 11 | id: "test" 12 | } 13 | }) 14 | } 15 | const findOne = 'findOne' 16 | const func = findOne() 17 | const obj = user.findOne() 18 | 19 | async function f(){ 20 | let output = await this.prisma.genUser.findUnique({ 21 | where:{} 22 | }); 23 | } 24 | `; 25 | -------------------------------------------------------------------------------- /tests/__snapshots__/findUnique/input/nexus-schema.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`findUnique inputs nexus-schema.ts 1`] = ` 4 | export const login = mutationField('login', { 5 | type: 'User', 6 | args: { 7 | email: stringArg({ required: true }), 8 | password: stringArg({ required: true }), 9 | }, 10 | async resolve(parent, { email, password }, context) { 11 | const user = await context.prisma.user.findUnique({ 12 | where: { email }, 13 | }) 14 | return user 15 | } 16 | }) 17 | `; 18 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/input/decimal.js: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace inputs decimal.js 1`] = ` 4 | import { PrismaClient, Prisma } from '@prisma/client'; 5 | 6 | async function main() { 7 | const prisma = new PrismaClient() 8 | 9 | const a = await prisma.a.findFirst() 10 | const b = await prisma.b.findFirst({ 11 | where: { 12 | decFloat: new Prisma.Decimal('1.23') 13 | } 14 | }) 15 | const c = await prisma.c.findFirst() 16 | const d = await prisma.d.findFirst() 17 | const e = await prisma.e.findFirst() 18 | 19 | } 20 | 21 | main() 22 | 23 | `; 24 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/input/decimal.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace inputs decimal.ts 1`] = ` 4 | import { PrismaClient, Prisma } from '@prisma/client'; 5 | 6 | async function main() { 7 | const prisma = new PrismaClient() 8 | 9 | const a: null | { 10 | id: string 11 | email: string 12 | name: string | null 13 | int: number 14 | sInt: number 15 | bInt: BigInt 16 | serial: number 17 | sSerial: number 18 | bSerial: number 19 | inc_int: number 20 | inc_sInt: number 21 | inc_bInt: BigInt 22 | } = await prisma.a.findFirst() 23 | const b = await prisma.b.findFirst({ 24 | where: { 25 | decFloat: new Prisma.Decimal('1.23') 26 | } 27 | }) 28 | const c = await prisma.c.findFirst() 29 | const d: null | { 30 | id: string 31 | bool: boolean 32 | byteA: Buffer 33 | xml: string 34 | json: Prisma.JsonValue 35 | jsonb: Prisma.JsonValue 36 | } = await prisma.d.findFirst() 37 | const e = await prisma.e.findFirst() 38 | 39 | } 40 | 41 | main() 42 | 43 | `; 44 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/input/dot-prisma.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace inputs dot-prisma.ts 1`] = ` 4 | import AWS from 'aws-sdk' 5 | import { Prisma } from '.prisma/client'; 6 | import { makeEmail } from '../../lib/mail' 7 | 8 | AWS.config.credentials = new AWS.Credentials( 9 | process.env.JAWS_ACCESS_KEY_ID!, 10 | process.env.JAWS_SECRET_ACCESS_KEY!, 11 | ) 12 | const sqs = new AWS.SQS({ region: 'us-east-2' }) 13 | 14 | type SendCommentNotificationArgs = { 15 | post: Prisma.Post 16 | thread: Prisma.Thread 17 | comment: Prisma.Comment 18 | commentAuthor: Prisma.User 19 | user: Prisma.User 20 | } 21 | 22 | type SendCommentThanksNotificationArgs = { 23 | post: Prisma.Post 24 | thread: Prisma.Thread 25 | comment: Prisma.Comment 26 | commentAuthor: Prisma.User 27 | commentThanksAuthor: Prisma.User 28 | } 29 | 30 | type SendPostCommentNotificationArgs = { 31 | post: Prisma.Post 32 | postAuthor: Prisma.User 33 | postComment: Prisma.PostComment 34 | postCommentAuthor: Prisma.User 35 | } 36 | 37 | type sendPasswordResetTokenEmailArgs = { 38 | user: Prisma.User 39 | resetToken: string 40 | } 41 | 42 | type sendNewBadgeEmailArgs = { 43 | badgeType: Prisma.BadgeType 44 | user: Prisma.User 45 | } 46 | 47 | type EmailParams = { 48 | from: string 49 | to: string 50 | subject: string 51 | html: string 52 | } 53 | 54 | type SqsParams = { 55 | MessageBody: string 56 | QueueUrl: string 57 | } 58 | 59 | export const sendJmail = (emailParams: EmailParams) => { 60 | if (!process.env.JMAIL_QUEUE_URL) { 61 | if (process.env.NODE_ENV === 'production') { 62 | throw new Error('NODE_ENV is prod, but no JMAIL_QUEUE_URL is specified. Something is probably very wrong.') 63 | } 64 | 65 | // We don't have a jmail queue url, so let's just spit this out to the 66 | // console for debugging 67 | console.info('Would have sent the follwing email data to the jmail queue if I had a JMAIL_QUEUE_URL:') 68 | console.info(emailParams) 69 | return new Promise(res => res()) 70 | } 71 | 72 | const params: SqsParams = { 73 | MessageBody: JSON.stringify(emailParams), 74 | QueueUrl: process.env.JMAIL_QUEUE_URL!, 75 | } 76 | 77 | return new Promise((res, rej) => { 78 | sqs.sendMessage(params, function (err, data) { 79 | if (err) { 80 | rej(err) 81 | } else { 82 | res(data) 83 | } 84 | }) 85 | }) 86 | } 87 | 88 | export const sendCommentNotification = ({ 89 | post, 90 | thread, 91 | comment, 92 | commentAuthor, 93 | user, 94 | }: SendCommentNotificationArgs) => { 95 | return sendJmail({ 96 | from: 'robin@journaly.com', 97 | to: user.email, 98 | subject: \`New activity on a thread in \${post.title}\`, 99 | html: makeEmail(\` 100 |

Heads up! @\${commentAuthor.handle} commented on a post you're subscribed to!

101 |

Journal entry: \${post.title}

102 |

Comment thread: "\${thread.highlightedContent}"

103 |

Comment: "\${comment.body}"

104 |

Click here to go to your journal entry!

105 | \`), 106 | }) 107 | } 108 | 109 | export const sendCommentThanksNotification = ({ 110 | post, 111 | thread, 112 | comment, 113 | commentAuthor, 114 | commentThanksAuthor, 115 | }: SendCommentThanksNotificationArgs) => { 116 | const commentThanksAuthorDisplayName = commentThanksAuthor.name || commentThanksAuthor.handle 117 | 118 | return sendJmail({ 119 | from: 'robin@journaly.com', 120 | to: commentAuthor.email, 121 | subject: \`\${commentThanksAuthorDisplayName} said thank you!\`, 122 | html: makeEmail(\` 123 |

Heads up! @\${commentThanksAuthorDisplayName} said thank you for your comment on their post!

124 |

Journal entry: \${post.title}

125 |

Comment thread: "\${thread.highlightedContent}"

126 |

Comment: "\${comment.body}"

127 |

Click here to go to your journal entry!

128 | \`), 129 | }) 130 | } 131 | 132 | export const sendPostCommentNotification = ({ 133 | post, 134 | postAuthor, 135 | postComment, 136 | postCommentAuthor, 137 | }: SendPostCommentNotificationArgs) => { 138 | return sendJmail({ 139 | from: 'robin@journaly.com', 140 | to: postAuthor.email, 141 | subject: "You've got feedback!", 142 | html: makeEmail(\` 143 |

Great news! @\${postCommentAuthor.handle} left you some feedback!

144 |

Journal entry: \${post.title}

145 |

Comment: "\${postComment.body}"

146 |

Click here to go to your journal entry!

147 | \`), 148 | }) 149 | } 150 | 151 | export const sendPasswordResetTokenEmail = ({ 152 | user, 153 | resetToken, 154 | }: sendPasswordResetTokenEmailArgs) => { 155 | return sendJmail({ 156 | from: 'robin@journaly.com', 157 | to: user.email, 158 | subject: 'Your Password Reset Link', 159 | html: makeEmail(\` 160 |

I heard you were having some trouble logging in. 161 |

Click here to reset your password!

162 |

Please note that the link will expire in 1 hour.

163 |

Warmly,

164 | \`), 165 | }) 166 | } 167 | 168 | const assertUnreachable = (x: never): never => { 169 | throw new Error(\`Didn't expect to get here \${x}\`) 170 | } 171 | 172 | const getBadgeName = (badgeType: Prisma.BadgeType): string => { 173 | switch (badgeType) { 174 | case Prisma.BadgeType.ALPHA_USER: 175 | return 'Alpha User' 176 | case Prisma.BadgeType.BETA_USER: 177 | return 'Beta User' 178 | case Prisma.BadgeType.TEN_POSTS: 179 | return '10 Posts' 180 | case Prisma.BadgeType.ONEHUNDRED_POSTS: 181 | return '100 Posts' 182 | case Prisma.BadgeType.CODE_CONTRIBUTOR: 183 | return 'Code Contributor' 184 | } 185 | 186 | return assertUnreachable(badgeType) 187 | } 188 | 189 | export const sendNewBadgeEmail = ({ 190 | user, 191 | badgeType, 192 | }: sendNewBadgeEmailArgs) => { 193 | return sendJmail({ 194 | from: 'robin@journaly.com', 195 | to: user.email, 196 | subject: 'You earned a new badge!', 197 | html: makeEmail(\` 198 |

Congratulations! You just earned the "\${getBadgeName(badgeType)}" badge on Journaly.

199 |

This badge will now be displayed on your profile page.

200 | \`), 201 | }) 202 | } 203 | 204 | `; 205 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/input/errorImports.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace inputs errorImports.ts 1`] = ` 4 | const { 5 | Prisma, 6 | PrismaClient 7 | } = require('./node_modules/@prisma/client') 8 | 9 | test('blog', async () => { 10 | const requests: any[] = [] 11 | const db = new PrismaClient({ 12 | errorFormat: 'colorless', 13 | __internal: { 14 | hooks: { 15 | beforeRequest: (request) => requests.push(request), 16 | }, 17 | }, 18 | }) 19 | 20 | if (!Prisma.prismaVersion || !Prisma.prismaVersion.client) { 21 | throw new Error(\`prismaVersion missing: \${JSON.stringify(Prisma.prismaVersion)}\`) 22 | } 23 | 24 | // Test connecting and disconnecting all the time 25 | await db.user.findMany() 26 | const posts = await db.user 27 | .findOne({ 28 | where: { 29 | email: 'a@a.de', 30 | }, 31 | }) 32 | .posts() 33 | 34 | expect(posts.length).toBe(0) 35 | db.$disconnect() 36 | expect(requests.length).toBe(2) 37 | 38 | await db.user.findMany() 39 | db.$disconnect() 40 | expect(requests.length).toBe(3) 41 | 42 | const count = await db.user.count() 43 | expect(typeof count === 'number').toBe(true) 44 | 45 | const paramCount = await db.user.count({ 46 | take: 10000, 47 | }) 48 | 49 | expect(typeof paramCount === 'number').toBe(true) 50 | 51 | db.$connect() 52 | await db.$disconnect() 53 | 54 | await new Promise((r) => setTimeout(r, 200)) 55 | db.$connect() 56 | 57 | const userPromise = db.user.findMany() 58 | await userPromise 59 | // @ts-ignore 60 | 61 | await db.$disconnect() 62 | 63 | await db.$connect() 64 | 65 | /** 66 | * queryRaw 67 | */ 68 | 69 | // Test queryRaw(string) 70 | const rawQuery = await db.$queryRaw('SELECT 1') 71 | expect(rawQuery[0]['1']).toBe(1) 72 | 73 | // Test queryRaw(string, values) 74 | const rawQueryWithValues = await db.$queryRaw( 75 | 'SELECT $1 AS name, $2 AS id', 76 | 'Alice', 77 | 42, 78 | ) 79 | 80 | expect(rawQueryWithValues[0]).toEqual({ 81 | name: 'Alice', 82 | id: 42, 83 | }) 84 | 85 | // Test queryRaw\`\` 86 | const rawQueryTemplate = await db.$queryRaw\`SELECT 1\` 87 | expect(rawQueryTemplate[0]['1']).toBe(1) 88 | 89 | // Test queryRaw\`\` with \${param} 90 | const rawQueryTemplateWithParams = await db.$queryRaw\`SELECT * FROM User WHERE name = \${'Alice'}\` 91 | expect(rawQueryTemplateWithParams[0].name).toBe('Alice') 92 | 93 | // Test queryRaw\`\` with prisma.sql\`\` 94 | const rawQueryTemplateFromSqlTemplate = await db.$queryRaw( 95 | Prisma.sql\` 96 | SELECT \${Prisma.join([Prisma.raw('email'), Prisma.raw('id'), Prisma.raw('name')])} 97 | FROM \${Prisma.raw('User')} 98 | \${Prisma.sql\`WHERE name = \${'Alice'}\`} 99 | \${Prisma.empty} 100 | \`, 101 | ) 102 | expect(rawQueryTemplateFromSqlTemplate[0].name).toBe('Alice') 103 | 104 | /** 105 | * .$executeRaw( 106 | */ 107 | 108 | // Test .$executeRaw((string) 109 | const executeRaw = await db.$executeRaw( 110 | 'UPDATE User SET name = $1 WHERE id = $2', 111 | 'name', 112 | 'id', 113 | ) 114 | expect(executeRaw).toBe(0) 115 | 116 | // Test .$executeRaw((string, values) 117 | const executeRawWithValues = await db.$executeRaw( 118 | 'UPDATE User SET name = $1 WHERE id = $2', 119 | 'Alice', 120 | 'id', 121 | ) 122 | expect(executeRawWithValues).toBe(0) 123 | 124 | // Test $executeRaw 125 | const $executeRawTemplate = await db.$executeRaw\`UPDATE User SET name = \${'name'} WHERE id = \${'id'}\` 126 | expect($executeRawTemplate).toBe(0) 127 | 128 | // Test validation errors 129 | let validationError 130 | try { 131 | await db.post.create({ 132 | data: {}, 133 | }) 134 | } catch (e) { 135 | validationError = e 136 | } finally { 137 | if ( 138 | !validationError || 139 | !(validationError instanceof Prisma.PrismaClientValidationError) 140 | ) { 141 | throw new Error(\`Validation error is incorrect\`) 142 | } 143 | } 144 | 145 | // Test known request error 146 | let knownRequestError 147 | try { 148 | const result = await db.user.create({ 149 | data: { 150 | email: 'a@a.de', 151 | name: 'Alice', 152 | }, 153 | }) 154 | } catch (e) { 155 | knownRequestError = e 156 | } finally { 157 | if ( 158 | !knownRequestError || 159 | !(knownRequestError instanceof Prisma.PrismaClientKnownRequestError) 160 | ) { 161 | throw new Error(\`Known request error is incorrect\`) 162 | } else { 163 | if (!knownRequestError.message.includes('.user.create()')) { 164 | throw new Error(\`Invalid error: \${knownRequestError.message}\`) 165 | } 166 | } 167 | } 168 | 169 | // relation query where not null 170 | const relationWhereNotNull = await db.user.findMany({ 171 | where: { 172 | profile: { 173 | bio: { not: null }, 174 | }, 175 | }, 176 | }) 177 | expect(relationWhereNotNull).toEqual([]) 178 | 179 | db.$disconnect() 180 | }) 181 | 182 | `; 183 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/input/issue-5.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace inputs issue-5.ts 1`] = ` 4 | import { User as PrismaUser } from '@prisma/client' 5 | import { User } from '../users/UserModel' 6 | 7 | export type UserLike = User | PrismaUser // TypeORM or Prisma user 8 | `; 9 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/input/issue-9.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace inputs issue-9.ts 1`] = ` 4 | // this one 5 | import { PrismaClient, Prisma as PrismaTypes } from "@prisma/client"; 6 | // will be 7 | 8 | // and 9 | 10 | class Prisma extends PrismaClient { 11 | constructor(options?: PrismaTypes.PrismaClientOptions) { 12 | super(options); 13 | } 14 | 15 | async onDelete(args: onDeleteArgs) { 16 | const prismaDelete = new PrismaDelete(this); 17 | await prismaDelete.onDelete(args); 18 | } 19 | } 20 | `; 21 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/input/keyof.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace inputs keyof.ts 1`] = ` 4 | import { PrismaClient, Prisma } from '@prisma/client'; 5 | type X = Required 6 | type Y = { 7 | hello: Prisma.UserArgs 8 | } 9 | type Z = { 10 | [T in keyof Prisma.UserArgs]: Prisma.UserArgs[T] 11 | }[keyof Prisma.UserArgs] 12 | 13 | function a(a: Prisma.UserArgs): Prisma.UserArgs { 14 | return null as any 15 | } 16 | function b() { 17 | } 18 | 19 | `; 20 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/input/minimal-idempotent.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace inputs minimal-idempotent.ts 1`] = ` 4 | import { Prisma, PrismaClient } from '@prisma/client' 5 | import * as fs from 'fs' 6 | function test(){ 7 | const why = fs 8 | } 9 | // in the code 10 | const args: Prisma.UserArgs 11 | `; 12 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/input/minimal.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace inputs minimal.ts 1`] = ` 4 | import { Prisma, PrismaClient } from '@prisma/client' 5 | import * as fs from 'fs' 6 | function test(){ 7 | const why = fs 8 | } 9 | // in the code 10 | const args: Prisma.UserArgs 11 | `; 12 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/input/nextjs.tsx: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace inputs nextjs.tsx 1`] = ` 4 | import React from "react"; 5 | import { GetServerSideProps } from "next"; 6 | import ReactMarkdown from "react-markdown"; 7 | import Layout from "../../components/Layout"; 8 | import Router from "next/router"; 9 | import { PostProps } from "../../components/Post"; 10 | import { PrismaClient, Prisma } from "@prisma/client"; 11 | import { useSession } from "next-auth/client"; 12 | 13 | const prisma = new PrismaClient(); 14 | 15 | export const getServerSideProps: GetServerSideProps = async ({ params }) => { 16 | let args: Prisma.UserArgs; 17 | const test = Prisma.sql.raw("SELECT") 18 | const post = await prisma.post.findOne({ 19 | where: { 20 | id: Number(params?.id) || -1, 21 | }, 22 | include: { 23 | author: { 24 | select: { name: true, email: true }, 25 | }, 26 | }, 27 | }); 28 | return { 29 | props: post, 30 | }; 31 | }; 32 | 33 | async function publishPost(id: number): Promise { 34 | await fetch(\`http://localhost:3000/api/publish/\${id}\`, { 35 | method: "PUT", 36 | }); 37 | await Router.push("/"); 38 | } 39 | 40 | async function deletePost(id: number): Promise { 41 | await fetch(\`http://localhost:3000/api/post/\${id}\`, { 42 | method: "DELETE", 43 | }); 44 | Router.push("/"); 45 | } 46 | 47 | const Post: React.FC = (props) => { 48 | const [session, loading] = useSession(); 49 | if (loading) { 50 | return
Authenticating ...
; 51 | } 52 | const userHasValidSession = Boolean(session); 53 | const postBelongsToUser = session?.user?.email === props.author?.email; 54 | let title = props.title; 55 | if (!props.published) { 56 | title = \`\${title} (Draft)\`; 57 | } 58 | 59 | return ( 60 | 61 |
62 |

{title}

63 |

By {props?.author?.name || "Unknown author"}

64 | 65 | {!props.published && userHasValidSession && postBelongsToUser && ( 66 | 67 | )} 68 | {userHasValidSession && postBelongsToUser && ( 69 | 70 | )} 71 |
72 | 93 |
94 | ); 95 | }; 96 | 97 | export default Post; 98 | 99 | `; 100 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/input/sql.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace inputs sql.ts 1`] = ` 4 | import { PrismaClient, Prisma } from '@prisma/client'; 5 | 6 | // tslint:disable 7 | 8 | // This file will not be executed, just compiled to check if the typings are valid 9 | async function main() { 10 | const prisma = new PrismaClient({ 11 | log: [ 12 | { 13 | emit: 'event', 14 | level: 'query', 15 | }, 16 | ], 17 | datasources: { 18 | db: { 19 | url: 'file:dev.db', 20 | }, 21 | }, 22 | }) 23 | 24 | prisma.on('query', (a) => { 25 | // 26 | }) 27 | 28 | Prisma.prismaVersion.client 29 | 30 | const x: Prisma.Sql = Prisma.sql\`SELECT * FROM \${Prisma.raw('User')} WHERE 'id' in \${Prisma.join([ 31 | 1, 32 | 2, 33 | 3, 34 | ])} \${Prisma.empty} \` 35 | 36 | const queryRaw1 = await prisma.$queryRaw\`SELECT * FROM User WHERE id = 1\` 37 | const queryRaw2 = await prisma.$queryRaw\`SELECT * FROM User WHERE id = \${1}\` 38 | const queryRaw3 = await prisma.$queryRaw( 39 | \`SELECT * FROM User WHERE id = $1\`, 40 | 2, 41 | ) 42 | const queryRaw4 = await prisma.$queryRaw( 43 | Prisma.sql\`SELECT * FROM User WHERE id = \${1}\`, 44 | ) 45 | const queryRaw5 = await prisma.$queryRaw( 46 | Prisma.sql\`SELECT * FROM User \${Prisma.sql\`WHERE id = \${1}\`}\`, 47 | ) 48 | 49 | const executeRaw1 = await prisma.$executeRaw\`SELECT * FROM User WHERE id = 1\` 50 | const executeRaw2 = await prisma.$executeRaw\`SELECT * FROM User WHERE id = \${1}\` 51 | const executeRaw3 = await prisma.$executeRaw( 52 | \`SELECT * FROM User WHERE id = $1\`, 53 | 2, 54 | ) 55 | const executeRaw4 = await prisma.$executeRaw( 56 | Prisma.sql\`SELECT * FROM User WHERE id = \${1}\`, 57 | ) 58 | const executeRaw5 = await prisma.$executeRaw( 59 | Prisma.sql\`SELECT * FROM User \${Prisma.sql\`WHERE id = \${1}\`}\`, 60 | ) 61 | 62 | const result1 = await prisma.user.findMany({ 63 | where: { 64 | posts: { 65 | some: { 66 | author: { 67 | AND: { 68 | id: '5', 69 | posts: { 70 | some: { 71 | author: { 72 | posts: { 73 | some: { 74 | title: '5', 75 | }, 76 | }, 77 | }, 78 | }, 79 | }, 80 | }, 81 | }, 82 | }, 83 | }, 84 | }, 85 | }) 86 | 87 | result1[0]!.email 88 | result1[0]!.id 89 | result1[0]!.name 90 | 91 | const result2: { 92 | id: string 93 | createdAt: Date 94 | updatedAt: Date 95 | published: boolean 96 | title: string 97 | content: string | null 98 | author: Prisma.User | null 99 | } | null = await prisma.post.findOne({ 100 | where: { 101 | id: '', 102 | }, 103 | include: { 104 | author: true, 105 | }, 106 | }) 107 | 108 | const result3: 'Please either choose \`select\` or \`include\`' = await prisma.post.findMany( 109 | { 110 | select: {}, 111 | include: {}, 112 | }, 113 | ) 114 | 115 | const result4: Array<{ 116 | id: string 117 | author: { 118 | name: string | null 119 | } | null 120 | }> = await prisma.post.findMany({ 121 | select: { 122 | id: true, 123 | author: { 124 | select: { 125 | name: true, 126 | }, 127 | }, 128 | }, 129 | }) 130 | 131 | const result5: Prisma.Post = await prisma.post.create({ 132 | data: { 133 | published: false, 134 | title: 'Title', 135 | }, 136 | }) 137 | 138 | await prisma.post.delete({ 139 | where: { 140 | id: '', 141 | }, 142 | }) 143 | 144 | await prisma.post.upsert({ 145 | create: { 146 | published: false, 147 | title: 'Title', 148 | }, 149 | update: { 150 | published: true, 151 | }, 152 | where: { 153 | id: '6', 154 | }, 155 | }) 156 | 157 | await prisma.post.updateMany({ 158 | data: { 159 | published: false, 160 | }, 161 | }) 162 | 163 | const count: number = await prisma.post.count({ 164 | where: { 165 | published: false, 166 | }, 167 | }) 168 | 169 | const $disconnect: Promise = prisma.$disconnect() 170 | 171 | // Trick to define a "positive" test, if "include" is NOT in "FindManyMachineDataArgs" 172 | type X = keyof Prisma.FindManyMachineDataArgs 173 | type Y = 'include' extends X ? number : string 174 | const y: Y = 'string' 175 | 176 | // Test for https://github.com/prisma/prisma-client-js/issues/615 177 | const users = await prisma.user.findMany({ 178 | include: { 179 | posts: { 180 | include: { 181 | author: true, 182 | }, 183 | orderBy: { 184 | title: 'asc', 185 | }, 186 | }, 187 | }, 188 | }) 189 | 190 | const id = users[0].posts[0].author?.id 191 | 192 | const like = await prisma.like.findOne({ 193 | where: { 194 | userId_postId: { 195 | postId: '', 196 | userId: '', 197 | }, 198 | }, 199 | include: { post: true }, 200 | }) 201 | 202 | like!.post 203 | 204 | const like2 = await prisma.like.upsert({ 205 | where: { 206 | userId_postId: { 207 | userId: '', 208 | postId: '', 209 | }, 210 | }, 211 | create: { 212 | post: { connect: { id: '' } }, 213 | user: { connect: { id: '' } }, 214 | }, 215 | update: {}, 216 | include: { post: true }, 217 | }) 218 | 219 | like2!.post 220 | 221 | // make sure, that null is not allowed for this type 222 | type LikeUpdateIdType = Prisma.LikeUpdateManyArgs['data']['id'] 223 | type AllowsNull = null extends LikeUpdateIdType ? true : false 224 | const allowsNull: AllowsNull = false 225 | 226 | // check if listing of \`set\` is done in nested relations 227 | // https://github.com/prisma/prisma/issues/3497 228 | await prisma.user.update({ 229 | where: { 230 | id: '6', 231 | }, 232 | data: { 233 | posts: { 234 | update: { 235 | data: { 236 | title: 'something', 237 | }, 238 | where: { 239 | id: 'whatever', 240 | }, 241 | }, 242 | }, 243 | }, 244 | }) 245 | 246 | await prisma.user.update({ 247 | where: { 248 | id: '6', 249 | }, 250 | data: { 251 | posts: { 252 | updateMany: { 253 | data: { 254 | title: 'something', 255 | }, 256 | where: { 257 | id: 'whatever', 258 | }, 259 | }, 260 | }, 261 | }, 262 | }) 263 | 264 | await prisma.post.update({ 265 | where: { 266 | id: '6', 267 | }, 268 | data: { 269 | author: { 270 | update: { 271 | name: 'something', 272 | }, 273 | }, 274 | }, 275 | }) 276 | } 277 | 278 | main().catch((e) => { 279 | console.error(e) 280 | }) 281 | 282 | `; 283 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/projects/custom-output/l1.ts.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace projects custom-output 1`] = ` 4 | import { PrismaClient, Post, User, Prisma } from './generated/client'; 5 | 6 | // tslint:disable 7 | 8 | // This file will not be executed, just compiled to check if the typings are valid 9 | async function main() { 10 | const prisma = new PrismaClient({ 11 | log: [ 12 | { 13 | emit: 'event', 14 | level: 'query', 15 | }, 16 | ], 17 | datasources: { 18 | db: { 19 | url: 'file:dev.db', 20 | }, 21 | }, 22 | }) 23 | 24 | prisma.on('query', (a) => { 25 | // 26 | }) 27 | 28 | Prisma.prismaVersion.client 29 | 30 | const x: Prisma.Sql = Prisma.sql\`SELECT * FROM \${Prisma.raw('User')} WHERE 'id' in \${Prisma.join([ 31 | 1, 32 | 2, 33 | 3, 34 | ])} \${Prisma.empty} \` 35 | 36 | const queryRaw1 = await prisma.$queryRaw\`SELECT * FROM User WHERE id = 1\` 37 | const queryRaw2 = await prisma.$queryRaw\`SELECT * FROM User WHERE id = \${1}\` 38 | const queryRaw3 = await prisma.$queryRaw( 39 | \`SELECT * FROM User WHERE id = $1\`, 40 | 2, 41 | ) 42 | const queryRaw4 = await prisma.$queryRaw( 43 | Prisma.sql\`SELECT * FROM User WHERE id = \${1}\`, 44 | ) 45 | const queryRaw5 = await prisma.$queryRaw( 46 | Prisma.sql\`SELECT * FROM User \${Prisma.sql\`WHERE id = \${1}\`}\`, 47 | ) 48 | 49 | const executeRaw1 = await prisma.$executeRaw\`SELECT * FROM User WHERE id = 1\` 50 | const executeRaw2 = await prisma.$executeRaw\`SELECT * FROM User WHERE id = \${1}\` 51 | const executeRaw3 = await prisma.$executeRaw( 52 | \`SELECT * FROM User WHERE id = $1\`, 53 | 2, 54 | ) 55 | const executeRaw4 = await prisma.$executeRaw( 56 | Prisma.sql\`SELECT * FROM User WHERE id = \${1}\`, 57 | ) 58 | const executeRaw5 = await prisma.$executeRaw( 59 | Prisma.sql\`SELECT * FROM User \${Prisma.sql\`WHERE id = \${1}\`}\`, 60 | ) 61 | 62 | const result1 = await prisma.user.findMany({ 63 | where: { 64 | posts: { 65 | some: { 66 | author: { 67 | AND: { 68 | id: '5', 69 | posts: { 70 | some: { 71 | author: { 72 | posts: { 73 | some: { 74 | title: '5', 75 | }, 76 | }, 77 | }, 78 | }, 79 | }, 80 | }, 81 | }, 82 | }, 83 | }, 84 | }, 85 | }) 86 | 87 | result1[0]!.email 88 | result1[0]!.id 89 | result1[0]!.name 90 | 91 | const result2: { 92 | id: string 93 | createdAt: Date 94 | updatedAt: Date 95 | published: boolean 96 | title: string 97 | content: string | null 98 | author: User | null 99 | } | null = await prisma.post.findOne({ 100 | where: { 101 | id: '', 102 | }, 103 | include: { 104 | author: true, 105 | }, 106 | }) 107 | 108 | const result3: 'Please either choose \`select\` or \`include\`' = await prisma.post.findMany( 109 | { 110 | select: {}, 111 | include: {}, 112 | }, 113 | ) 114 | 115 | const result4: Array<{ 116 | id: string 117 | author: { 118 | name: string | null 119 | } | null 120 | }> = await prisma.post.findMany({ 121 | select: { 122 | id: true, 123 | author: { 124 | select: { 125 | name: true, 126 | }, 127 | }, 128 | }, 129 | }) 130 | 131 | const result5: Post = await prisma.post.create({ 132 | data: { 133 | published: false, 134 | title: 'Title', 135 | }, 136 | }) 137 | 138 | await prisma.post.delete({ 139 | where: { 140 | id: '', 141 | }, 142 | }) 143 | 144 | await prisma.post.upsert({ 145 | create: { 146 | published: false, 147 | title: 'Title', 148 | }, 149 | update: { 150 | published: true, 151 | }, 152 | where: { 153 | id: '6', 154 | }, 155 | }) 156 | 157 | await prisma.post.updateMany({ 158 | data: { 159 | published: false, 160 | }, 161 | }) 162 | 163 | const count: number = await prisma.post.count({ 164 | where: { 165 | published: false, 166 | }, 167 | }) 168 | 169 | const $disconnect: Promise = prisma.$disconnect() 170 | 171 | // Trick to define a "positive" test, if "include" is NOT in "FindManyMachineDataArgs" 172 | type X = keyof Prisma.FindManyMachineDataArgs 173 | type Y = 'include' extends X ? number : string 174 | const y: Y = 'string' 175 | 176 | // Test for https://github.com/prisma/prisma-client-js/issues/615 177 | const users = await prisma.user.findMany({ 178 | include: { 179 | posts: { 180 | include: { 181 | author: true, 182 | }, 183 | orderBy: { 184 | title: 'asc', 185 | }, 186 | }, 187 | }, 188 | }) 189 | 190 | const id = users[0].posts[0].author?.id 191 | 192 | const like = await prisma.like.findOne({ 193 | where: { 194 | userId_postId: { 195 | postId: '', 196 | userId: '', 197 | }, 198 | }, 199 | include: { post: true }, 200 | }) 201 | 202 | like!.post 203 | 204 | const like2 = await prisma.like.upsert({ 205 | where: { 206 | userId_postId: { 207 | userId: '', 208 | postId: '', 209 | }, 210 | }, 211 | create: { 212 | post: { connect: { id: '' } }, 213 | user: { connect: { id: '' } }, 214 | }, 215 | update: {}, 216 | include: { post: true }, 217 | }) 218 | 219 | like2!.post 220 | 221 | // make sure, that null is not allowed for this type 222 | type LikeUpdateIdType = Prisma.LikeUpdateManyArgs['data']['id'] 223 | type AllowsNull = null extends LikeUpdateIdType ? true : false 224 | const allowsNull: AllowsNull = false 225 | 226 | // check if listing of \`set\` is done in nested relations 227 | // https://github.com/prisma/prisma/issues/3497 228 | await prisma.user.update({ 229 | where: { 230 | id: '6', 231 | }, 232 | data: { 233 | posts: { 234 | update: { 235 | data: { 236 | title: 'something', 237 | }, 238 | where: { 239 | id: 'whatever', 240 | }, 241 | }, 242 | }, 243 | }, 244 | }) 245 | 246 | await prisma.user.update({ 247 | where: { 248 | id: '6', 249 | }, 250 | data: { 251 | posts: { 252 | updateMany: { 253 | data: { 254 | title: 'something', 255 | }, 256 | where: { 257 | id: 'whatever', 258 | }, 259 | }, 260 | }, 261 | }, 262 | }) 263 | 264 | await prisma.post.update({ 265 | where: { 266 | id: '6', 267 | }, 268 | data: { 269 | author: { 270 | update: { 271 | name: 'something', 272 | }, 273 | }, 274 | }, 275 | }) 276 | } 277 | 278 | main().catch((e) => { 279 | console.error(e) 280 | }) 281 | 282 | `; 283 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/projects/custom-output/l2/l1.ts.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace projects custom-output 1`] = ` 4 | import { PrismaClient, Post, User, Prisma } from '../generated/client'; 5 | 6 | // tslint:disable 7 | 8 | // This file will not be executed, just compiled to check if the typings are valid 9 | async function main() { 10 | const prisma = new PrismaClient({ 11 | log: [ 12 | { 13 | emit: 'event', 14 | level: 'query', 15 | }, 16 | ], 17 | datasources: { 18 | db: { 19 | url: 'file:dev.db', 20 | }, 21 | }, 22 | }) 23 | 24 | prisma.on('query', (a) => { 25 | // 26 | }) 27 | 28 | Prisma.prismaVersion.client 29 | 30 | const x: Prisma.Sql = Prisma.sql\`SELECT * FROM \${Prisma.raw('User')} WHERE 'id' in \${Prisma.join([ 31 | 1, 32 | 2, 33 | 3, 34 | ])} \${Prisma.empty} \` 35 | 36 | const queryRaw1 = await prisma.$queryRaw\`SELECT * FROM User WHERE id = 1\` 37 | const queryRaw2 = await prisma.$queryRaw\`SELECT * FROM User WHERE id = \${1}\` 38 | const queryRaw3 = await prisma.$queryRaw( 39 | \`SELECT * FROM User WHERE id = $1\`, 40 | 2, 41 | ) 42 | const queryRaw4 = await prisma.$queryRaw( 43 | Prisma.sql\`SELECT * FROM User WHERE id = \${1}\`, 44 | ) 45 | const queryRaw5 = await prisma.$queryRaw( 46 | Prisma.sql\`SELECT * FROM User \${Prisma.sql\`WHERE id = \${1}\`}\`, 47 | ) 48 | 49 | const executeRaw1 = await prisma.$executeRaw\`SELECT * FROM User WHERE id = 1\` 50 | const executeRaw2 = await prisma.$executeRaw\`SELECT * FROM User WHERE id = \${1}\` 51 | const executeRaw3 = await prisma.$executeRaw( 52 | \`SELECT * FROM User WHERE id = $1\`, 53 | 2, 54 | ) 55 | const executeRaw4 = await prisma.$executeRaw( 56 | Prisma.sql\`SELECT * FROM User WHERE id = \${1}\`, 57 | ) 58 | const executeRaw5 = await prisma.$executeRaw( 59 | Prisma.sql\`SELECT * FROM User \${Prisma.sql\`WHERE id = \${1}\`}\`, 60 | ) 61 | 62 | const result1 = await prisma.user.findMany({ 63 | where: { 64 | posts: { 65 | some: { 66 | author: { 67 | AND: { 68 | id: '5', 69 | posts: { 70 | some: { 71 | author: { 72 | posts: { 73 | some: { 74 | title: '5', 75 | }, 76 | }, 77 | }, 78 | }, 79 | }, 80 | }, 81 | }, 82 | }, 83 | }, 84 | }, 85 | }) 86 | 87 | result1[0]!.email 88 | result1[0]!.id 89 | result1[0]!.name 90 | 91 | const result2: { 92 | id: string 93 | createdAt: Date 94 | updatedAt: Date 95 | published: boolean 96 | title: string 97 | content: string | null 98 | author: User | null 99 | } | null = await prisma.post.findOne({ 100 | where: { 101 | id: '', 102 | }, 103 | include: { 104 | author: true, 105 | }, 106 | }) 107 | 108 | const result3: 'Please either choose \`select\` or \`include\`' = await prisma.post.findMany( 109 | { 110 | select: {}, 111 | include: {}, 112 | }, 113 | ) 114 | 115 | const result4: Array<{ 116 | id: string 117 | author: { 118 | name: string | null 119 | } | null 120 | }> = await prisma.post.findMany({ 121 | select: { 122 | id: true, 123 | author: { 124 | select: { 125 | name: true, 126 | }, 127 | }, 128 | }, 129 | }) 130 | 131 | const result5: Post = await prisma.post.create({ 132 | data: { 133 | published: false, 134 | title: 'Title', 135 | }, 136 | }) 137 | 138 | await prisma.post.delete({ 139 | where: { 140 | id: '', 141 | }, 142 | }) 143 | 144 | await prisma.post.upsert({ 145 | create: { 146 | published: false, 147 | title: 'Title', 148 | }, 149 | update: { 150 | published: true, 151 | }, 152 | where: { 153 | id: '6', 154 | }, 155 | }) 156 | 157 | await prisma.post.updateMany({ 158 | data: { 159 | published: false, 160 | }, 161 | }) 162 | 163 | const count: number = await prisma.post.count({ 164 | where: { 165 | published: false, 166 | }, 167 | }) 168 | 169 | const $disconnect: Promise = prisma.$disconnect() 170 | 171 | // Trick to define a "positive" test, if "include" is NOT in "FindManyMachineDataArgs" 172 | type X = keyof Prisma.FindManyMachineDataArgs 173 | type Y = 'include' extends X ? number : string 174 | const y: Y = 'string' 175 | 176 | // Test for https://github.com/prisma/prisma-client-js/issues/615 177 | const users = await prisma.user.findMany({ 178 | include: { 179 | posts: { 180 | include: { 181 | author: true, 182 | }, 183 | orderBy: { 184 | title: 'asc', 185 | }, 186 | }, 187 | }, 188 | }) 189 | 190 | const id = users[0].posts[0].author?.id 191 | 192 | const like = await prisma.like.findOne({ 193 | where: { 194 | userId_postId: { 195 | postId: '', 196 | userId: '', 197 | }, 198 | }, 199 | include: { post: true }, 200 | }) 201 | 202 | like!.post 203 | 204 | const like2 = await prisma.like.upsert({ 205 | where: { 206 | userId_postId: { 207 | userId: '', 208 | postId: '', 209 | }, 210 | }, 211 | create: { 212 | post: { connect: { id: '' } }, 213 | user: { connect: { id: '' } }, 214 | }, 215 | update: {}, 216 | include: { post: true }, 217 | }) 218 | 219 | like2!.post 220 | 221 | // make sure, that null is not allowed for this type 222 | type LikeUpdateIdType = Prisma.LikeUpdateManyArgs['data']['id'] 223 | type AllowsNull = null extends LikeUpdateIdType ? true : false 224 | const allowsNull: AllowsNull = false 225 | 226 | // check if listing of \`set\` is done in nested relations 227 | // https://github.com/prisma/prisma/issues/3497 228 | await prisma.user.update({ 229 | where: { 230 | id: '6', 231 | }, 232 | data: { 233 | posts: { 234 | update: { 235 | data: { 236 | title: 'something', 237 | }, 238 | where: { 239 | id: 'whatever', 240 | }, 241 | }, 242 | }, 243 | }, 244 | }) 245 | 246 | await prisma.user.update({ 247 | where: { 248 | id: '6', 249 | }, 250 | data: { 251 | posts: { 252 | updateMany: { 253 | data: { 254 | title: 'something', 255 | }, 256 | where: { 257 | id: 'whatever', 258 | }, 259 | }, 260 | }, 261 | }, 262 | }) 263 | 264 | await prisma.post.update({ 265 | where: { 266 | id: '6', 267 | }, 268 | data: { 269 | author: { 270 | update: { 271 | name: 'something', 272 | }, 273 | }, 274 | }, 275 | }) 276 | } 277 | 278 | main().catch((e) => { 279 | console.error(e) 280 | }) 281 | 282 | `; 283 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/projects/custom-output/package.json.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace projects custom-output 1`] = ` 4 | { 5 | "name": "minimal", 6 | "dependencies": { 7 | "@prisma/cli": "^2.10.2", 8 | "@prisma/client": "^2.10.2" 9 | } 10 | } 11 | 12 | `; 13 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/projects/custom-output/prisma/schema.prisma.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace projects custom-output 1`] = ` 4 | generator client { 5 | provider = "prisma-client-js" 6 | output = "../generated/client" 7 | } 8 | 9 | datasource db { 10 | provider = "sqlite" 11 | url = env("DOTENV_ROOT_PRISMA_SHOULD_WORK") 12 | } 13 | 14 | model Post { 15 | id Int @default(autoincrement()) @id 16 | createdAt DateTime @default(now()) 17 | title String 18 | content String? 19 | published Boolean @default(false) 20 | author User @relation(fields: [authorId], references: [id]) 21 | authorId Int 22 | } 23 | 24 | model Profile { 25 | id Int @default(autoincrement()) @id 26 | bio String? 27 | user User @relation(fields: [userId], references: [id]) 28 | userId Int @unique 29 | } 30 | 31 | model User { 32 | id Int @default(autoincrement()) @id 33 | email String @unique 34 | name String? 35 | posts Post[] 36 | profile Profile? 37 | } 38 | `; 39 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/projects/minimal/issue-5.ts.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace projects minimal 1`] = ` 4 | import { User as PrismaUser } from '@prisma/client' 5 | import { User } from '../users/UserModel' 6 | 7 | export type UserLike = User | PrismaUser // TypeORM or Prisma user 8 | `; 9 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/projects/minimal/l1.ts.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace projects minimal 1`] = ` 4 | import { PrismaClient, Post, User, Prisma } from '@prisma/client'; 5 | 6 | // tslint:disable 7 | 8 | // This file will not be executed, just compiled to check if the typings are valid 9 | async function main() { 10 | const prisma = new PrismaClient({ 11 | log: [ 12 | { 13 | emit: 'event', 14 | level: 'query', 15 | }, 16 | ], 17 | datasources: { 18 | db: { 19 | url: 'file:dev.db', 20 | }, 21 | }, 22 | }) 23 | 24 | prisma.on('query', (a) => { 25 | // 26 | }) 27 | 28 | Prisma.prismaVersion.client 29 | 30 | const x: Prisma.Sql = Prisma.sql\`SELECT * FROM \${Prisma.raw('User')} WHERE 'id' in \${Prisma.join([ 31 | 1, 32 | 2, 33 | 3, 34 | ])} \${Prisma.empty} \` 35 | 36 | const queryRaw1 = await prisma.$queryRaw\`SELECT * FROM User WHERE id = 1\` 37 | const queryRaw2 = await prisma.$queryRaw\`SELECT * FROM User WHERE id = \${1}\` 38 | const queryRaw3 = await prisma.$queryRaw( 39 | \`SELECT * FROM User WHERE id = $1\`, 40 | 2, 41 | ) 42 | const queryRaw4 = await prisma.$queryRaw( 43 | Prisma.sql\`SELECT * FROM User WHERE id = \${1}\`, 44 | ) 45 | const queryRaw5 = await prisma.$queryRaw( 46 | Prisma.sql\`SELECT * FROM User \${Prisma.sql\`WHERE id = \${1}\`}\`, 47 | ) 48 | 49 | const executeRaw1 = await prisma.$executeRaw\`SELECT * FROM User WHERE id = 1\` 50 | const executeRaw2 = await prisma.$executeRaw\`SELECT * FROM User WHERE id = \${1}\` 51 | const executeRaw3 = await prisma.$executeRaw( 52 | \`SELECT * FROM User WHERE id = $1\`, 53 | 2, 54 | ) 55 | const executeRaw4 = await prisma.$executeRaw( 56 | Prisma.sql\`SELECT * FROM User WHERE id = \${1}\`, 57 | ) 58 | const executeRaw5 = await prisma.$executeRaw( 59 | Prisma.sql\`SELECT * FROM User \${Prisma.sql\`WHERE id = \${1}\`}\`, 60 | ) 61 | 62 | const result1 = await prisma.user.findMany({ 63 | where: { 64 | posts: { 65 | some: { 66 | author: { 67 | AND: { 68 | id: '5', 69 | posts: { 70 | some: { 71 | author: { 72 | posts: { 73 | some: { 74 | title: '5', 75 | }, 76 | }, 77 | }, 78 | }, 79 | }, 80 | }, 81 | }, 82 | }, 83 | }, 84 | }, 85 | }) 86 | 87 | result1[0]!.email 88 | result1[0]!.id 89 | result1[0]!.name 90 | 91 | const result2: { 92 | id: string 93 | createdAt: Date 94 | updatedAt: Date 95 | published: boolean 96 | title: string 97 | content: string | null 98 | author: User | null 99 | } | null = await prisma.post.findOne({ 100 | where: { 101 | id: '', 102 | }, 103 | include: { 104 | author: true, 105 | }, 106 | }) 107 | 108 | const result3: 'Please either choose \`select\` or \`include\`' = await prisma.post.findMany( 109 | { 110 | select: {}, 111 | include: {}, 112 | }, 113 | ) 114 | 115 | const result4: Array<{ 116 | id: string 117 | author: { 118 | name: string | null 119 | } | null 120 | }> = await prisma.post.findMany({ 121 | select: { 122 | id: true, 123 | author: { 124 | select: { 125 | name: true, 126 | }, 127 | }, 128 | }, 129 | }) 130 | 131 | const result5: Post = await prisma.post.create({ 132 | data: { 133 | published: false, 134 | title: 'Title', 135 | }, 136 | }) 137 | 138 | await prisma.post.delete({ 139 | where: { 140 | id: '', 141 | }, 142 | }) 143 | 144 | await prisma.post.upsert({ 145 | create: { 146 | published: false, 147 | title: 'Title', 148 | }, 149 | update: { 150 | published: true, 151 | }, 152 | where: { 153 | id: '6', 154 | }, 155 | }) 156 | 157 | await prisma.post.updateMany({ 158 | data: { 159 | published: false, 160 | }, 161 | }) 162 | 163 | const count: number = await prisma.post.count({ 164 | where: { 165 | published: false, 166 | }, 167 | }) 168 | 169 | const $disconnect: Promise = prisma.$disconnect() 170 | 171 | // Trick to define a "positive" test, if "include" is NOT in "FindManyMachineDataArgs" 172 | type X = keyof Prisma.FindManyMachineDataArgs 173 | type Y = 'include' extends X ? number : string 174 | const y: Y = 'string' 175 | 176 | // Test for https://github.com/prisma/prisma-client-js/issues/615 177 | const users = await prisma.user.findMany({ 178 | include: { 179 | posts: { 180 | include: { 181 | author: true, 182 | }, 183 | orderBy: { 184 | title: 'asc', 185 | }, 186 | }, 187 | }, 188 | }) 189 | 190 | const id = users[0].posts[0].author?.id 191 | 192 | const like = await prisma.like.findOne({ 193 | where: { 194 | userId_postId: { 195 | postId: '', 196 | userId: '', 197 | }, 198 | }, 199 | include: { post: true }, 200 | }) 201 | 202 | like!.post 203 | 204 | const like2 = await prisma.like.upsert({ 205 | where: { 206 | userId_postId: { 207 | userId: '', 208 | postId: '', 209 | }, 210 | }, 211 | create: { 212 | post: { connect: { id: '' } }, 213 | user: { connect: { id: '' } }, 214 | }, 215 | update: {}, 216 | include: { post: true }, 217 | }) 218 | 219 | like2!.post 220 | 221 | // make sure, that null is not allowed for this type 222 | type LikeUpdateIdType = Prisma.LikeUpdateManyArgs['data']['id'] 223 | type AllowsNull = null extends LikeUpdateIdType ? true : false 224 | const allowsNull: AllowsNull = false 225 | 226 | // check if listing of \`set\` is done in nested relations 227 | // https://github.com/prisma/prisma/issues/3497 228 | await prisma.user.update({ 229 | where: { 230 | id: '6', 231 | }, 232 | data: { 233 | posts: { 234 | update: { 235 | data: { 236 | title: 'something', 237 | }, 238 | where: { 239 | id: 'whatever', 240 | }, 241 | }, 242 | }, 243 | }, 244 | }) 245 | 246 | await prisma.user.update({ 247 | where: { 248 | id: '6', 249 | }, 250 | data: { 251 | posts: { 252 | updateMany: { 253 | data: { 254 | title: 'something', 255 | }, 256 | where: { 257 | id: 'whatever', 258 | }, 259 | }, 260 | }, 261 | }, 262 | }) 263 | 264 | await prisma.post.update({ 265 | where: { 266 | id: '6', 267 | }, 268 | data: { 269 | author: { 270 | update: { 271 | name: 'something', 272 | }, 273 | }, 274 | }, 275 | }) 276 | } 277 | 278 | main().catch((e) => { 279 | console.error(e) 280 | }) 281 | 282 | `; 283 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/projects/minimal/l2/l1.ts.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace projects minimal 1`] = ` 4 | import { PrismaClient, Post, User, Prisma } from '@prisma/client'; 5 | 6 | // tslint:disable 7 | 8 | // This file will not be executed, just compiled to check if the typings are valid 9 | async function main() { 10 | const prisma = new PrismaClient({ 11 | log: [ 12 | { 13 | emit: 'event', 14 | level: 'query', 15 | }, 16 | ], 17 | datasources: { 18 | db: { 19 | url: 'file:dev.db', 20 | }, 21 | }, 22 | }) 23 | 24 | prisma.on('query', (a) => { 25 | // 26 | }) 27 | 28 | Prisma.prismaVersion.client 29 | 30 | const x: Prisma.Sql = Prisma.sql\`SELECT * FROM \${Prisma.raw('User')} WHERE 'id' in \${Prisma.join([ 31 | 1, 32 | 2, 33 | 3, 34 | ])} \${Prisma.empty} \` 35 | 36 | const queryRaw1 = await prisma.$queryRaw\`SELECT * FROM User WHERE id = 1\` 37 | const queryRaw2 = await prisma.$queryRaw\`SELECT * FROM User WHERE id = \${1}\` 38 | const queryRaw3 = await prisma.$queryRaw( 39 | \`SELECT * FROM User WHERE id = $1\`, 40 | 2, 41 | ) 42 | const queryRaw4 = await prisma.$queryRaw( 43 | Prisma.sql\`SELECT * FROM User WHERE id = \${1}\`, 44 | ) 45 | const queryRaw5 = await prisma.$queryRaw( 46 | Prisma.sql\`SELECT * FROM User \${Prisma.sql\`WHERE id = \${1}\`}\`, 47 | ) 48 | 49 | const executeRaw1 = await prisma.$executeRaw\`SELECT * FROM User WHERE id = 1\` 50 | const executeRaw2 = await prisma.$executeRaw\`SELECT * FROM User WHERE id = \${1}\` 51 | const executeRaw3 = await prisma.$executeRaw( 52 | \`SELECT * FROM User WHERE id = $1\`, 53 | 2, 54 | ) 55 | const executeRaw4 = await prisma.$executeRaw( 56 | Prisma.sql\`SELECT * FROM User WHERE id = \${1}\`, 57 | ) 58 | const executeRaw5 = await prisma.$executeRaw( 59 | Prisma.sql\`SELECT * FROM User \${Prisma.sql\`WHERE id = \${1}\`}\`, 60 | ) 61 | 62 | const result1 = await prisma.user.findMany({ 63 | where: { 64 | posts: { 65 | some: { 66 | author: { 67 | AND: { 68 | id: '5', 69 | posts: { 70 | some: { 71 | author: { 72 | posts: { 73 | some: { 74 | title: '5', 75 | }, 76 | }, 77 | }, 78 | }, 79 | }, 80 | }, 81 | }, 82 | }, 83 | }, 84 | }, 85 | }) 86 | 87 | result1[0]!.email 88 | result1[0]!.id 89 | result1[0]!.name 90 | 91 | const result2: { 92 | id: string 93 | createdAt: Date 94 | updatedAt: Date 95 | published: boolean 96 | title: string 97 | content: string | null 98 | author: User | null 99 | } | null = await prisma.post.findOne({ 100 | where: { 101 | id: '', 102 | }, 103 | include: { 104 | author: true, 105 | }, 106 | }) 107 | 108 | const result3: 'Please either choose \`select\` or \`include\`' = await prisma.post.findMany( 109 | { 110 | select: {}, 111 | include: {}, 112 | }, 113 | ) 114 | 115 | const result4: Array<{ 116 | id: string 117 | author: { 118 | name: string | null 119 | } | null 120 | }> = await prisma.post.findMany({ 121 | select: { 122 | id: true, 123 | author: { 124 | select: { 125 | name: true, 126 | }, 127 | }, 128 | }, 129 | }) 130 | 131 | const result5: Post = await prisma.post.create({ 132 | data: { 133 | published: false, 134 | title: 'Title', 135 | }, 136 | }) 137 | 138 | await prisma.post.delete({ 139 | where: { 140 | id: '', 141 | }, 142 | }) 143 | 144 | await prisma.post.upsert({ 145 | create: { 146 | published: false, 147 | title: 'Title', 148 | }, 149 | update: { 150 | published: true, 151 | }, 152 | where: { 153 | id: '6', 154 | }, 155 | }) 156 | 157 | await prisma.post.updateMany({ 158 | data: { 159 | published: false, 160 | }, 161 | }) 162 | 163 | const count: number = await prisma.post.count({ 164 | where: { 165 | published: false, 166 | }, 167 | }) 168 | 169 | const $disconnect: Promise = prisma.$disconnect() 170 | 171 | // Trick to define a "positive" test, if "include" is NOT in "FindManyMachineDataArgs" 172 | type X = keyof Prisma.FindManyMachineDataArgs 173 | type Y = 'include' extends X ? number : string 174 | const y: Y = 'string' 175 | 176 | // Test for https://github.com/prisma/prisma-client-js/issues/615 177 | const users = await prisma.user.findMany({ 178 | include: { 179 | posts: { 180 | include: { 181 | author: true, 182 | }, 183 | orderBy: { 184 | title: 'asc', 185 | }, 186 | }, 187 | }, 188 | }) 189 | 190 | const id = users[0].posts[0].author?.id 191 | 192 | const like = await prisma.like.findOne({ 193 | where: { 194 | userId_postId: { 195 | postId: '', 196 | userId: '', 197 | }, 198 | }, 199 | include: { post: true }, 200 | }) 201 | 202 | like!.post 203 | 204 | const like2 = await prisma.like.upsert({ 205 | where: { 206 | userId_postId: { 207 | userId: '', 208 | postId: '', 209 | }, 210 | }, 211 | create: { 212 | post: { connect: { id: '' } }, 213 | user: { connect: { id: '' } }, 214 | }, 215 | update: {}, 216 | include: { post: true }, 217 | }) 218 | 219 | like2!.post 220 | 221 | // make sure, that null is not allowed for this type 222 | type LikeUpdateIdType = Prisma.LikeUpdateManyArgs['data']['id'] 223 | type AllowsNull = null extends LikeUpdateIdType ? true : false 224 | const allowsNull: AllowsNull = false 225 | 226 | // check if listing of \`set\` is done in nested relations 227 | // https://github.com/prisma/prisma/issues/3497 228 | await prisma.user.update({ 229 | where: { 230 | id: '6', 231 | }, 232 | data: { 233 | posts: { 234 | update: { 235 | data: { 236 | title: 'something', 237 | }, 238 | where: { 239 | id: 'whatever', 240 | }, 241 | }, 242 | }, 243 | }, 244 | }) 245 | 246 | await prisma.user.update({ 247 | where: { 248 | id: '6', 249 | }, 250 | data: { 251 | posts: { 252 | updateMany: { 253 | data: { 254 | title: 'something', 255 | }, 256 | where: { 257 | id: 'whatever', 258 | }, 259 | }, 260 | }, 261 | }, 262 | }) 263 | 264 | await prisma.post.update({ 265 | where: { 266 | id: '6', 267 | }, 268 | data: { 269 | author: { 270 | update: { 271 | name: 'something', 272 | }, 273 | }, 274 | }, 275 | }) 276 | } 277 | 278 | main().catch((e) => { 279 | console.error(e) 280 | }) 281 | 282 | `; 283 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/projects/minimal/package.json.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace projects minimal 1`] = ` 4 | { 5 | "name": "minimal", 6 | "dependencies": { 7 | "@prisma/cli": "^2.10.2", 8 | "@prisma/client": "^2.10.2" 9 | } 10 | } 11 | 12 | `; 13 | -------------------------------------------------------------------------------- /tests/__snapshots__/namespace/projects/minimal/prisma/schema.prisma.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`namespace projects minimal 1`] = ` 4 | generator client { 5 | provider = "prisma-client-js" 6 | } 7 | 8 | datasource db { 9 | provider = "sqlite" 10 | url = env("DOTENV_ROOT_PRISMA_SHOULD_WORK") 11 | } 12 | 13 | model Post { 14 | id Int @default(autoincrement()) @id 15 | createdAt DateTime @default(now()) 16 | title String 17 | content String? 18 | published Boolean @default(false) 19 | author User @relation(fields: [authorId], references: [id]) 20 | authorId Int 21 | } 22 | 23 | model Profile { 24 | id Int @default(autoincrement()) @id 25 | bio String? 26 | user User @relation(fields: [userId], references: [id]) 27 | userId Int @unique 28 | } 29 | 30 | model User { 31 | id Int @default(autoincrement()) @id 32 | email String @unique 33 | name String? 34 | posts Post[] 35 | profile Profile? 36 | } 37 | `; 38 | -------------------------------------------------------------------------------- /tests/__snapshots__/to$/input/minimal.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`to$ inputs minimal.ts 1`] = ` 4 | import { PrismaClient } from '@prisma/client' 5 | 6 | const prisma = new PrismaClient() 7 | 8 | function main(){ 9 | prisma.$transaction() 10 | prisma.$connect() 11 | prisma.$disconnect() 12 | prisma.$executeRaw() 13 | prisma.$on() 14 | prisma.$use() 15 | prisma.$queryRaw() 16 | 17 | prisma.$transaction() 18 | prisma.$connect() 19 | prisma.$disconnect() 20 | prisma.$executeRaw() 21 | prisma.$on() 22 | prisma.$use() 23 | prisma.$queryRaw() 24 | // For the people with a transaction table 25 | prisma.transaction.create() 26 | } 27 | 28 | const transaction = "transaction" 29 | const connect = "connect" 30 | const disconnect = "disconnect" 31 | const executeRaw = "executeRaw" 32 | const on = "on" 33 | const use = "use" 34 | const queryRaw = "queryRaw" 35 | 36 | test.transaction() 37 | test.connect() 38 | test.disconnect() 39 | test.executeRaw() 40 | test.on() 41 | test.use() 42 | test.queryRaw() 43 | `; 44 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects throw-missing-schema 1`] = `[Error: Prisma Schema Could Not be found, try specifying the \`--schemaPath ./path/to/schema.prisma\`]`; 4 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/input/issue-5.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 inputs issue-5.ts 1`] = ` 4 | import { User as PrismaUser } from '@prisma/client' 5 | import { User } from '../users/UserModel' 6 | 7 | export type UserLike = User | PrismaUser // TypeORM or Prisma user 8 | `; 9 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/input/issue-6.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 inputs issue-6.ts 1`] = ` 4 | import { Person as LocalPerson } from "./local-file"; 5 | import { Prisma } from "@prisma/client"; 6 | `; 7 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/input/minimal.ts: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 inputs minimal.ts 1`] = ` 4 | import { PrismaClient, Prisma } from '@prisma/client' 5 | 6 | const prisma = new PrismaClient() 7 | 8 | function main(){ 9 | const user = prisma.user.findUnique({ 10 | where: { 11 | id: "test" 12 | } 13 | }) 14 | } 15 | const findOne = 'findOne' 16 | const func = findOne() 17 | const obj = user.findOne() 18 | 19 | function test(){ 20 | const args: Prisma.UserArgs; 21 | } 22 | 23 | function dollar(){ 24 | prisma.$transaction() 25 | prisma.$connect() 26 | prisma.$disconnect() 27 | prisma.$executeRaw() 28 | prisma.$on() 29 | prisma.$use() 30 | prisma.$queryRaw() 31 | 32 | prisma.$transaction() 33 | prisma.$connect() 34 | prisma.$disconnect() 35 | prisma.$executeRaw() 36 | prisma.$on() 37 | prisma.$use() 38 | prisma.$queryRaw() 39 | } 40 | 41 | const transaction = "transaction" 42 | const connect = "connect" 43 | const disconnect = "disconnect" 44 | const executeRaw = "executeRaw" 45 | const on = "on" 46 | const use = "use" 47 | const queryRaw = "queryRaw" 48 | 49 | test.transaction() 50 | test.connect() 51 | test.disconnect() 52 | test.executeRaw() 53 | test.on() 54 | test.use() 55 | test.queryRaw() 56 | // in the code 57 | `; 58 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/custom-output/.gitignore.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects custom-output 1`] = `ignore-me`; 4 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/custom-output/ignore-me/l1.ts.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects custom-output 1`] = ` 4 | import { 5 | PrismaClient, 6 | Post, 7 | User, 8 | prismaVersion, 9 | FindManyMachineDataArgs, 10 | LikeUpdateManyArgs, 11 | sql, 12 | join, 13 | empty, 14 | raw, 15 | Sql 16 | } from './generated/client' 17 | 18 | // tslint:disable 19 | 20 | // This file will not be executed, just compiled to check if the typings are valid 21 | async function main() { 22 | const prisma = new PrismaClient({ 23 | log: [ 24 | { 25 | emit: 'event', 26 | level: 'query', 27 | }, 28 | ], 29 | datasources: { 30 | db: { 31 | url: 'file:dev.db', 32 | }, 33 | }, 34 | }) 35 | const user = prisma.user.findOne({ 36 | where: { 37 | id: "tests" 38 | } 39 | }) 40 | 41 | prisma.on('query', (a) => { 42 | // 43 | }) 44 | 45 | prismaVersion.client 46 | 47 | const x: Sql = sql\`SELECT * FROM \${raw('User')} WHERE 'id' in \${join([ 48 | 1, 49 | 2, 50 | 3, 51 | ])} \${empty} \` 52 | 53 | const queryRaw1 = await prisma.$queryRaw\`SELECT * FROM User WHERE id = 1\` 54 | const queryRaw2 = await prisma.$queryRaw\`SELECT * FROM User WHERE id = \${1}\` 55 | const queryRaw3 = await prisma.$queryRaw( 56 | \`SELECT * FROM User WHERE id = $1\`, 57 | 2, 58 | ) 59 | const queryRaw4 = await prisma.$queryRaw( 60 | sql\`SELECT * FROM User WHERE id = \${1}\`, 61 | ) 62 | const queryRaw5 = await prisma.$queryRaw( 63 | sql\`SELECT * FROM User \${sql\`WHERE id = \${1}\`}\`, 64 | ) 65 | 66 | const executeRaw1 = await prisma.$executeRaw\`SELECT * FROM User WHERE id = 1\` 67 | const executeRaw2 = await prisma.$executeRaw\`SELECT * FROM User WHERE id = \${1}\` 68 | const executeRaw3 = await prisma.$executeRaw( 69 | \`SELECT * FROM User WHERE id = $1\`, 70 | 2, 71 | ) 72 | const executeRaw4 = await prisma.$executeRaw( 73 | sql\`SELECT * FROM User WHERE id = \${1}\`, 74 | ) 75 | const executeRaw5 = await prisma.$executeRaw( 76 | sql\`SELECT * FROM User \${sql\`WHERE id = \${1}\`}\`, 77 | ) 78 | 79 | const result1 = await prisma.user.findMany({ 80 | where: { 81 | posts: { 82 | some: { 83 | author: { 84 | AND: { 85 | id: '5', 86 | posts: { 87 | some: { 88 | author: { 89 | posts: { 90 | some: { 91 | title: '5', 92 | }, 93 | }, 94 | }, 95 | }, 96 | }, 97 | }, 98 | }, 99 | }, 100 | }, 101 | }, 102 | }) 103 | 104 | result1[0]!.email 105 | result1[0]!.id 106 | result1[0]!.name 107 | 108 | const result2: { 109 | id: string 110 | createdAt: Date 111 | updatedAt: Date 112 | published: boolean 113 | title: string 114 | content: string | null 115 | author: User | null 116 | } | null = await prisma.post.findOne({ 117 | where: { 118 | id: '', 119 | }, 120 | include: { 121 | author: true, 122 | }, 123 | }) 124 | 125 | const result3: 'Please either choose \`select\` or \`include\`' = await prisma.post.findMany( 126 | { 127 | select: {}, 128 | include: {}, 129 | }, 130 | ) 131 | 132 | const result4: Array<{ 133 | id: string 134 | author: { 135 | name: string | null 136 | } | null 137 | }> = await prisma.post.findMany({ 138 | select: { 139 | id: true, 140 | author: { 141 | select: { 142 | name: true, 143 | }, 144 | }, 145 | }, 146 | }) 147 | 148 | const result5: Post = await prisma.post.create({ 149 | data: { 150 | published: false, 151 | title: 'Title', 152 | }, 153 | }) 154 | 155 | await prisma.post.delete({ 156 | where: { 157 | id: '', 158 | }, 159 | }) 160 | 161 | await prisma.post.upsert({ 162 | create: { 163 | published: false, 164 | title: 'Title', 165 | }, 166 | update: { 167 | published: true, 168 | }, 169 | where: { 170 | id: '6', 171 | }, 172 | }) 173 | 174 | await prisma.post.updateMany({ 175 | data: { 176 | published: false, 177 | }, 178 | }) 179 | 180 | const count: number = await prisma.post.count({ 181 | where: { 182 | published: false, 183 | }, 184 | }) 185 | 186 | const $disconnect: Promise = prisma.$disconnect() 187 | 188 | // Trick to define a "positive" test, if "include" is NOT in "FindManyMachineDataArgs" 189 | type X = keyof FindManyMachineDataArgs 190 | type Y = 'include' extends X ? number : string 191 | const y: Y = 'string' 192 | 193 | // Test for https://github.com/prisma/prisma-client-js/issues/615 194 | const users = await prisma.user.findMany({ 195 | include: { 196 | posts: { 197 | include: { 198 | author: true, 199 | }, 200 | orderBy: { 201 | title: 'asc', 202 | }, 203 | }, 204 | }, 205 | }) 206 | 207 | const id = users[0].posts[0].author?.id 208 | 209 | const like = await prisma.like.findOne({ 210 | where: { 211 | userId_postId: { 212 | postId: '', 213 | userId: '', 214 | }, 215 | }, 216 | include: { post: true }, 217 | }) 218 | 219 | like!.post 220 | 221 | const like2 = await prisma.like.upsert({ 222 | where: { 223 | userId_postId: { 224 | userId: '', 225 | postId: '', 226 | }, 227 | }, 228 | create: { 229 | post: { connect: { id: '' } }, 230 | user: { connect: { id: '' } }, 231 | }, 232 | update: {}, 233 | include: { post: true }, 234 | }) 235 | 236 | like2!.post 237 | 238 | // make sure, that null is not allowed for this type 239 | type LikeUpdateIdType = LikeUpdateManyArgs['data']['id'] 240 | type AllowsNull = null extends LikeUpdateIdType ? true : false 241 | const allowsNull: AllowsNull = false 242 | 243 | // check if listing of \`set\` is done in nested relations 244 | // https://github.com/prisma/prisma/issues/3497 245 | await prisma.user.update({ 246 | where: { 247 | id: '6', 248 | }, 249 | data: { 250 | posts: { 251 | update: { 252 | data: { 253 | title: 'something', 254 | }, 255 | where: { 256 | id: 'whatever', 257 | }, 258 | }, 259 | }, 260 | }, 261 | }) 262 | 263 | await prisma.user.update({ 264 | where: { 265 | id: '6', 266 | }, 267 | data: { 268 | posts: { 269 | updateMany: { 270 | data: { 271 | title: 'something', 272 | }, 273 | where: { 274 | id: 'whatever', 275 | }, 276 | }, 277 | }, 278 | }, 279 | }) 280 | 281 | await prisma.post.update({ 282 | where: { 283 | id: '6', 284 | }, 285 | data: { 286 | author: { 287 | update: { 288 | name: 'something', 289 | }, 290 | }, 291 | }, 292 | }) 293 | } 294 | 295 | main().catch((e) => { 296 | console.error(e) 297 | }) 298 | 299 | function dollar(){ 300 | prisma.transaction() 301 | prisma.connect() 302 | prisma.disconnect() 303 | prisma.executeRaw() 304 | prisma.on() 305 | prisma.use() 306 | prisma.queryRaw() 307 | 308 | prisma.$transaction() 309 | prisma.$connect() 310 | prisma.$disconnect() 311 | prisma.$executeRaw() 312 | prisma.$on() 313 | prisma.$use() 314 | prisma.$queryRaw() 315 | } 316 | 317 | const transaction = "transaction" 318 | const connect = "connect" 319 | const disconnect = "disconnect" 320 | const executeRaw = "executeRaw" 321 | const on = "on" 322 | const use = "use" 323 | const queryRaw = "queryRaw" 324 | 325 | test.transaction() 326 | test.connect() 327 | test.disconnect() 328 | test.executeRaw() 329 | test.on() 330 | test.use() 331 | test.queryRaw() 332 | `; 333 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/custom-output/l1.ts.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects custom-output 1`] = ` 4 | import { PrismaClient, Post, User, Prisma } from './generated/client'; 5 | 6 | // tslint:disable 7 | 8 | // This file will not be executed, just compiled to check if the typings are valid 9 | async function main() { 10 | const prisma = new PrismaClient({ 11 | log: [ 12 | { 13 | emit: 'event', 14 | level: 'query', 15 | }, 16 | ], 17 | datasources: { 18 | db: { 19 | url: 'file:dev.db', 20 | }, 21 | }, 22 | }) 23 | const user = prisma.user.findUnique({ 24 | where: { 25 | id: "tests" 26 | } 27 | }) 28 | 29 | prisma.$on('query', (a) => { 30 | // 31 | }) 32 | 33 | Prisma.prismaVersion.client 34 | 35 | const x: Prisma.Sql = Prisma.sql\`SELECT * FROM \${Prisma.raw('User')} WHERE 'id' in \${Prisma.join([ 36 | 1, 37 | 2, 38 | 3, 39 | ])} \${Prisma.empty} \` 40 | 41 | const queryRaw1 = await prisma.$queryRaw\`SELECT * FROM User WHERE id = 1\` 42 | const queryRaw2 = await prisma.$queryRaw\`SELECT * FROM User WHERE id = \${1}\` 43 | const queryRaw3 = await prisma.$queryRaw( 44 | \`SELECT * FROM User WHERE id = $1\`, 45 | 2, 46 | ) 47 | const queryRaw4 = await prisma.$queryRaw( 48 | Prisma.sql\`SELECT * FROM User WHERE id = \${1}\`, 49 | ) 50 | const queryRaw5 = await prisma.$queryRaw( 51 | Prisma.sql\`SELECT * FROM User \${Prisma.sql\`WHERE id = \${1}\`}\`, 52 | ) 53 | 54 | const executeRaw1 = await prisma.$executeRaw\`SELECT * FROM User WHERE id = 1\` 55 | const executeRaw2 = await prisma.$executeRaw\`SELECT * FROM User WHERE id = \${1}\` 56 | const executeRaw3 = await prisma.$executeRaw( 57 | \`SELECT * FROM User WHERE id = $1\`, 58 | 2, 59 | ) 60 | const executeRaw4 = await prisma.$executeRaw( 61 | Prisma.sql\`SELECT * FROM User WHERE id = \${1}\`, 62 | ) 63 | const executeRaw5 = await prisma.$executeRaw( 64 | Prisma.sql\`SELECT * FROM User \${Prisma.sql\`WHERE id = \${1}\`}\`, 65 | ) 66 | 67 | const result1 = await prisma.user.findMany({ 68 | where: { 69 | posts: { 70 | some: { 71 | author: { 72 | AND: { 73 | id: '5', 74 | posts: { 75 | some: { 76 | author: { 77 | posts: { 78 | some: { 79 | title: '5', 80 | }, 81 | }, 82 | }, 83 | }, 84 | }, 85 | }, 86 | }, 87 | }, 88 | }, 89 | }, 90 | }) 91 | 92 | result1[0]!.email 93 | result1[0]!.id 94 | result1[0]!.name 95 | 96 | const result2: { 97 | id: string 98 | createdAt: Date 99 | updatedAt: Date 100 | published: boolean 101 | title: string 102 | content: string | null 103 | author: User | null 104 | } | null = await prisma.post.findUnique({ 105 | where: { 106 | id: '', 107 | }, 108 | include: { 109 | author: true, 110 | }, 111 | }) 112 | 113 | const result3: 'Please either choose \`select\` or \`include\`' = await prisma.post.findMany( 114 | { 115 | select: {}, 116 | include: {}, 117 | }, 118 | ) 119 | 120 | const result4: Array<{ 121 | id: string 122 | author: { 123 | name: string | null 124 | } | null 125 | }> = await prisma.post.findMany({ 126 | select: { 127 | id: true, 128 | author: { 129 | select: { 130 | name: true, 131 | }, 132 | }, 133 | }, 134 | }) 135 | 136 | const result5: Post = await prisma.post.create({ 137 | data: { 138 | published: false, 139 | title: 'Title', 140 | }, 141 | }) 142 | 143 | await prisma.post.delete({ 144 | where: { 145 | id: '', 146 | }, 147 | }) 148 | 149 | await prisma.post.upsert({ 150 | create: { 151 | published: false, 152 | title: 'Title', 153 | }, 154 | update: { 155 | published: true, 156 | }, 157 | where: { 158 | id: '6', 159 | }, 160 | }) 161 | 162 | await prisma.post.updateMany({ 163 | data: { 164 | published: false, 165 | }, 166 | }) 167 | 168 | const count: number = await prisma.post.count({ 169 | where: { 170 | published: false, 171 | }, 172 | }) 173 | 174 | const $disconnect: Promise = prisma.$disconnect() 175 | 176 | // Trick to define a "positive" test, if "include" is NOT in "FindManyMachineDataArgs" 177 | type X = keyof Prisma.FindManyMachineDataArgs 178 | type Y = 'include' extends X ? number : string 179 | const y: Y = 'string' 180 | 181 | // Test for https://github.com/prisma/prisma-client-js/issues/615 182 | const users = await prisma.user.findMany({ 183 | include: { 184 | posts: { 185 | include: { 186 | author: true, 187 | }, 188 | orderBy: { 189 | title: 'asc', 190 | }, 191 | }, 192 | }, 193 | }) 194 | 195 | const id = users[0].posts[0].author?.id 196 | 197 | const like = await prisma.like.findUnique({ 198 | where: { 199 | userId_postId: { 200 | postId: '', 201 | userId: '', 202 | }, 203 | }, 204 | include: { post: true }, 205 | }) 206 | 207 | like!.post 208 | 209 | const like2 = await prisma.like.upsert({ 210 | where: { 211 | userId_postId: { 212 | userId: '', 213 | postId: '', 214 | }, 215 | }, 216 | create: { 217 | post: { connect: { id: '' } }, 218 | user: { connect: { id: '' } }, 219 | }, 220 | update: {}, 221 | include: { post: true }, 222 | }) 223 | 224 | like2!.post 225 | 226 | // make sure, that null is not allowed for this type 227 | type LikeUpdateIdType = Prisma.LikeUpdateManyArgs['data']['id'] 228 | type AllowsNull = null extends LikeUpdateIdType ? true : false 229 | const allowsNull: AllowsNull = false 230 | 231 | // check if listing of \`set\` is done in nested relations 232 | // https://github.com/prisma/prisma/issues/3497 233 | await prisma.user.update({ 234 | where: { 235 | id: '6', 236 | }, 237 | data: { 238 | posts: { 239 | update: { 240 | data: { 241 | title: 'something', 242 | }, 243 | where: { 244 | id: 'whatever', 245 | }, 246 | }, 247 | }, 248 | }, 249 | }) 250 | 251 | await prisma.user.update({ 252 | where: { 253 | id: '6', 254 | }, 255 | data: { 256 | posts: { 257 | updateMany: { 258 | data: { 259 | title: 'something', 260 | }, 261 | where: { 262 | id: 'whatever', 263 | }, 264 | }, 265 | }, 266 | }, 267 | }) 268 | 269 | await prisma.post.update({ 270 | where: { 271 | id: '6', 272 | }, 273 | data: { 274 | author: { 275 | update: { 276 | name: 'something', 277 | }, 278 | }, 279 | }, 280 | }) 281 | } 282 | 283 | main().catch((e) => { 284 | console.error(e) 285 | }) 286 | 287 | function dollar(){ 288 | prisma.$transaction() 289 | prisma.$connect() 290 | prisma.$disconnect() 291 | prisma.$executeRaw() 292 | prisma.$on() 293 | prisma.$use() 294 | prisma.$queryRaw() 295 | 296 | prisma.$transaction() 297 | prisma.$connect() 298 | prisma.$disconnect() 299 | prisma.$executeRaw() 300 | prisma.$on() 301 | prisma.$use() 302 | prisma.$queryRaw() 303 | } 304 | 305 | const transaction = "transaction" 306 | const connect = "connect" 307 | const disconnect = "disconnect" 308 | const executeRaw = "executeRaw" 309 | const on = "on" 310 | const use = "use" 311 | const queryRaw = "queryRaw" 312 | 313 | test.transaction() 314 | test.connect() 315 | test.disconnect() 316 | test.executeRaw() 317 | test.on() 318 | test.use() 319 | test.queryRaw() 320 | `; 321 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/custom-output/l2/l1.ts.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects custom-output 1`] = ` 4 | import { PrismaClient, Post, User, Prisma } from '../generated/client'; 5 | 6 | // tslint:disable 7 | 8 | // This file will not be executed, just compiled to check if the typings are valid 9 | async function main() { 10 | const prisma = new PrismaClient({ 11 | log: [ 12 | { 13 | emit: 'event', 14 | level: 'query', 15 | }, 16 | ], 17 | datasources: { 18 | db: { 19 | url: 'file:dev.db', 20 | }, 21 | }, 22 | }) 23 | const user = prisma.user.findUnique({ 24 | where: { 25 | id: "tests" 26 | } 27 | }) 28 | prisma.$on('query', (a) => { 29 | // 30 | }) 31 | 32 | Prisma.prismaVersion.client 33 | 34 | const x: Prisma.Sql = Prisma.sql\`SELECT * FROM \${Prisma.raw('User')} WHERE 'id' in \${Prisma.join([ 35 | 1, 36 | 2, 37 | 3, 38 | ])} \${Prisma.empty} \` 39 | 40 | const queryRaw1 = await prisma.$queryRaw\`SELECT * FROM User WHERE id = 1\` 41 | const queryRaw2 = await prisma.$queryRaw\`SELECT * FROM User WHERE id = \${1}\` 42 | const queryRaw3 = await prisma.$queryRaw( 43 | \`SELECT * FROM User WHERE id = $1\`, 44 | 2, 45 | ) 46 | const queryRaw4 = await prisma.$queryRaw( 47 | Prisma.sql\`SELECT * FROM User WHERE id = \${1}\`, 48 | ) 49 | const queryRaw5 = await prisma.$queryRaw( 50 | Prisma.sql\`SELECT * FROM User \${Prisma.sql\`WHERE id = \${1}\`}\`, 51 | ) 52 | 53 | const executeRaw1 = await prisma.$executeRaw\`SELECT * FROM User WHERE id = 1\` 54 | const executeRaw2 = await prisma.$executeRaw\`SELECT * FROM User WHERE id = \${1}\` 55 | const executeRaw3 = await prisma.$executeRaw( 56 | \`SELECT * FROM User WHERE id = $1\`, 57 | 2, 58 | ) 59 | const executeRaw4 = await prisma.$executeRaw( 60 | Prisma.sql\`SELECT * FROM User WHERE id = \${1}\`, 61 | ) 62 | const executeRaw5 = await prisma.$executeRaw( 63 | Prisma.sql\`SELECT * FROM User \${Prisma.sql\`WHERE id = \${1}\`}\`, 64 | ) 65 | 66 | const result1 = await prisma.user.findMany({ 67 | where: { 68 | posts: { 69 | some: { 70 | author: { 71 | AND: { 72 | id: '5', 73 | posts: { 74 | some: { 75 | author: { 76 | posts: { 77 | some: { 78 | title: '5', 79 | }, 80 | }, 81 | }, 82 | }, 83 | }, 84 | }, 85 | }, 86 | }, 87 | }, 88 | }, 89 | }) 90 | 91 | result1[0]!.email 92 | result1[0]!.id 93 | result1[0]!.name 94 | 95 | const result2: { 96 | id: string 97 | createdAt: Date 98 | updatedAt: Date 99 | published: boolean 100 | title: string 101 | content: string | null 102 | author: User | null 103 | } | null = await prisma.post.findUnique({ 104 | where: { 105 | id: '', 106 | }, 107 | include: { 108 | author: true, 109 | }, 110 | }) 111 | 112 | const result3: 'Please either choose \`select\` or \`include\`' = await prisma.post.findMany( 113 | { 114 | select: {}, 115 | include: {}, 116 | }, 117 | ) 118 | 119 | const result4: Array<{ 120 | id: string 121 | author: { 122 | name: string | null 123 | } | null 124 | }> = await prisma.post.findMany({ 125 | select: { 126 | id: true, 127 | author: { 128 | select: { 129 | name: true, 130 | }, 131 | }, 132 | }, 133 | }) 134 | 135 | const result5: Post = await prisma.post.create({ 136 | data: { 137 | published: false, 138 | title: 'Title', 139 | }, 140 | }) 141 | 142 | await prisma.post.delete({ 143 | where: { 144 | id: '', 145 | }, 146 | }) 147 | 148 | await prisma.post.upsert({ 149 | create: { 150 | published: false, 151 | title: 'Title', 152 | }, 153 | update: { 154 | published: true, 155 | }, 156 | where: { 157 | id: '6', 158 | }, 159 | }) 160 | 161 | await prisma.post.updateMany({ 162 | data: { 163 | published: false, 164 | }, 165 | }) 166 | 167 | const count: number = await prisma.post.count({ 168 | where: { 169 | published: false, 170 | }, 171 | }) 172 | 173 | const $disconnect: Promise = prisma.$disconnect() 174 | 175 | // Trick to define a "positive" test, if "include" is NOT in "FindManyMachineDataArgs" 176 | type X = keyof Prisma.FindManyMachineDataArgs 177 | type Y = 'include' extends X ? number : string 178 | const y: Y = 'string' 179 | 180 | // Test for https://github.com/prisma/prisma-client-js/issues/615 181 | const users = await prisma.user.findMany({ 182 | include: { 183 | posts: { 184 | include: { 185 | author: true, 186 | }, 187 | orderBy: { 188 | title: 'asc', 189 | }, 190 | }, 191 | }, 192 | }) 193 | 194 | const id = users[0].posts[0].author?.id 195 | 196 | const like = await prisma.like.findUnique({ 197 | where: { 198 | userId_postId: { 199 | postId: '', 200 | userId: '', 201 | }, 202 | }, 203 | include: { post: true }, 204 | }) 205 | 206 | like!.post 207 | 208 | const like2 = await prisma.like.upsert({ 209 | where: { 210 | userId_postId: { 211 | userId: '', 212 | postId: '', 213 | }, 214 | }, 215 | create: { 216 | post: { connect: { id: '' } }, 217 | user: { connect: { id: '' } }, 218 | }, 219 | update: {}, 220 | include: { post: true }, 221 | }) 222 | 223 | like2!.post 224 | 225 | // make sure, that null is not allowed for this type 226 | type LikeUpdateIdType = Prisma.LikeUpdateManyArgs['data']['id'] 227 | type AllowsNull = null extends LikeUpdateIdType ? true : false 228 | const allowsNull: AllowsNull = false 229 | 230 | // check if listing of \`set\` is done in nested relations 231 | // https://github.com/prisma/prisma/issues/3497 232 | await prisma.user.update({ 233 | where: { 234 | id: '6', 235 | }, 236 | data: { 237 | posts: { 238 | update: { 239 | data: { 240 | title: 'something', 241 | }, 242 | where: { 243 | id: 'whatever', 244 | }, 245 | }, 246 | }, 247 | }, 248 | }) 249 | 250 | await prisma.user.update({ 251 | where: { 252 | id: '6', 253 | }, 254 | data: { 255 | posts: { 256 | updateMany: { 257 | data: { 258 | title: 'something', 259 | }, 260 | where: { 261 | id: 'whatever', 262 | }, 263 | }, 264 | }, 265 | }, 266 | }) 267 | 268 | await prisma.post.update({ 269 | where: { 270 | id: '6', 271 | }, 272 | data: { 273 | author: { 274 | update: { 275 | name: 'something', 276 | }, 277 | }, 278 | }, 279 | }) 280 | } 281 | 282 | main().catch((e) => { 283 | console.error(e) 284 | }) 285 | 286 | `; 287 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/custom-output/package.json.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects custom-output 1`] = ` 4 | { 5 | "name": "minimal", 6 | "dependencies": { 7 | "@prisma/cli": "^2.10.2", 8 | "@prisma/client": "^2.10.2" 9 | } 10 | } 11 | 12 | `; 13 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/custom-output/prisma/schema.prisma.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects custom-output 1`] = ` 4 | generator client { 5 | provider = "prisma-client-js" 6 | output = "../generated/client" 7 | } 8 | 9 | datasource db { 10 | provider = "sqlite" 11 | url = env("DOTENV_ROOT_PRISMA_SHOULD_WORK") 12 | } 13 | 14 | model Post { 15 | id Int @default(autoincrement()) @id 16 | createdAt DateTime @default(now()) 17 | title String 18 | content String? 19 | published Boolean @default(false) 20 | author User @relation(fields: [authorId], references: [id]) 21 | authorId Int 22 | } 23 | 24 | model Profile { 25 | id Int @default(autoincrement()) @id 26 | bio String? 27 | user User @relation(fields: [userId], references: [id]) 28 | userId Int @unique 29 | } 30 | 31 | model User { 32 | id Int @default(autoincrement()) @id 33 | email String @unique 34 | name String? 35 | posts Post[] 36 | profile Profile? 37 | } 38 | `; 39 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/issues/.gitignore.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects issues 1`] = ` 4 | node_modules 5 | 6 | `; 7 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/issues/issue-18.ts.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects issues 1`] = ` 4 | import { Person } from "@prisma/client"; 5 | 6 | const person = {where: { 7 | Person: { id: personId }, 8 | expiresAt: { gt: new Date() } 9 | }, 10 | } 11 | console.log(person); 12 | 13 | `; 14 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/issues/package.json.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects issues 1`] = ` 4 | { 5 | "devDependencies": { 6 | "@prisma/cli": "^2.12.0", 7 | "@prisma/codemods": "^0.5.1" 8 | }, 9 | "dependencies": { 10 | "@prisma/client": "^2.12.0" 11 | }, 12 | "type": "module", 13 | "scripts": { 14 | "test": "codemods namespace ./index.js" 15 | } 16 | } 17 | 18 | `; 19 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/issues/prisma/schema.prisma.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects issues 1`] = ` 4 | // This is your Prisma schema file, 5 | // learn more about it in the docs: https://pris.ly/d/prisma-schema 6 | 7 | datasource db { 8 | provider = "sqlite" 9 | url = "file:./dev.db" 10 | } 11 | 12 | generator client { 13 | provider = "prisma-client-js" 14 | } 15 | 16 | model Person { 17 | name String @id 18 | } 19 | 20 | `; 21 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/prisma-codemods-issue-6-main/.gitignore.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects prisma-codemods-issue-6-main 1`] = ` 4 | node_modules 5 | 6 | `; 7 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/prisma-codemods-issue-6-main/index.js.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects prisma-codemods-issue-6-main 1`] = ` 4 | import { Person as LocalPerson } from "./local-file"; 5 | import { Person } from "@prisma/client"; 6 | 7 | /** @type {Person} */ 8 | const person = new LocalPerson(); 9 | 10 | console.log(person); 11 | 12 | `; 13 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/prisma-codemods-issue-6-main/local-file.js.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects prisma-codemods-issue-6-main 1`] = ` 4 | export class Person { 5 | constructor() { 6 | console.log("hello, everything is good"); 7 | } 8 | } 9 | 10 | `; 11 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/prisma-codemods-issue-6-main/package.json.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects prisma-codemods-issue-6-main 1`] = ` 4 | { 5 | "devDependencies": { 6 | "@prisma/cli": "^2.12.0", 7 | "@prisma/codemods": "^0.5.1" 8 | }, 9 | "dependencies": { 10 | "@prisma/client": "^2.12.0" 11 | }, 12 | "type": "module", 13 | "scripts": { 14 | "test": "codemods namespace ./index.js" 15 | } 16 | } 17 | 18 | `; 19 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/prisma-codemods-issue-6-main/prisma/schema.prisma.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects prisma-codemods-issue-6-main 1`] = ` 4 | // This is your Prisma schema file, 5 | // learn more about it in the docs: https://pris.ly/d/prisma-schema 6 | 7 | datasource db { 8 | provider = "sqlite" 9 | url = "file:./dev.db" 10 | } 11 | 12 | generator client { 13 | provider = "prisma-client-js" 14 | } 15 | 16 | model Person { 17 | name String @id 18 | } 19 | 20 | `; 21 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/prisma-codemods-issue-6-main/readme.md.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects prisma-codemods-issue-6-main 1`] = ` 4 | # @prisma/codemods issue #6 5 | 6 | ## Reproduction 7 | 8 | 1. Clone repo 9 | 2. Run \`yarn\` (other package managers may also work) 10 | 3. Run \`yarn test\` or \`npm test\` 11 | 4. Observe if the imports are valid (\`Person as LocalPerson\` from \`./local-file\` should not be changed) 12 | 13 | `; 14 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/throw-missing-schema/.gitignore.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects throw-missing-schema 1`] = ` 4 | node_modules 5 | 6 | `; 7 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/throw-missing-schema/index.js.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects throw-missing-schema 1`] = ` 4 | import { Person as LocalPerson } from "./local-file"; 5 | import { Person } from "@prisma/client"; 6 | 7 | /** @type {Person} */ 8 | const person = new LocalPerson(); 9 | 10 | console.log(person); 11 | 12 | `; 13 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/throw-missing-schema/local-file.js.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects throw-missing-schema 1`] = ` 4 | export class Person { 5 | constructor() { 6 | console.log("hello, everything is good"); 7 | } 8 | } 9 | 10 | `; 11 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/throw-missing-schema/package.json.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects throw-missing-schema 1`] = ` 4 | { 5 | "devDependencies": { 6 | "@prisma/cli": "^2.12.0", 7 | "@prisma/codemods": "^0.5.1" 8 | }, 9 | "dependencies": { 10 | "@prisma/client": "^2.12.0" 11 | }, 12 | "type": "module", 13 | "scripts": { 14 | "test": "codemods namespace ./index.js" 15 | } 16 | } 17 | 18 | `; 19 | -------------------------------------------------------------------------------- /tests/__snapshots__/update-2.12/projects/throw-missing-schema/readme.md.ssnap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`update-2.12 projects throw-missing-schema 1`] = ` 4 | # @prisma/codemods issue #6 5 | 6 | ## Reproduction 7 | 8 | 1. Clone repo 9 | 2. Run \`yarn\` (other package managers may also work) 10 | 3. Run \`yarn test\` or \`npm test\` 11 | 4. Observe if the imports are valid (\`Person as LocalPerson\` from \`./local-file\` should not be changed) 12 | 13 | `; 14 | -------------------------------------------------------------------------------- /tests/findUnique.test.ts: -------------------------------------------------------------------------------- 1 | 2 | import { buildTest } from "./utils/buildTest"; 3 | 4 | buildTest("findUnique") -------------------------------------------------------------------------------- /tests/namespace.test.ts: -------------------------------------------------------------------------------- 1 | 2 | import { buildTest } from "./utils/buildTest"; 3 | buildTest("namespace") -------------------------------------------------------------------------------- /tests/to$.test.ts: -------------------------------------------------------------------------------- 1 | 2 | import { buildTest } from "./utils/buildTest"; 3 | 4 | buildTest("to$") -------------------------------------------------------------------------------- /tests/update-2.12.test.ts: -------------------------------------------------------------------------------- 1 | 2 | import { buildTest } from "./utils/buildTest"; 3 | 4 | buildTest("update-2.12") -------------------------------------------------------------------------------- /tests/utils/buildTest.ts: -------------------------------------------------------------------------------- 1 | //@ts-ignore 2 | import Copy from "@apexearth/copy"; 3 | import fs from "fs"; 4 | // @ts-ignore 5 | import { addSerializer } from "jest-specific-snapshot"; 6 | import path from "path"; 7 | // @ts-ignore 8 | import tempy from "tempy"; 9 | import { getCustomImportPath } from "../../utils/getCustomImportPath"; 10 | import { runTransform } from "../../utils/runner"; 11 | import { serializer } from "./snapshotSerializer"; 12 | 13 | // @ts-ignore 14 | import("jest-specific-snapshot"); 15 | 16 | addSerializer(serializer); 17 | 18 | const SNAPSHOT_DIR = path.join(__dirname, "..", "__snapshots__"); 19 | const FIXTURES_DIR = path.join(__dirname, "..", "__fixtures__"); 20 | 21 | async function run( 22 | transformer: string, 23 | filePath: string, 24 | flags?: { instanceNames: string } 25 | ) { 26 | let result = ""; 27 | const baseOptions = { 28 | projectDir: filePath, 29 | customImportPath: process.env.PRISMA_CUSTOM_IMPORT_PATH, 30 | flags: { 31 | dry: false, 32 | print: false, 33 | runInBand: true, 34 | instanceNames: flags?.instanceNames, 35 | }, 36 | testMode: true, 37 | }; 38 | if (transformer === "update-2.12") { 39 | const namespace = await runTransform({ 40 | transformer: "namespace", 41 | ...baseOptions, 42 | }); 43 | const findUnique = await runTransform({ 44 | transformer: "findUnique", 45 | 46 | ...baseOptions, 47 | }); 48 | const to$ = await runTransform({ 49 | transformer: "to$", 50 | ...baseOptions, 51 | }); 52 | result = [namespace.stdout, findUnique.stdout].join("\n"); 53 | } else { 54 | const trans = await runTransform({ 55 | transformer, 56 | ...baseOptions, 57 | }); 58 | result = trans.stdout; 59 | } 60 | return result; 61 | } 62 | const getAllFiles = function (dirPath: string, arrayOfFiles: string[] = []) { 63 | let files = fs.readdirSync(dirPath); 64 | 65 | arrayOfFiles = arrayOfFiles ?? []; 66 | const notCustom = (f: string) => 67 | process.env.PRISMA_CUSTOM_IMPORT_PATH 68 | ? !f.includes(process.env.PRISMA_CUSTOM_IMPORT_PATH) 69 | : true; 70 | files.forEach(function (file) { 71 | const filepath = path.join(dirPath, "/", file); 72 | if (!filepath.includes("node_modules") && notCustom(filepath)) { 73 | if (fs.statSync(dirPath + "/" + file).isDirectory()) { 74 | arrayOfFiles = getAllFiles(filepath, arrayOfFiles); 75 | } else { 76 | arrayOfFiles.push(filepath); 77 | } 78 | } 79 | }); 80 | 81 | return arrayOfFiles; 82 | }; 83 | async function copy(from: string, to: string) { 84 | return new Promise((resolve, reject) => { 85 | Copy({ 86 | from, // Source copy path. 87 | to, // Destination copy path. 88 | recursive: true, // Copy recursively. 89 | }) 90 | .then(() => resolve()) 91 | .catch((err: Error) => reject(err)); 92 | }); 93 | } 94 | export async function buildTest(transformer: string) { 95 | const transformerFixtures = path.join(FIXTURES_DIR, transformer); 96 | 97 | const inputsDir = path.join(transformerFixtures, "inputs"); 98 | const projectsDir = path.join(transformerFixtures, "projects"); 99 | 100 | if (fs.existsSync(inputsDir)) { 101 | describe(`${transformer} inputs`, () => { 102 | const files = fs.readdirSync(inputsDir); 103 | for (const file of files) { 104 | const inputFilename = path.basename(file) 105 | test(inputFilename, async () => { 106 | const filePathFixed = path.join(inputsDir, file); 107 | const filePath = tempy.writeSync( 108 | fs.readFileSync(filePathFixed, { encoding: "utf8" }) 109 | ); 110 | if (inputFilename.includes("instanceNames")) { 111 | await run(transformer, filePath, { 112 | instanceNames: "whatEverYouWant,another", 113 | }); 114 | } else { 115 | await run(transformer, filePath); 116 | } 117 | const snapshotFile = path.join( 118 | SNAPSHOT_DIR, 119 | transformer, 120 | "input", 121 | file 122 | ); 123 | const result = fs.readFileSync(filePath, { encoding: "utf8" }); 124 | // @ts-ignore 125 | expect(result).toMatchSpecificSnapshot(snapshotFile); 126 | }); 127 | } 128 | }); 129 | } 130 | if (fs.existsSync(projectsDir)) { 131 | describe(`${transformer} projects`, () => { 132 | const projects = fs.readdirSync(projectsDir); 133 | for (const projectName of projects) { 134 | test(projectName, async () => { 135 | const projectFixedDir = path.join(projectsDir, projectName); 136 | const projectDir = tempy.directory(); 137 | 138 | await copy(projectFixedDir, projectDir); 139 | 140 | try { 141 | process.env.PRISMA_CUSTOM_IMPORT_PATH = await getCustomImportPath({ 142 | cwd: projectDir, 143 | }); 144 | } catch (err) { 145 | if (projectName.startsWith("throw")) { 146 | expect(err).toMatchSnapshot(); 147 | } 148 | } 149 | await run(transformer, projectDir); 150 | 151 | const files = getAllFiles(projectDir); 152 | files.forEach((file) => { 153 | const snapshotFile = path.join( 154 | SNAPSHOT_DIR, 155 | transformer, 156 | "projects", 157 | projectName, 158 | path.relative(projectDir, file) + ".ssnap" 159 | ); 160 | const result = fs.readFileSync(file, { encoding: "utf8" }); 161 | // @ts-ignore 162 | expect(result).toMatchSpecificSnapshot(snapshotFile); 163 | }); 164 | }); 165 | } 166 | }); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /tests/utils/snapshotSerializer.ts: -------------------------------------------------------------------------------- 1 | import stripAnsi from 'strip-ansi' 2 | 3 | export const serializer = { 4 | test(value: any) { 5 | return typeof value === 'string' || value instanceof Error 6 | }, 7 | serialize(value: any) { 8 | if (typeof value === 'string') { 9 | return cleanLogs(value) 10 | } 11 | return value.toString() 12 | }, 13 | } 14 | 15 | export function cleanLogs(logs: string): string { 16 | const clean = stripAnsi(logs) 17 | return clean 18 | } 19 | 20 | -------------------------------------------------------------------------------- /transforms/findUnique.ts: -------------------------------------------------------------------------------- 1 | import { API, FileInfo, Options } from "jscodeshift"; 2 | 3 | const INSTANCE_NAME = 'prisma' 4 | 5 | export default function transform(file: FileInfo, api: API, options: Options) { 6 | const j = api.jscodeshift; 7 | // Convert the entire file source into a collection of nodes paths. 8 | const root = j(file.source); 9 | let foundInstanceNames: string[] = [] 10 | 11 | // Finds All const x = new PrismaClient() and adds x to the foundInstanceNames 12 | root.find(j.VariableDeclarator, { 13 | id: { 14 | type: "Identifier" 15 | }, 16 | init: { 17 | type: "NewExpression", 18 | callee: { 19 | name: "PrismaClient" 20 | } 21 | } 22 | }).forEach((vd: any) => { 23 | if(vd.node.id?.name){ 24 | foundInstanceNames.push(vd.node.id?.name) 25 | } 26 | }); 27 | const instanceNames = getInstanceNames(foundInstanceNames, options?.instanceNames) // If custom instance names are passed to the cli these are used 28 | 29 | root.find(j.Identifier, { 30 | name: 'findOne' 31 | }).filter((idPath) => { 32 | // This finds prisma.x.findOne 33 | if ( 34 | instanceNames.includes(idPath?.parent?.value?.object?.object?.name) || 35 | instanceNames.includes(idPath?.parent?.value?.object?.object?.property?.name) 36 | ) { 37 | return true; 38 | } 39 | return false; 40 | }) 41 | .replaceWith((p) => 42 | Object.assign({}, p.node, { 43 | name: `findUnique`, 44 | }) 45 | ); 46 | return root.toSource(); 47 | } 48 | 49 | function getInstanceNames(foundInstanceNames: string[], cli?: string): string[]{ 50 | if(cli){ 51 | const fromCli = cli.split(',').map(i => i.trim()) 52 | if(fromCli.length > 0){ 53 | console.log(`Only searching for passed instance names: ${cli}`); 54 | return fromCli 55 | } 56 | } 57 | return foundInstanceNames.length > 0 ? foundInstanceNames : [INSTANCE_NAME] 58 | } -------------------------------------------------------------------------------- /transforms/namespace.ts: -------------------------------------------------------------------------------- 1 | import { 2 | API, 3 | CallExpression, 4 | Collection, 5 | FileInfo, 6 | Identifier, 7 | JSCodeshift, 8 | Options, 9 | StringLiteral, 10 | } from "jscodeshift"; 11 | import fs from "fs" 12 | import { isPrismaImport } from "../utils/helpers"; 13 | let RESERVED = ["PrismaClient", "Prisma"]; 14 | 15 | function handleImports(root: Collection, j: JSCodeshift) { 16 | let edit: string[] = []; 17 | let shouldAddImport = true; 18 | 19 | const prismaImport = root.find(j.ImportDeclaration).filter((nodePath) => { 20 | return ( 21 | Boolean(nodePath.node.source.value) && 22 | typeof nodePath.node.source.value === "string" && 23 | isPrismaImport(nodePath.node.source.value) 24 | ); 25 | }); 26 | 27 | const specifiers = prismaImport 28 | .find(j.ImportSpecifier) 29 | .filter((nPath) => { 30 | if (nPath.value.local && nPath.value.local.name === "Prisma") { 31 | shouldAddImport = false; 32 | } 33 | if (nPath.value.local && !RESERVED.includes(nPath.value.local.name) && nPath.value.local.name === nPath.value.imported.name) { 34 | edit.push(nPath.value.local.name); 35 | return true; 36 | } 37 | return false; 38 | }) 39 | .remove(); 40 | 41 | if (edit.length > 0 && shouldAddImport) { 42 | specifiers.at(0).insertBefore(j.importSpecifier(j.identifier("Prisma"))); 43 | } 44 | return edit; 45 | } 46 | 47 | function handleRequire(root: Collection, j: JSCodeshift) { 48 | let edit: string[] = []; 49 | let shouldAddImport = true; 50 | // console.log("Running"); 51 | root 52 | .find(j.VariableDeclarator) 53 | .filter((vdPath) => { 54 | // console.log(vdPath); 55 | if ( 56 | vdPath.node.id.type === "ObjectPattern" && 57 | vdPath.node.init && 58 | vdPath.node.init.type === "CallExpression" 59 | ) { 60 | if ( 61 | vdPath.node.init.callee.type === "Identifier" && 62 | vdPath.node.init.callee.name === "require" 63 | ) { 64 | if (vdPath.node.init.arguments) { 65 | // console.log(vdPath.node.init.arguments[0].type === "StringLiteral"); 66 | return true; 67 | } 68 | } 69 | } 70 | return false; 71 | }) 72 | .forEach((path) => { 73 | const value = ((path.node.init as CallExpression) 74 | .arguments[0] as StringLiteral).value; 75 | if (isPrismaImport(value)) { 76 | let variableDeclarator = j(path); 77 | // console.log(path.node.id); 78 | const properties = variableDeclarator 79 | .find(j.ObjectProperty) 80 | .filter((propertyPath) => { 81 | // , { key: { type: "Identifier" } } 82 | // console.log(propertyPath.node); 83 | return propertyPath.node.key.type === "Identifier"; 84 | }) 85 | .forEach((property) => { 86 | if ((property.value.key as Identifier).name === "Prisma") { 87 | shouldAddImport = false; 88 | } 89 | // console.log(property); 90 | if (!RESERVED.includes((property.value.key as Identifier).name)) { 91 | edit.push((property.value.key as Identifier).name); 92 | j(property).remove(); 93 | } 94 | }); 95 | if (edit.length > 0 && shouldAddImport) { 96 | properties.at(0).insertBefore(j.identifier("Prisma")); 97 | } 98 | } 99 | }); 100 | return edit; 101 | } 102 | export default function transform(file: FileInfo, api: API, options: Options) { 103 | if(process.env.PRISMA_TOP_LEVEL_EXPORTS_FILE){ 104 | const data = fs.readFileSync(process.env.PRISMA_TOP_LEVEL_EXPORTS_FILE, {encoding: 'utf8'}) 105 | const topLevelExports = data.split(',') 106 | RESERVED.push(...topLevelExports) 107 | RESERVED = RESERVED.filter((v, i, a) => a.indexOf(v) === i); 108 | } 109 | const j = api.jscodeshift; 110 | // Convert the entire file source into a collection of nodes paths. 111 | const root = j(file.source); 112 | 113 | const importEdits = handleImports(root, j); 114 | const requireEdits = handleRequire(root, j); 115 | 116 | const all = importEdits.concat(requireEdits); 117 | 118 | const edit = all.filter(function (elem, pos) { 119 | return all.indexOf(elem) == pos; 120 | }); 121 | const identifiers = root.find(j.Identifier); 122 | identifiers 123 | .filter((idPath) => { 124 | return edit.includes(idPath.value.name) && idPath.parent.value.type !== 'ImportSpecifier'; 125 | }) 126 | .replaceWith((p) => 127 | Object.assign({}, p.node, { 128 | name: `Prisma.${p.node.name}`, 129 | }) 130 | ); 131 | return root.toSource(); 132 | } 133 | 134 | -------------------------------------------------------------------------------- /transforms/to$.ts: -------------------------------------------------------------------------------- 1 | import { API, FileInfo, Options } from "jscodeshift"; 2 | 3 | const methods = [ 4 | "transaction", 5 | "connect", 6 | "disconnect", 7 | "executeRaw", 8 | "on", 9 | "use", 10 | "queryRaw", 11 | ]; 12 | 13 | export default function transform(file: FileInfo, api: API, options: Options) { 14 | const j = api.jscodeshift; 15 | // Convert the entire file source into a collection of nodes paths. 16 | const root = j(file.source); 17 | const identifiers = root.find(j.Identifier); 18 | identifiers 19 | .filter((idPath) => { 20 | // This finds prisma.x.findOne 21 | if ( 22 | methods.includes(idPath.value.name) && 23 | idPath?.parent?.value?.object?.name === "prisma" && 24 | idPath?.parent?.parent?.value?.type === 'CallExpression' 25 | 26 | ) { 27 | return true; 28 | } 29 | return false; 30 | }) 31 | .replaceWith((p) => 32 | Object.assign({}, p.node, { 33 | name: `$${p.node.name}`, 34 | }) 35 | ); 36 | return root.toSource(); 37 | } 38 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "sourceMap": true, 5 | "declaration": false, 6 | "esModuleInterop": true, 7 | "target": "es2015", 8 | "strict": true, 9 | "downlevelIteration": true, 10 | "preserveWatchOutput": true, 11 | }, 12 | "include": ["**/*.ts"], 13 | "exclude": ["node_modules","tests"] 14 | } -------------------------------------------------------------------------------- /utils/getCustomImportPath.ts: -------------------------------------------------------------------------------- 1 | import { getConfig, getDMMF } from '@prisma/sdk' 2 | import { getSchemaPathInternal } from '@prisma/sdk/dist/cli/getSchema'; 3 | import path from 'path'; 4 | import fs from 'fs' 5 | import tempy from 'tempy'; 6 | 7 | interface Options { 8 | schemaPathFromArgs?: string, 9 | cwd: string 10 | } 11 | export async function getCustomImportPath(options: Options){ 12 | 13 | const schemaPath = await getSchemaPathInternal(options?.schemaPathFromArgs, {cwd: options.cwd}) 14 | if(!schemaPath || !fs.existsSync(schemaPath)){ 15 | throw new Error("Prisma Schema Could Not be found, try specifying the `--schemaPath ./path/to/schema.prisma`") 16 | } 17 | const datamodel = schemaPath && fs.readFileSync(schemaPath, {encoding: 'utf8'}) 18 | if(datamodel){ 19 | const config = await getConfig({datamodel, ignoreEnvVarErrors: true}) 20 | process.env.PRISMA_TOP_LEVEL_EXPORTS_FILE = await getTopLevelExports(datamodel) 21 | const generator = config.generators[0] 22 | 23 | if(generator){ 24 | return generator?.output ? generator.output.replace(/\.\.\//g, '') : '' 25 | } 26 | } 27 | return '' 28 | } 29 | function getModelNames(model?: T[]){ 30 | return model ? model.map(it => it.name): [] 31 | } 32 | export async function getTopLevelExports(datamodel: string){ 33 | const dmmf = await getDMMF({datamodel}) 34 | const schema = dmmf.schema 35 | const inputs = getModelNames(schema.inputObjectTypes.model) 36 | const outputs = getModelNames(schema.outputObjectTypes.model) 37 | const enums = getModelNames(schema.enumTypes.model) 38 | const expts = [...inputs, ...outputs, ...enums].filter((v, i, a) => a.indexOf(v) === i); 39 | const filePath = tempy.writeSync(expts.join(',')) 40 | return filePath 41 | } 42 | -------------------------------------------------------------------------------- /utils/helpers.ts: -------------------------------------------------------------------------------- 1 | export function isPrismaImport(importPath: string) { 2 | const prismaPaths = [".prisma/client", "@prisma/client"]; 3 | if (process.env.PRISMA_CUSTOM_IMPORT_PATH) { 4 | prismaPaths.push(process.env.PRISMA_CUSTOM_IMPORT_PATH); 5 | } 6 | return prismaPaths.some((p) => { 7 | return importPath.includes(p); 8 | }); 9 | } -------------------------------------------------------------------------------- /utils/runner.ts: -------------------------------------------------------------------------------- 1 | import execa from "execa"; 2 | import fs from 'fs'; 3 | import path from "path"; 4 | export interface Options { 5 | 6 | projectDir: string; 7 | transformer: string; 8 | customImportPath?: string; 9 | flags: { dry?: boolean; print?: boolean, runInBand?: boolean, instanceNames?: string }; 10 | testMode?: boolean 11 | } 12 | export const transformerDirectory = path.join(__dirname, "../", "transforms"); 13 | export const jscodeshiftExecutable = require.resolve(".bin/jscodeshift"); 14 | 15 | export function runTransform({ 16 | projectDir, 17 | flags, 18 | transformer, 19 | customImportPath, 20 | testMode, 21 | }: Options ) { 22 | const transformerPath = path.join(transformerDirectory, `${transformer}.js`); 23 | 24 | let args = []; 25 | 26 | if(flags.instanceNames){ 27 | if(typeof flags.instanceNames === 'string'){ 28 | args.push(`--instanceNames=${flags.instanceNames}`) 29 | } 30 | } 31 | const { dry, print, runInBand } = flags; 32 | 33 | if (dry) { 34 | args.push("--dry"); 35 | } 36 | if (print) { 37 | args.push("--print"); 38 | } 39 | if (runInBand) { 40 | args.push("--run-in-band"); 41 | } 42 | if(testMode){ 43 | args.push("--verbose=2"); 44 | } else { 45 | args.push("--verbose=0"); 46 | } 47 | args.push("--no-babel") 48 | if(customImportPath){ 49 | args.push(`--ignore-pattern=**/${customImportPath}/**`); 50 | } 51 | if(typeof projectDir === 'string'){ 52 | if(fs.existsSync(path.join(projectDir, '.gitignore'))){ 53 | args.push(`--ignore-config=${path.join(projectDir, '.gitignore')}`) 54 | } 55 | else if(fs.existsSync(path.join(projectDir,'..', '.gitignore'))){ 56 | args.push(`--ignore-config=${path.join(projectDir, '..','.gitignore')}`) 57 | } 58 | } 59 | args.push("--ignore-pattern=**/node_modules/**"); 60 | // TODO Check TSX parser 61 | args.push("--extensions=tsx,ts,js,tsx"); 62 | args.push("--parser=tsx"); 63 | 64 | args = args.concat(["--transform", transformerPath]); 65 | 66 | args = args.concat(projectDir); 67 | 68 | console.log(`Executing command: jscodeshift ${args.join(" ")}`); 69 | 70 | const result = execa.sync(jscodeshiftExecutable, args, { 71 | stdio: testMode ? "pipe" : "inherit", 72 | stripFinalNewline: false, 73 | }); 74 | 75 | if (result.stderr) { 76 | throw result.stderr; 77 | } 78 | return result 79 | } 80 | --------------------------------------------------------------------------------