├── .env.example ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── doc_request.md │ ├── website_request.md │ └── z_doc_release.md └── workflows │ └── ci.yml ├── .gitignore ├── .husky └── pre-commit ├── .prettierignore ├── .prettierrc ├── .vs ├── VSWorkspaceState.json ├── docs │ └── v15 │ │ └── .suo └── slnx.sqlite ├── README.md ├── SECURITY.md ├── config.js ├── content ├── 100-getting-started │ ├── 01-quickstart.mdx │ ├── 02-setup-prisma │ │ ├── 100-start-from-scratch │ │ │ ├── 110-relational-databases │ │ │ │ ├── 100-connect-your-database.mdx │ │ │ │ ├── 150-using-prisma-migrate.mdx │ │ │ │ ├── 200-install-prisma-client.mdx │ │ │ │ ├── 250-querying-the-database.mdx │ │ │ │ ├── 300-next-steps.mdx │ │ │ │ └── index.mdx │ │ │ ├── 120-mongodb │ │ │ │ ├── 100-connect-your-database.mdx │ │ │ │ ├── 125-creating-the-prisma-schema.mdx │ │ │ │ ├── 200-install-prisma-client.mdx │ │ │ │ ├── 250-querying-the-database.mdx │ │ │ │ ├── 300-next-steps.mdx │ │ │ │ └── index.mdx │ │ │ └── index.mdx │ │ ├── 200-add-to-existing-project │ │ │ ├── 110-relational-databases │ │ │ │ ├── 100-connect-your-database.mdx │ │ │ │ ├── 150-introspection.mdx │ │ │ │ ├── 200-install-prisma-client.mdx │ │ │ │ ├── 250-querying-the-database.mdx │ │ │ │ ├── 300-next-steps.mdx │ │ │ │ ├── index.mdx │ │ │ │ └── prisma-client-node-module.png │ │ │ ├── 120-mongodb │ │ │ │ ├── 100-connect-your-database.mdx │ │ │ │ ├── 125-creating-the-prisma-schema.mdx │ │ │ │ ├── 200-install-prisma-client.mdx │ │ │ │ ├── 250-querying-the-database.mdx │ │ │ │ ├── 300-next-steps.mdx │ │ │ │ ├── index.mdx │ │ │ │ └── prisma-client-node-module.png │ │ │ └── index.mdx │ │ └── index.mdx │ └── index.mdx ├── 200-concepts │ ├── 050-overview │ │ ├── 100-what-is-prisma │ │ │ ├── 100-data-modeling.mdx │ │ │ └── index.mdx │ │ ├── 200-why-prisma.mdx │ │ ├── 250-should-you-use-prisma.mdx │ │ ├── 300-prisma-in-your-stack │ │ │ ├── 01-rest.md │ │ │ ├── 02-graphql.md │ │ │ ├── 03-is-prisma-an-orm.mdx │ │ │ └── index.mdx │ │ ├── index.mdx │ │ └── user-table.svg │ ├── 100-components │ │ ├── 01-prisma-schema │ │ │ ├── 02-data-sources.mdx │ │ │ ├── 03-generators.mdx │ │ │ ├── 04-data-model.mdx │ │ │ ├── 06-relations │ │ │ │ ├── 07-referential-actions.mdx │ │ │ │ ├── 100-one-to-one-relations.mdx │ │ │ │ ├── 200-one-to-many-relations.mdx │ │ │ │ ├── 300-many-to-many-relations.mdx │ │ │ │ ├── 400-self-relations.mdx │ │ │ │ ├── 500-troubleshooting-relations.mdx │ │ │ │ ├── index.mdx │ │ │ │ ├── one-to-many.png │ │ │ │ ├── relations-intro.png │ │ │ │ └── sample-schema.png │ │ │ ├── 08-features-without-psl-equivalent.mdx │ │ │ ├── index.mdx │ │ │ └── prisma-schema │ │ │ │ ├── relations-intro.png │ │ │ │ └── sample-database.png │ │ ├── 02-prisma-client │ │ │ ├── 000-working-with-prismaclient │ │ │ │ ├── 010-generating-prisma-client.mdx │ │ │ │ ├── 015-instantiate-prisma-client.mdx │ │ │ │ ├── 020-use-custom-model-and-field-names.mdx │ │ │ │ ├── 100-connection-management.mdx │ │ │ │ ├── 115-connection-pool.mdx │ │ │ │ ├── 130-logging.mdx │ │ │ │ ├── 150-error-formatting.mdx │ │ │ │ ├── index.mdx │ │ │ │ └── prisma-client-node-module.png │ │ │ ├── 030-crud.mdx │ │ │ ├── 035-select-fields.mdx │ │ │ ├── 037-relation-queries.mdx │ │ │ ├── 050-filtering-and-sorting.mdx │ │ │ ├── 051-working-with-fields │ │ │ │ ├── 100-working-with-json-fields.mdx │ │ │ │ ├── 200-working-with-scalar-lists-arrays.mdx │ │ │ │ └── index.mdx │ │ │ ├── 052-advanced-type-safety │ │ │ │ ├── 100-operating-against-partial-structures-of-model-types.mdx │ │ │ │ ├── 99-prisma-validator.mdx │ │ │ │ └── index.mdx │ │ │ ├── 053-middleware │ │ │ │ ├── 100-soft-delete-middleware.mdx │ │ │ │ ├── 200-logging-middleware.mdx │ │ │ │ ├── 300-session-data-middleware.mdx │ │ │ │ └── index.mdx │ │ │ ├── 054-pagination.mdx │ │ │ ├── 055-aggregation-grouping-summarizing.mdx │ │ │ ├── 058-transactions.mdx │ │ │ ├── 070-case-sensitivity.mdx │ │ │ ├── 080-null-and-undefined.mdx │ │ │ ├── 090-raw-database-access.mdx │ │ │ ├── 140-debugging.mdx │ │ │ ├── 210-module-bundlers.mdx │ │ │ ├── 220-database-polyfills.mdx │ │ │ ├── 230-handling-exceptions-and-errors.mdx │ │ │ └── index.mdx │ │ ├── 03-prisma-migrate │ │ │ ├── 100-legacy-migrate.mdx │ │ │ ├── 100-supported-types-and-db-features.mdx │ │ │ ├── 150-db-push.mdx │ │ │ ├── 200-shadow-database.mdx │ │ │ ├── 300-prisma-migrate-limitations-issues.mdx │ │ │ ├── index.mdx │ │ │ ├── migrate-mapping.png │ │ │ ├── shadow-database.png │ │ │ └── shadow-db.png │ │ ├── 04-introspection.mdx │ │ ├── 05-prisma-cli │ │ │ ├── 01-installation.mdx │ │ │ └── index.mdx │ │ ├── 06-prisma-studio.mdx │ │ ├── 07-prisma-data-platform.mdx │ │ ├── 08-prisma-engines │ │ │ ├── 200-query-engine.mdx │ │ │ └── index.mdx │ │ ├── 250-preview-features │ │ │ ├── 050-client-preview-features.mdx │ │ │ ├── 080-cli-preview-features.mdx │ │ │ ├── 100-sql-server │ │ │ │ ├── 001-sql-server-start-from-scratch.mdx │ │ │ │ ├── 010-sql-server-connection-string.mdx │ │ │ │ ├── 020-sql-server-local.mdx │ │ │ │ ├── 030-sql-server-docker.mdx │ │ │ │ └── index.mdx │ │ │ └── index.mdx │ │ └── index.mdx │ ├── 200-database-connectors │ │ ├── 03-postgresql.mdx │ │ ├── 04-mysql.mdx │ │ ├── 05-sqlite.mdx │ │ ├── 06-microsoft-sql-server.mdx │ │ ├── 07-mongodb.mdx │ │ ├── index.mdx │ │ └── mongodb.png │ ├── 300-more │ │ ├── 050-environment-variables │ │ │ ├── 100-managing-env-files-and-setting-variables.mdx │ │ │ ├── 200-using-multiple-env-files.mdx │ │ │ └── index.mdx │ │ ├── 100-editor-setup.mdx │ │ ├── 300-telemetry.mdx │ │ ├── 400-comparisons │ │ │ ├── 01-prisma-and-typeorm.mdx │ │ │ ├── 02-prisma-and-sequelize.mdx │ │ │ ├── 03-prisma-and-mongoose.mdx │ │ │ └── index.mdx │ │ └── index.mdx │ └── index.mdx ├── 300-guides │ ├── 010-schema-query-examples │ │ └── index.mdx │ ├── 050-database │ │ ├── 100-developing-with-prisma-migrate │ │ │ ├── 050-add-prisma-migrate-to-a-project.mdx │ │ │ ├── 150-team-development.mdx │ │ │ ├── 160-baselining.mdx │ │ │ ├── 165-enable-native-database-functions.mdx │ │ │ ├── 168-include-unsupported-database-features.mdx │ │ │ ├── 170-customizing-migrations.mdx │ │ │ ├── 200-troubleshooting-development.mdx │ │ │ ├── deploy-db.png │ │ │ ├── existing-database.png │ │ │ ├── index.mdx │ │ │ ├── migrate-team-dev.png │ │ │ ├── migration-history.png │ │ │ └── new-dev-db.png │ │ ├── 300-seed-database.mdx │ │ ├── 400-prototyping-schema-db-push.mdx │ │ ├── 700-patching-production.mdx │ │ ├── 800-production-troubleshooting.mdx │ │ ├── 900-advanced-database-tasks │ │ │ ├── 06-cascading-deletes │ │ │ │ ├── 01-postgresql.mdx │ │ │ │ ├── 02-mysql.mdx │ │ │ │ ├── 03-sqlite.mdx │ │ │ │ ├── cascading-deletes │ │ │ │ │ └── cascading-deletes-illustration.png │ │ │ │ └── index.mdx │ │ │ ├── 07-data-validation │ │ │ │ ├── 01-postgresql.mdx │ │ │ │ └── index.mdx │ │ │ ├── 08-sql-views.mdx │ │ │ └── index.mdx │ │ └── index.mdx │ ├── 100-performance-and-optimization │ │ ├── 085-query-optimization-performance.mdx │ │ ├── 100-prisma-client-transactions-guide.mdx │ │ ├── 150-connection-management │ │ │ ├── 200-configure-pg-bouncer.mdx │ │ │ ├── index.mdx │ │ │ ├── serverless-connections-2.png │ │ │ └── serverless-connections.png │ │ └── index.mdx │ ├── 150-testing │ │ ├── 100-unit-testing.mdx │ │ ├── 150-integration-testing.mdx │ │ ├── Docker_Diagram_V1.png │ │ └── index.mdx │ ├── 200-deployment │ │ ├── 100-deployment.mdx │ │ ├── 110-deployment-guides │ │ │ ├── 150-deploying-to-azure-functions.mdx │ │ │ ├── 200-deploying-to-heroku.mdx │ │ │ ├── 300-deploying-to-vercel.mdx │ │ │ ├── 400-deploying-to-aws-lambda.mdx │ │ │ ├── 500-deploying-to-netlify.mdx │ │ │ ├── 600-deploying-migrations-from-a-local-environment.mdx │ │ │ ├── 650-caveats-when-deploying-to-aws-platforms.mdx │ │ │ ├── 700-deploying-to-a-different-os.mdx │ │ │ └── index.mdx │ │ ├── 150-deploy-database-changes-with-prisma-migrate.mdx │ │ ├── images │ │ │ ├── heroku-architecture.png │ │ │ ├── heroku-deployed.png │ │ │ ├── netlify-admin-ui.png │ │ │ ├── netlify-architecture.png │ │ │ ├── netlify-deployed-seed.png │ │ │ ├── netlify-deployed.png │ │ │ ├── netlify-environment.png │ │ │ ├── netlify-fork.png │ │ │ └── netlify-init-1.png │ │ └── index.mdx │ ├── 300-upgrade-guides │ │ ├── 200-upgrading-to-latest │ │ │ ├── 300-codemods.mdx │ │ │ └── index.mdx │ │ ├── 800-upgrade-from-prisma-1 │ │ │ ├── 01-how-to-upgrade.mdx │ │ │ ├── 02-schema-incompatibilities.mdx │ │ │ ├── 03-upgrading-the-prisma-layer.mdx │ │ │ ├── 04-upgrading-nexus-prisma-to-nexus.mdx │ │ │ ├── 05-upgrading-prisma-binding-to-nexus.mdx │ │ │ ├── 06-upgrading-prisma-binding-to-sdl-first.mdx │ │ │ ├── 07-upgrading-a-rest-api.mdx │ │ │ └── index.mdx │ │ ├── 900-upgrade-from-graphcool.mdx │ │ └── index.mdx │ ├── 400-migrate-to-prisma │ │ ├── 01-migrate-from-typeorm.mdx │ │ ├── 02-migrate-from-sequelize.mdx │ │ └── index.mdx │ ├── 600-general-guides │ │ ├── 100-database-workflows │ │ │ ├── 04-unique-constraints-and-indexes │ │ │ │ ├── 01-postgresql.mdx │ │ │ │ ├── 02-mysql.mdx │ │ │ │ ├── 03-sqlite.mdx │ │ │ │ ├── index.mdx │ │ │ │ └── unique-constraints-and-indexes │ │ │ │ │ └── unique-constraint-illustration.png │ │ │ ├── 05-foreign-keys │ │ │ │ ├── 01-postgresql.mdx │ │ │ │ ├── 02-mysql.mdx │ │ │ │ ├── 03-sqlite.mdx │ │ │ │ ├── foreign-keys │ │ │ │ │ └── foreign-keys-illustration.png │ │ │ │ └── index.mdx │ │ │ └── index.mdx │ │ └── index.mdx │ └── index.mdx ├── 400-reference │ ├── 100-system-requirements.mdx │ ├── 200-api-reference │ │ ├── 050-prisma-client-reference.mdx │ │ ├── 100-prisma-schema-reference.mdx │ │ ├── 200-command-reference.mdx │ │ ├── 250-error-reference.mdx │ │ ├── 300-environment-variables-reference.mdx │ │ └── index.mdx │ ├── 300-database-reference │ │ ├── 01-database-features.mdx │ │ ├── 02-connection-urls.mdx │ │ ├── 03-supported-databases.mdx │ │ └── index.mdx │ └── index.mdx ├── 500-support │ ├── 050-creating-bug-reports.mdx │ ├── 100-help-articles │ │ ├── 100-autocompletion-in-graphql-resolvers-with-js.mdx │ │ ├── 200-working-with-many-to-many-relations.mdx │ │ ├── 300-finding-entities-based-on-relation.mdx │ │ ├── 400-nextjs-prisma-client-dev-practices.mdx │ │ └── index.mdx │ └── index.mdx ├── 600-about │ ├── 00-whats-new-in-prisma-docs.mdx │ ├── 01-about-the-docs.mdx │ ├── 02-style-guide │ │ ├── 01-mdx-examples.mdx │ │ ├── 02-template.mdx │ │ ├── 03-frontmatter.mdx │ │ └── index.mdx │ ├── 05-faq.mdx │ ├── 06-limitations.mdx │ ├── 07-roadmap.mdx │ ├── 08-releases.mdx │ ├── 09-example-projects.mdx │ ├── index.mdx │ └── user-table.svg └── doc-images │ ├── baseline-production-from-local.png │ ├── connect-sql-server.png │ ├── cursor-1.png │ ├── cursor-2.png │ ├── cursor-3.png │ ├── database-setup-illustration.png │ ├── database-tables.png │ ├── new-query.png │ ├── offset-skip-take.png │ ├── prisma-introspection-development-workflow.png │ └── prisma-migrate-development-workflow.png ├── functions └── index.js ├── gatsby-browser.js ├── gatsby-config.js ├── gatsby-node.js ├── gatsby-ssr.js ├── images.d.ts ├── jest.setup.js ├── netlify.toml ├── package-lock.json ├── package.json ├── plugins ├── gatsby-plugin-page-list │ ├── gatsby-node.js │ ├── index.js │ └── package.json ├── gatsby-remark-check-links-numberless │ ├── index.js │ └── package.json └── gatsby-remark-to-absoluteurl │ ├── index.js │ └── package.json ├── prisma ├── migrations │ ├── 20201216150604_init │ │ └── migration.sql │ └── 20201216150920_add_feedback_text │ │ └── migration.sql └── schema.prisma ├── renovate.json ├── schema.sql ├── src ├── components │ ├── button │ │ ├── AccentButton.tsx │ │ ├── Button.tsx │ │ ├── PrimaryButton.tsx │ │ ├── SecondaryButton.tsx │ │ ├── SpecialButton.tsx │ │ └── index.tsx │ ├── customMdx │ │ ├── admonition.tsx │ │ ├── button.tsx │ │ ├── code.tsx │ │ ├── codeBlock.tsx │ │ ├── codeWithResult.tsx │ │ ├── collapsible.tsx │ │ ├── copy.tsx │ │ ├── fileWithIcon.tsx │ │ ├── footnote.tsx │ │ ├── index.tsx │ │ ├── navigationLinksContainer.tsx │ │ ├── parallelBlocks.tsx │ │ ├── prism │ │ │ ├── index.css │ │ │ └── prism-prisma.js │ │ ├── quiz.tsx │ │ ├── subSections.tsx │ │ ├── switchTech.tsx │ │ ├── tabbedContent │ │ │ ├── DefaultTabOS.tsx │ │ │ └── index.tsx │ │ ├── table.tsx │ │ ├── tip.tsx │ │ └── topBlock.tsx │ ├── footer.tsx │ ├── header.tsx │ ├── image.tsx │ ├── layout.css │ ├── layout.tsx │ ├── link.tsx │ ├── newsletter │ │ ├── index.tsx │ │ ├── mailChimp.ts │ │ └── valid.ts │ ├── pageBottom.tsx │ ├── parentTitleComp.tsx │ ├── search │ │ ├── hitComps.tsx │ │ ├── index.tsx │ │ ├── input.tsx │ │ └── overlay.tsx │ ├── select.tsx │ ├── seo.tsx │ ├── sidebar │ │ ├── index.tsx │ │ ├── tree.tsx │ │ └── treeNode.tsx │ ├── switcherBlock.tsx │ ├── techSwitcher.tsx │ ├── toc.tsx │ └── topSection.tsx ├── hooks │ ├── useAllArticlesQuery.ts │ ├── useLayoutQuery.ts │ └── useWindowDimensions.ts ├── html.js ├── icons │ ├── ArrowDown.tsx │ ├── ArrowEmail.tsx │ ├── ArrowRight.tsx │ ├── Clear.tsx │ ├── Code.tsx │ ├── Copy.tsx │ ├── Database.tsx │ ├── Display.tsx │ ├── Down.tsx │ ├── DownChevron.tsx │ ├── Email.tsx │ ├── ExternalLink.tsx │ ├── Facebook.tsx │ ├── File.tsx │ ├── Git.tsx │ ├── GitGrey.tsx │ ├── HashLink.tsx │ ├── Logo.tsx │ ├── Prisma.tsx │ ├── PrismaLogoGrey.tsx │ ├── RightChevron.tsx │ ├── Search.tsx │ ├── SearchSlash.tsx │ ├── Slack.tsx │ ├── Twitter.tsx │ ├── Up.tsx │ ├── UpChevron.tsx │ ├── Youtube.tsx │ ├── home │ │ ├── CLI.tsx │ │ ├── DbLink.tsx │ │ └── Schema.tsx │ └── technologies │ │ ├── Flow.tsx │ │ ├── Go.tsx │ │ ├── JS.tsx │ │ ├── MongoDB.tsx │ │ ├── MySQL.tsx │ │ ├── NodeJS.tsx │ │ ├── PostgreSQL.tsx │ │ ├── SQLite.tsx │ │ └── Typescript.tsx ├── images │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── home-bg.svg │ └── list-dot.png ├── interfaces │ ├── AllArticles.interface.ts │ ├── Article.interface.ts │ ├── EdgeNode.interface.ts │ └── Layout.interface.ts ├── layouts │ └── articleLayout.tsx ├── pages │ ├── 404.tsx │ └── index.tsx └── utils │ ├── algolia.js │ ├── goToNavItem.js │ ├── parentTitle.ts │ ├── stats.js │ ├── stringify.ts │ ├── treeData.ts │ └── urlGenerator.ts ├── static └── social │ └── docs-social.png ├── tsconfig.json └── tslint.json /.env.example: -------------------------------------------------------------------------------- 1 | # rename this file to .env and supply the values listed below 2 | # also make sure they are available to the build tool (e.g. Netlify) 3 | # warning: variables prefixed with GATSBY_ will be made available to client-side code 4 | # be careful not to expose sensitive data (in this case your Algolia admin key) 5 | GATSBY_ALGOLIA_APP_ID="XXX" 6 | GATSBY_ALGOLIA_SEARCH_KEY="XXX" 7 | GATSBY_ALGOLIA_ADMIN_API_KEY="XXX" 8 | GATSBY_ALGOLIA_INDEX_NAME="XXX" -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/doc_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: ✍ Documentation request or bug 3 | about: Report a content issue (incorrect content, spelling mistake, broken link), request new content, or suggest an improvement. 4 | labels: 'docs' 5 | assignees: '' 6 | --- 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/website_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: ✨ Doc site request or bug 3 | about: Request a website feature or improvement, or report a bug. For documentation, please use documentation request. 4 | labels: 'website' 5 | --- 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/z_doc_release.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🎉 Documentation release 3 | about: INTERNAL ONLY. Documentation release tasks. 4 | title: 'Release:' 5 | labels: 'docs,docs/task' 6 | assignees: '' 7 | --- 8 | 9 | ## Release 10 | 11 | - [ ] Merge in new content 12 | - [ ] Update 'What's new' page with links to the relase notes and new docs (example: https://www.prisma.io/docs/about/whats-new-in-prisma-docs#april-04-2021) 13 | - [ ] Add links to release notes 14 | 15 | ## After release 16 | 17 | - [ ] Add the 'What's new' video 18 | - [ ] Clean up milestone 19 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | jobs: 10 | gatsby-for-percy: 11 | name: Percy screenshots via Gatsby build 12 | runs-on: ubuntu-latest 13 | env: 14 | PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }} 15 | steps: 16 | - uses: actions/checkout@v2 17 | - uses: actions/setup-node@v2 18 | with: 19 | cache: 'npm' 20 | node-version: '14' 21 | - run: npm ci 22 | - run: npx gatsby build 23 | -------------------------------------------------------------------------------- /.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 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # dotenv environment variables file 55 | .env 56 | 57 | # gatsby files 58 | .cache/ 59 | public 60 | reduxcache* 61 | 62 | # Mac files 63 | .DS_Store 64 | 65 | # Yarn 66 | yarn-error.log 67 | .pnp/ 68 | .pnp.js 69 | # Yarn Integrity file 70 | .yarn-integrity 71 | yarn.lock 72 | 73 | .envrc 74 | 75 | # Example page 76 | content/00-example.mdx 77 | 78 | # History 79 | .history/ 80 | 81 | # webStorm settings 82 | .idea 83 | 84 | # vscode settings 85 | .vscode/ 86 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | public/ 3 | .cache/ 4 | static/ 5 | out/ 6 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "jsxBracketSameLine": false, 4 | "singleQuote": true, 5 | "tabWidth": 2, 6 | "trailingComma": "es5", 7 | "semi": false, 8 | "overrides": [ 9 | { 10 | "files": "*.mdx", 11 | "options": { 12 | "printWidth": 80 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /.vs/VSWorkspaceState.json: -------------------------------------------------------------------------------- 1 | { 2 | "ExpandedNodes": [""], 3 | "PreviewInSolutionExplorer": false 4 | } 5 | -------------------------------------------------------------------------------- /.vs/docs/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/.vs/docs/v15/.suo -------------------------------------------------------------------------------- /.vs/slnx.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/.vs/slnx.sqlite -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /content/100-getting-started/02-setup-prisma/100-start-from-scratch/120-mongodb/200-install-prisma-client.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Install Prisma Client' 3 | metaTitle: 'Install Prisma Client' 4 | metaDescription: 'Install and generate the Prisma Client in your project' 5 | langSwitcher: ['typescript', 'node'] 6 | dbSwitcher: ['mongodb'] 7 | toc: false 8 | --- 9 | 10 | ## Install and generate Prisma Client 11 | 12 | To get started with Prisma Client, you need to install the `@prisma/client` package: 13 | 14 | ```terminal copy 15 | npm install @prisma/client 16 | ``` 17 | 18 | Notice that the install command automatically invokes `prisma generate` for you which reads your Prisma schema and generates a version of Prisma Client that is _tailored_ to your models. 19 | 20 | ![Install and generate Prisma Client](https://imgur.com/FensWfo.png) 21 | 22 | Whenever you make changes to your Prisma schema in the future, you manually need to invoke `prisma generate` in order to accommodate the changes in your Prisma Client API. 23 | 24 | 25 | 26 | 27 | 28 | 34 | Creating the Prisma schema 35 | 36 | 37 | 43 | Querying the database 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 60 | Creating the Prisma schema 61 | 62 | 63 | 69 | Querying the database 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /content/100-getting-started/02-setup-prisma/100-start-from-scratch/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Start from scratch' 3 | metaTitle: 'Start from scratch with Prisma' 4 | metaDescription: 'Learn how to create a new Node.js or TypeScript project from scratch by connecting Prisma to your database of choice and generating a Prisma Client for database access.' 5 | toc: false 6 | --- 7 | 8 | 9 | 10 | Start a fresh project from scratch with following tutorials as they introduce you to the [Prisma CLI](../../../concepts/components/prisma-cli), [Prisma Client](../../../concepts/components/prisma-client), and [Prisma Migrate](../../../concepts/components/prisma-migrate). 11 | 12 | 13 | 14 | ## In this section 15 | 16 | 17 | -------------------------------------------------------------------------------- /content/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/prisma-client-node-module.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/100-getting-started/02-setup-prisma/200-add-to-existing-project/110-relational-databases/prisma-client-node-module.png -------------------------------------------------------------------------------- /content/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/200-install-prisma-client.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Install Prisma Client' 3 | metaTitle: 'Install Prisma Client' 4 | metaDescription: 'Install and generate the Prisma Client in your project' 5 | langSwitcher: ['typescript', 'node'] 6 | dbSwitcher: ['mongodb'] 7 | toc: false 8 | --- 9 | 10 | ## Install and generate Prisma Client 11 | 12 | To get started with Prisma Client, you need to install the `@prisma/client` package: 13 | 14 | ```terminal copy 15 | npm install @prisma/client 16 | ``` 17 | 18 | Notice that the install command automatically invokes `prisma generate` for you which reads your Prisma schema and generates a version of Prisma Client that is _tailored_ to your models. 19 | 20 | ![Install and generate Prisma Client](https://imgur.com/FensWfo.png) 21 | 22 | Whenever you make changes to your Prisma schema in the future, you manually need to invoke `prisma generate` in order to accommodate the changes in your Prisma Client API. 23 | 24 | 25 | 26 | 27 | 28 | 34 | Creating the Prisma schema 35 | 36 | 37 | 43 | Querying the database 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 60 | Creating the Prisma schema 61 | 62 | 63 | 69 | Querying the database 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /content/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/prisma-client-node-module.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/100-getting-started/02-setup-prisma/200-add-to-existing-project/120-mongodb/prisma-client-node-module.png -------------------------------------------------------------------------------- /content/100-getting-started/02-setup-prisma/200-add-to-existing-project/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Add to existing project' 3 | metaTitle: 'Add Prisma to an existing project' 4 | metaDescription: 'Learn how to add Prisma to an existing Node.js or TypeScript project by connecting it to your database of choice and generating a Prisma Client for database access.' 5 | --- 6 | 7 | 8 | -------------------------------------------------------------------------------- /content/100-getting-started/02-setup-prisma/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Set up Prisma' 3 | metaTitle: '' 4 | metaDescription: '' 5 | toc: false 6 | staticLink: true 7 | --- 8 | 9 | 10 | 11 | Start from scratch or add Prisma to an existing project. The following tutorials introduce you to the [Prisma CLI](../../../concepts/components/prisma-cli), [Prisma Client](../../../concepts/components/prisma-client), and [Prisma Migrate](../../../concepts/components/prisma-migrate). 12 | 13 | 14 | 15 | ## In this section 16 | 17 | 18 | -------------------------------------------------------------------------------- /content/200-concepts/050-overview/300-prisma-in-your-stack/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Prisma in your stack' 3 | metaTitle: 'How Prisma fits into your stack' 4 | metaDescription: 'How Prisma fits into your stack' 5 | toc: false 6 | --- 7 | 8 | 9 | 10 | Prisma is a database toolkit that simplifies database access. You can use Prisma tools to build a GraphQL or REST API, or as part of a fullstack application - the extent to which you incorporate Prisma is up to you. 11 | 12 | 13 | 14 | If you are building a GraphQL API, check out [GraphQL Nexus](https://nexusjs.org/) - code first GraphQL schemas with [a plugin specifically for Prisma](https://nxs.li/plugins/prisma). 15 | 16 | 17 | 18 | 19 | 20 | ## In this section 21 | 22 | 23 | -------------------------------------------------------------------------------- /content/200-concepts/050-overview/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Overview' 3 | metaTitle: 'Overview' 4 | metaDescription: 'Overview' 5 | staticLink: true 6 | toc: false 7 | --- 8 | 9 | ## In this section 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/01-prisma-schema/02-data-sources.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Data sources' 3 | metaTitle: 'Data sources (Reference)' 4 | metaDescription: 'Data sources enable Prisma to connect to your database. This page explains how to configure data sources in your Prisma schema.' 5 | --- 6 | 7 | 8 | 9 | A data source determines how Prisma connects your database, and is represented by the [`datasource`](../../../reference/api-reference/prisma-schema-reference#datasource) block in the Prisma schema. The following data source uses the `postgresql` provider and includes a connection URL: 10 | 11 | ```prisma 12 | datasource db { 13 | provider = "postgresql" 14 | url = "postgresql://johndoe:mypassword@localhost:5432/mydb?schema=public" 15 | } 16 | ``` 17 | 18 | A Prisma schema can only have _one_ data source. However, you can: 19 | 20 | - [Programmatically override a data source `url` when creating your `PrismaClient`](../../../reference/api-reference/prisma-client-reference#programmatically-override-a-datasource-url) 21 | - [Specify a different URL for Prisma Migrate's shadow database if you are working with cloud-hosted development databases](../prisma-migrate#cloud-hosted-shadow-databases-must-be-created-manually) 22 | 23 | > **Note**: Multiple provider support was removed in 2.22.0. Please see [Deprecation of provider array notation](https://github.com/prisma/prisma/issues/3834) for more information. 24 | 25 | 26 | 27 | ## SSL certificates 28 | 29 | Some data source `provider`s allow you to configure your connection with SSL, and provide parameters for the `url` to specificy the location of certificates. 30 | 31 | - [Configuring an SSL connection with PostgreSQL](../../database-connectors/postgresql#configuring-an-ssl-connection) 32 | - [Configuring an SSL connection with MySQL](../../database-connectors/mysql#configuring-an-ssl-connection) 33 | 34 | Prisma resolves SSL certificates relative to the `./prisma` directory. If your certificate files are located outside that directory, e.g. your project root directory, use relative paths for certificates: 35 | 36 | ```prisma 37 | datasource db { 38 | provider = "postgresql" 39 | url = "postgresql://johndoe:mypassword@localhost:5432/mydb?schema=public&sslmode=require&sslcert=../server-ca.pem&sslidentity=../client-identity.p12&sslpassword=" 40 | } 41 | ``` 42 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/01-prisma-schema/06-relations/one-to-many.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/200-concepts/100-components/01-prisma-schema/06-relations/one-to-many.png -------------------------------------------------------------------------------- /content/200-concepts/100-components/01-prisma-schema/06-relations/relations-intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/200-concepts/100-components/01-prisma-schema/06-relations/relations-intro.png -------------------------------------------------------------------------------- /content/200-concepts/100-components/01-prisma-schema/06-relations/sample-schema.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/200-concepts/100-components/01-prisma-schema/06-relations/sample-schema.png -------------------------------------------------------------------------------- /content/200-concepts/100-components/01-prisma-schema/prisma-schema/relations-intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/200-concepts/100-components/01-prisma-schema/prisma-schema/relations-intro.png -------------------------------------------------------------------------------- /content/200-concepts/100-components/01-prisma-schema/prisma-schema/sample-database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/200-concepts/100-components/01-prisma-schema/prisma-schema/sample-database.png -------------------------------------------------------------------------------- /content/200-concepts/100-components/02-prisma-client/000-working-with-prismaclient/150-error-formatting.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Configuring error formatting' 3 | metaTitle: 'Configuring error formatting (Concepts)' 4 | metaDescription: 'This page explains how to configure the formatting of errors when using Prisma Client.' 5 | --- 6 | 7 | 8 | 9 | By default, Prisma Client uses [ANSI escape characters](https://en.wikipedia.org/wiki/ANSI_escape_code) to pretty print the error stack and give recommendations on how to fix a problem. While this is very useful when using Prisma Client from the terminal, in contexts like a GraphQL API, you only want the minimal error without any additional formatting. 10 | 11 | This page explains how error formatting can be configured with Prisma Client. 12 | 13 | 14 | 15 | ## Formatting levels 16 | 17 | There are 3 error formatting levels: 18 | 19 | 1. **Pretty Error** (default): Includes a full stack trace with colors, syntax highlighting of the code and extended error message with a possible solution for the problem. 20 | 2. **Colorless Error**: Same as pretty errors, just without colors. 21 | 3. **Minimal Error**: The raw error message. 22 | 23 | In order to configure these different error formatting levels, there are two options: 24 | 25 | - Setting the config options via environment variables 26 | - Providing the config options to the `PrismaClient` constructor 27 | 28 | ## Formatting via environment variables 29 | 30 | - [`NO_COLOR`](../../../../reference/api-reference/environment-variables-reference/#no_color): If this env var is provided, colors are stripped from the error messages. Therefore you end up with a **colorless error**. The `NO_COLOR` environment variable is a standard described [here](https://no-color.org/). 31 | - `NODE_ENV=production`: If the env var `NODE_ENV` is set to `production`, only the **minimal error** will be printed. This allows for easier digestion of logs in production environments. 32 | 33 | ### Formatting via the `PrismaClient` constructor 34 | 35 | Alternatively, use the `PrismaClient` [`errorFormat`](../../../../reference/api-reference/prisma-client-reference#errorformat) parameter to set the error format: 36 | 37 | ```ts 38 | const prisma = new PrismaClient({ 39 | errorFormat: 'pretty', 40 | }) 41 | ``` 42 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/02-prisma-client/000-working-with-prismaclient/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Working with PrismaClient' 3 | metaTitle: 'Working with PrismaClient (Concepts)' 4 | metaDescription: 'This page explains how to generate, configure, and instantiate Prisma Client, as well as when and how to manage database connections.' 5 | --- 6 | 7 | 8 | 9 | This section describes how to generate, configure, and instantiate `PrismaClient` , as well as when and how to actively [manage connections](connection-management). 10 | 11 | 12 | 13 | ## In this section 14 | 15 | 16 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/02-prisma-client/000-working-with-prismaclient/prisma-client-node-module.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/200-concepts/100-components/02-prisma-client/000-working-with-prismaclient/prisma-client-node-module.png -------------------------------------------------------------------------------- /content/200-concepts/100-components/02-prisma-client/051-working-with-fields/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Working with fields' 3 | metaTitle: 'Working with fields (Concepts)' 4 | metaDescription: 'How to read, write, and filter by complex fields.' 5 | tocDepth: 2 6 | --- 7 | 8 | 9 | 10 | This section describes how to perform CRUD operations on more advanced field types. 11 | 12 | 13 | 14 | ## Working with Decimal 15 | 16 | `Decimal` fields are represented by the [`Decimal.js` library](https://mikemcl.github.io/decimal.js/). The following example demonstrates how to import and use `Prisma.Decimal`: 17 | 18 | ```ts 19 | import { PrismaClient, Prisma } from '@prisma/client' 20 | 21 | const newTypes = await prisma.sample.create({ 22 | data: { 23 | cost: new Prisma.Decimal(24.454545), 24 | }, 25 | }) 26 | ``` 27 | 28 | ## Working with BigInt 29 | 30 | `BigInt` fields are represented by the [`BigInt` type](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) (Node.js 10.4.0+ required). The following example demonstrates how to use the `BigInt` type: 31 | 32 | ```ts 33 | import { PrismaClient, Prisma } from '@prisma/client' 34 | 35 | const newTypes = await prisma.sample.create({ 36 | data: { 37 | revenue: BigInt(534543543534), 38 | }, 39 | }) 40 | ``` 41 | 42 | ### Serializing BigInt 43 | 44 | Prisma returns records as plain JavaScript objects. If you attempt to use `JSON.stringify` on an object that includes a `BigInt` field, you will see the following error: 45 | 46 | ``` 47 | Do not know how to serialize a BigInt 48 | ``` 49 | 50 | To work around this issue, use a customized implementation of `JSON.stringify`: 51 | 52 | ```js 53 | JSON.stringify( 54 | this, 55 | (key, value) => (typeof value === 'bigint' ? value.toString() : value) // return everything else unchanged 56 | ) 57 | ``` 58 | 59 | ## Working with Bytes 60 | 61 | `Bytes` fields are represented by the [`Buffer`](https://nodejs.org/api/buffer.html) type. The following example demonstrates how to use the `Buffer` type: 62 | 63 | ```ts 64 | import { PrismaClient, Prisma } from '@prisma/client' 65 | 66 | const newTypes = await prisma.sample.create({ 67 | data: { 68 | myField: Buffer.from([1, 2, 3, 4]), 69 | }, 70 | }) 71 | ``` 72 | 73 | ## Working with Json 74 | 75 | See: [Working with `Json` fields](working-with-json-fields) 76 | 77 | ## Working with scalar lists / scalar arrays 78 | 79 | See: [Working with scalar lists / arrays](working-with-scalar-lists-arrays) 80 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/02-prisma-client/053-middleware/200-logging-middleware.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Logging middleware' 3 | metaTitle: 'Logging middleware (Reference)' 4 | metaDescription: 'How to use middleware to log the time taken to perform any query.' 5 | --- 6 | 7 | 8 | 9 | The following example logs the time taken for a Prisma Query to run: 10 | 11 | ```ts 12 | const prisma = new PrismaClient() 13 | 14 | prisma.$use(async (params, next) => { 15 | const before = Date.now() 16 | 17 | const result = await next(params) 18 | 19 | const after = Date.now() 20 | 21 | console.log(`Query ${params.model}.${params.action} took ${after - before}ms`) 22 | 23 | return result 24 | }) 25 | 26 | const create = await prisma.post.create({ 27 | data: { 28 | title: 'Welcome to Prisma Day 2020', 29 | }, 30 | }) 31 | 32 | const createAgain = await prisma.post.create({ 33 | data: { 34 | title: 'All about database collation', 35 | }, 36 | }) 37 | ``` 38 | 39 | Example output: 40 | 41 | ```no-lines 42 | Query Post.create took 92ms 43 | Query Post.create took 15ms 44 | ``` 45 | 46 | The example is based on the following sample schema: 47 | 48 | ```prisma 49 | generator client { 50 | provider = "prisma-client-js" 51 | } 52 | 53 | datasource db { 54 | provider = "mysql" 55 | url = env("DATABASE_URL") 56 | } 57 | 58 | model Post { 59 | authorId Int? 60 | content String? 61 | id Int @default(autoincrement()) @id 62 | published Boolean @default(false) 63 | title String 64 | user User? @relation(fields: [authorId], references: [id]) 65 | language String? 66 | 67 | @@index([authorId], name: "authorId") 68 | } 69 | 70 | model User { 71 | email String @unique 72 | id Int @default(autoincrement()) @id 73 | name String? 74 | posts Post[] 75 | extendedProfile Json? 76 | role Role @default(USER) 77 | } 78 | 79 | enum Role { 80 | ADMIN 81 | USER 82 | MODERATOR 83 | } 84 | ``` 85 | 86 | 87 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/02-prisma-client/053-middleware/300-session-data-middleware.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Session data middleware' 3 | metaTitle: 'Session Data Middleware (Reference)' 4 | metaDescription: 'How to use middleware to set the value taken from session state.' 5 | --- 6 | 7 | 8 | 9 | The following example sets the `language` field of each `Post` to the context language (taken, for example, from session state): 10 | 11 | ```ts 12 | const prisma = new PrismaClient() 13 | 14 | const contextLanguage = 'en-us' // Session state 15 | 16 | prisma.$use(async (params, next) => { 17 | if (params.model == 'Post' && params.action == 'create') { 18 | params.args.data.language = contextLanguage 19 | } 20 | 21 | return next(params) 22 | }) 23 | 24 | const create = await prisma.post.create({ 25 | data: { 26 | title: 'My post in English', 27 | }, 28 | }) 29 | ``` 30 | 31 | The example is based on the following sample schema: 32 | 33 | ```prisma 34 | generator client { 35 | provider = "prisma-client-js" 36 | } 37 | 38 | datasource db { 39 | provider = "mysql" 40 | url = env("DATABASE_URL") 41 | } 42 | 43 | model Post { 44 | authorId Int? 45 | content String? 46 | id Int @default(autoincrement()) @id 47 | published Boolean @default(false) 48 | title String 49 | user User? @relation(fields: [authorId], references: [id]) 50 | language String? 51 | 52 | @@index([authorId], name: "authorId") 53 | } 54 | 55 | model User { 56 | email String @unique 57 | id Int @default(autoincrement()) @id 58 | name String? 59 | posts Post[] 60 | extendedProfile Json? 61 | role Role @default(USER) 62 | } 63 | 64 | enum Role { 65 | ADMIN 66 | USER 67 | MODERATOR 68 | } 69 | ``` 70 | 71 | 72 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/02-prisma-client/140-debugging.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Debugging' 3 | metaTitle: 'Debugging (Reference)' 4 | metaDescription: 'This page explains how to enable debugging output for Prisma Client by setting the `DEBUG` environment variable.' 5 | --- 6 | 7 | 8 | 9 | You can enable debugging output in Prisma Client via the [`DEBUG`](../../../reference/api-reference/environment-variables-reference/#debug) environment variable. It accepts two namespaces to print debugging output: 10 | 11 | - `prisma:engine`: Prints relevant debug messages happening in a Prisma [engine](https://github.com/prisma/prisma-engines/) 12 | - `prisma:client`: Prints relevant debug messages happening in the Prisma Client runtime 13 | - `prisma*`: Prints all debug messages from Prisma Client or CLI 14 | - `*`: Prints all debug messages, including external sources such as `dotenv` 15 | 16 | 17 | 18 | Prisma Client can be configured to log warnings, errors and information related to queries sent to the database. See [Configuring logging](./working-with-prismaclient/logging) for more information. 19 | 20 | 21 | 22 | 23 | 24 | ## Setting the `DEBUG` environment variable 25 | 26 | Here are examples for setting these debugging options in bash: 27 | 28 | ```terminal 29 | # enable only `prisma:engine`-level debugging output 30 | export DEBUG="prisma:engine" 31 | 32 | # enable only `prisma:client`-level debugging output 33 | export DEBUG="prisma:client" 34 | 35 | # enable both `prisma-client`- and `engine`-level debugging output 36 | export DEBUG="prisma:client,prisma:engine" 37 | ``` 38 | 39 | To enable all `prisma` debugging options, set `DEBUG` to `prisma*`: 40 | 41 | ```terminal 42 | export DEBUG="prisma*" 43 | ``` 44 | 45 | To enable _all_ debugging options, set `DEBUG` to `*`: 46 | 47 | ```terminal 48 | export DEBUG="*" 49 | ``` 50 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/02-prisma-client/210-module-bundlers.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Module bundlers' 3 | metaTitle: 'Module bundlers (Reference)' 4 | metaDescription: 'This page gives an overview of the most important things to be aware of when using a module bundler to bundle an application that uses Prisma Client.' 5 | --- 6 | 7 | ## Overview 8 | 9 | _Module bundlers_ bundle JavaScript modules into a single JavaScript file. Most bundlers work by copying over the JavaScript code from a variety of source files into the target file. 10 | 11 | Since Prisma Client is not only based on JavaScript code, but also relies on the [**query engine binary file**](../prisma-engines/query-engine#the-query-engine-binary-file) to be available, you need to make sure that your bundled code has access to the binary file. 12 | 13 | To do so, you can use plugins that let you copy over static assets: 14 | 15 | | Bundler | Plugin | 16 | | :------ | :------------------------------------------------------------------------------------------------------ | 17 | | Webpack | [`copy-webpack-plugin`](https://github.com/webpack-contrib/copy-webpack-plugin#copy-webpack-plugin) | 18 | | Parcel | [`parcel-plugin-static-files-copy`](https://github.com/elwin013/parcel-plugin-static-files-copy#readme) | 19 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/02-prisma-client/220-database-polyfills.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Database polyfills' 3 | metaTitle: 'Database polyfills (Concepts)' 4 | metaDescription: 'Prisma Client provides features that are not achievable with relational databases. These features are referred to as "polyfills" and explained on this page.' 5 | --- 6 | 7 | 8 | 9 | Prisma Client provides features that are typically either not achievable with a particular databases or require extensions. These features are referred to as _polyfills_. For all databases, this includes: 10 | 11 | - Initializing [ID](../prisma-schema/data-model#defining-an-id-field) values with `cuid` and `uuid` values 12 | - Using [`@updatedAt`](../prisma-schema/data-model#defining-attributes) to store the time when a record was last updated 13 | 14 | For relational databases, this includes: 15 | 16 | - [Implicit many-to-many relations](../prisma-schema/relations/many-to-many-relations#implicit-many-to-many-relations) 17 | 18 | For MongoDB, this includes: 19 | 20 | - [Relations in general](../prisma-schema/relations/) - foreign key relations between documents are not enforced in MongoDB 21 | 22 | 23 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/02-prisma-client/230-handling-exceptions-and-errors.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Handling exceptions and errors' 3 | metaTitle: 'Handling exceptions and errors (Reference)' 4 | metaDescription: 'This page covers how to handle exceptions and errors' 5 | --- 6 | 7 | 8 | 9 | 10 | 11 | **Error handling incomplete in MongoDB**
12 | Error handling for the [MongoDB connector](../../database-connectors/mongodb) is incomplete. 13 | 14 |
15 | 16 | In order to handle different types of errors you can use `instanceof` to check what the error is and handle it accordingly. 17 | 18 | The following example tries to create a user with an already existing email record. This will throw an error because the `email` field has the `@unique` attribute applied to it. 19 | 20 | ```prisma file=schema.prisma 21 | model User { 22 | id Int @id @default(autoincrement()) 23 | email String @unique 24 | name String? 25 | } 26 | ``` 27 | 28 | Use the `Prisma` namespace to access the error type. The [error code](../../../reference/api-reference/error-reference#error-codes) can then be checked and a message can be printed. 29 | 30 | ```ts 31 | import { PrismaClient, Prisma } from '@prisma/client' 32 | 33 | const client = new PrismaClient() 34 | 35 | try { 36 | await client.user.create({ data: { email: 'alreadyexisting@mail.com' } }) 37 | } catch (e) { 38 | if (e instanceof Prisma.PrismaClientKnownRequestError) { 39 | // The .code property can be accessed in a type-safe manner 40 | if (e.code === 'P2002') { 41 | console.log( 42 | 'There is a unique constraint violation, a new user cannot be created with this email' 43 | ) 44 | } 45 | } 46 | throw e 47 | } 48 | ``` 49 | 50 | See [Errors reference](../../../reference/api-reference/error-reference) for a detailed breakdown of the different error types and their codes. 51 | 52 |
53 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/03-prisma-migrate/migrate-mapping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/200-concepts/100-components/03-prisma-migrate/migrate-mapping.png -------------------------------------------------------------------------------- /content/200-concepts/100-components/03-prisma-migrate/shadow-database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/200-concepts/100-components/03-prisma-migrate/shadow-database.png -------------------------------------------------------------------------------- /content/200-concepts/100-components/03-prisma-migrate/shadow-db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/200-concepts/100-components/03-prisma-migrate/shadow-db.png -------------------------------------------------------------------------------- /content/200-concepts/100-components/05-prisma-cli/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Prisma CLI' 3 | metaTitle: '' 4 | metaDescription: '' 5 | toc: false 6 | --- 7 | 8 | 9 | 10 | The Prisma command line interface (CLI) is the primary way to interact with your Prisma project from the command line. It can initialize new project assets, generate Prisma Client, and analyze existing database structures through introspection to automatically create your application models. 11 | 12 | > There are also a few Preview commands that you can access with the `--preview-feature` flag if you'd like to use in-progress functionality 13 | 14 | 15 | 16 | ## Prisma CLI command reference 17 | 18 | See [Prisma CLI command reference](../../../reference/api-reference/command-reference) for a complete list of commands. 19 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/06-prisma-studio.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Prisma Studio' 3 | metaTitle: 'Prisma Studio (Reference)' 4 | metaDescription: 'Prisma Studio is a visual database editor.' 5 | experimental: false 6 | --- 7 | 8 | 9 | 10 | Prisma Studio is a visual editor for the data in your database. Note that Prisma Studio is not open source but you can still create issues in the [`prisma/studio`](https://github.com/prisma/studio) repo. 11 | 12 | You can run it with two ways: 13 | 14 | 1. Run `$ npx prisma studio` in your terminal. 15 | 2. Install [the desktop app](https://github.com/prisma/studio/releases) from the installers. Windows, macOS and Linux are supported. 16 | 17 | 18 | 19 | ## Troubleshooting 20 | 21 | ### Terminal: Failed to run script / Error in Prisma Client request 22 | 23 | Caching issues may cause Prisma Studio to use an older version of the query engine. You may see the following error: 24 | 25 | ``` 26 | Error in request: PrismaClientKnownRequestError: Failed to validate the query Error occurred during query validation & transformation 27 | ``` 28 | 29 | To resolve, delete the following folders: 30 | 31 | - `~/.cache/prisma` on macOS and Linux 32 | - `%AppData%/Prisma/Studio` on Windows 33 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/07-prisma-data-platform.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Prisma Data Platform' 3 | metaTitle: 'Prisma Data Platform (Concept)' 4 | metaDescription: 'The Prisma Data Platform (Early Access) helps developers collaborate better in projects that are using the open-source tools. One of its main features today is an online data browser.' 5 | experimental: false 6 | earlyaccess: true 7 | --- 8 | 9 | 10 | 11 | The [Prisma Data Platform](https://cloud.prisma.io/) (Early Access) helps developers collaborate better in projects that are using the open-source tools. One of its main features today is an [online data browser](https://www.prisma.io/blog/prisma-online-data-browser-ejgg5c8p3u4x). 12 | 13 | You can access it from [cloud.prisma.io](https://cloud.prisma.io). 14 | 15 | 16 | 17 | ## Current Functionality 18 | 19 | In the current version of the platform, you can: 20 | 21 | - Import your existing Prisma project 22 | - Browse your data 23 | - View your Prisma schema 24 | - Invite users 25 | 26 | ## User Roles 27 | 28 | These are the currently supported roles in the Platform: 29 | 30 | - **Admin**: Can do all possible actions, such as configuring project settings and viewing/editing data 31 | - **Developer**: Access the data browser, view and edit data and view the schema 32 | - **Collaborator**: Access the data browser and view and edit data 33 | - **Viewer**: Access the data browser and view data 34 | 35 | In order to add users, you need to use their GitHub username and they need to have an account in the Platform. 36 | 37 | ## Static IP for usage in allowlists 38 | 39 | The Prisma Data Platform can have a static IP which you can add to an allowlist in order to connect to your database through our Data Browser. 40 | 41 | You can [create an issue](https://github.com/prisma/studio/issues/new?assignees=&labels=topic%3A+hosted+data+browser&template=hosted-data-browser-bug-report.md&title=) with your request and we will enable it for you. Please note that while this is a feature that will be part of a paid plan in the future, it is currently offered for free while we are in Early Access. 42 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/250-preview-features/050-client-preview-features.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Prisma Client and schema preview features 3 | metaDescription: Prisma Client features that are currently in preview. 4 | --- 5 | 6 | 7 | 8 | The following [Preview](../../../../about/releases#preview) feature flags are available for Prisma Client and the Prisma schema: 9 | 10 | - [`orderByRelations`](../prisma-client/filtering-and-sorting#sort-by-relation-aggregate-value-preview) [Submit feedback](https://github.com/prisma/prisma/issues/5438) 11 | - [`selectRelationCount`](../prisma-client/aggregation-grouping-summarizing#count-relations) [Submit feedback](https://github.com/prisma/prisma/issues/6312) 12 | - [`orderByAggregateGroup`](../prisma-client/aggregation-grouping-summarizing#order-by-aggregate-group-preview) [Submit feedback](https://github.com/prisma/prisma/issues/6545) 13 | - [`referentialActions`](../prisma-schema/relations/referential-actions) 14 | - [`nApi` (Node-API support)](../prisma-engines/query-engine#enable-the-node-api-n-api-preview) [Submit feedback](https://github.com/prisma/prisma/issues/6301) 15 | - [`filterJson`](../prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field) [Submit feedback](https://github.com/prisma/prisma/issues/7135) 16 | - [`microsoftSqlServer`](sql-server) ([Submit feedback](https://github.com/prisma/prisma/issues/4039)) 17 | - [`mongoDb`](../../database-connectors/mongodb)) ([Submit feedback](https://github.com/prisma/prisma/issues/4039)) 18 | 19 | To enable a Preview feature, [add the feature flag to the `generator` block](#enabling-a-prisma-client-preview-feature) in the `schema.prisma` file. [Share your feedback on all Preview features on GitHub](https://github.com/prisma/prisma/issues/3108). 20 | 21 | 22 | 23 | ## Enabling a Prisma Client preview feature 24 | 25 | To enable a Prisma Client Preview feature: 26 | 27 | 1. Add the Preview feature flag to the `generator` block: 28 | 29 | ```prisma 30 | generator client { 31 | provider = "prisma-client-js" 32 | previewFeatures = ["orderByRelations"] 33 | } 34 | ``` 35 | 36 | 2. Re-generate the client: 37 | 38 | ```terminal 39 | npx prisma generate 40 | ``` 41 | 42 | 3. If you are using Visual Studio Code and the Preview feature is not available in your `.ts` file after generating the client, run the **TypeScript: Restart TS server** command. 43 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/250-preview-features/080-cli-preview-features.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Prisma CLI preview features 3 | metaDescription: Prisma CLI features that are currently in preview. 4 | --- 5 | 6 | 7 | 8 | The following Preview features are available for the Prisma CLI: 9 | 10 | - [`db seed`](../../../reference/api-reference/command-reference#db-seed-preview) 11 | 12 | To use a Preview CLI feature, [use the `--preview-feature` flag](./) when you run the command. [Share your feedback on all Preview features on GitHub](https://github.com/prisma/prisma/issues/3108). 13 | 14 | 15 | 16 | ## Enabling a Prisma CLI preview feature 17 | 18 | To use a Prisma CLI Preview feature, append the `--preview-feature` flag each time you run the command: 19 | 20 | ```terminal 21 | npx prisma db seed --preview-feature 22 | ``` 23 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/250-preview-features/100-sql-server/030-sql-server-docker.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'SQL Server on Docker' 3 | metaTitle: 'SQL Server on Docker (Preview)' 4 | metaDescription: 'Download and use the Microsoft SQL Server Docker image.' 5 | --- 6 | 7 | 8 | 9 | To run a Microsoft SQL Server container image with Docker: 10 | 11 | 1. Install and set up [Docker](https://docs.docker.com/get-docker/) 12 | 1. Run the following command in your terminal to download the Microsoft SQL Server 2019 image: 13 | 14 | ```terminal 15 | docker pull mcr.microsoft.com/mssql/server:2019-latest 16 | ``` 17 | 18 | 1. Create an instance of the container image, replacing the value of `SA_PASSWORD` with a password of your choice: 19 | 20 | ```terminal 21 | docker run --name sql_container -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=myPassword' -p 1433:1433 -d mcr.microsoft.com/mssql/server:2019-latest 22 | ``` 23 | 24 | 1. [Follow Microsoft's instructions to connect to SQL Server and use the `sqlcmd` tool](https://docs.microsoft.com/en-us/sql/linux/quickstart-install-connect-docker?view=sql-server-ver15&pivots=cs1-cmd#connect-to-sql-server), replacing the image name and password with your own. 25 | 26 | 1. From the `sqlcmd` command prompt, create a new database: 27 | 28 | ```terminal 29 | CREATE DATABASE quickstart 30 | GO 31 | ``` 32 | 33 | 1. Run the following command to check that your database was created successfully: 34 | 35 | ```terminal 36 | sp_databases 37 | GO 38 | ``` 39 | 40 | 41 | 42 | ## Connection URL credentials 43 | 44 | Based on this example, your credentials are: 45 | 46 | - **Username**: sa 47 | - **Password**: myPassword 48 | - **Database**: quickstart 49 | - **Port**: 1433 50 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/250-preview-features/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Preview features' 3 | metaTitle: 'Preview features (Reference)' 4 | metaDescription: 'Previews are typically available behind a feature flag or require some form of opt-in.' 5 | hiddenPage: false 6 | --- 7 | 8 | 9 | 10 | Some Prisma features are released as [Previews](../../../about/releases#preview). [Share your feedback on all Preview features on GitHub](https://github.com/prisma/prisma/issues/3108). For information about available preview features and how to enable them, see: 11 | 12 | - [Prisma CLI preview features](cli-preview-features) 13 | - [Prisma Client preview features](client-preview-features) 14 | 15 | 16 | -------------------------------------------------------------------------------- /content/200-concepts/100-components/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Components' 3 | metaTitle: 'Components' 4 | metaDescription: 'Components' 5 | staticLink: true 6 | toc: false 7 | --- 8 | 9 | ## In this section 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/200-concepts/200-database-connectors/05-sqlite.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'SQLite' 3 | metaTitle: 'SQLite database connector (Reference)' 4 | metaDescription: 'This page explains how Prisma can connect to a SQLite database using the SQLite database connector.' 5 | --- 6 | 7 | 8 | 9 | The SQLite data source connector connects Prisma to a [SQLite](https://www.sqlite.org/) database file. These files always have the file ending `.db` (e.g.: `dev.db`). 10 | 11 | 12 | 13 | ## Example 14 | 15 | To connect to a SQLite database file, you need to configure a [`datasource`](../components/prisma-schema/data-sources) block in your [schema file](../components/prisma-schema): 16 | 17 | ```prisma file=schema.prisma 18 | datasource db { 19 | provider = "sqlite" 20 | url = "file:./dev.db" 21 | } 22 | ``` 23 | 24 | The fields passed to the `datasource` block are: 25 | 26 | - `provider`: Specifies the `sqlite` data source connector. 27 | - `url`: Specifies the [connection URL](../../../reference/database-reference/connection-urls) for the SQLite database. The connection URL always starts with the prefix `file:` and then contains a file path pointing to the SQLite database file. In this case, the file is located in the same directory and called `dev.db`. 28 | 29 | ## Data model mapping 30 | 31 | The SQLite connector maps the [scalar types](../components/prisma-schema/data-model#scalar-fields) from the [data model](../components/prisma-schema/data-model) to native column types as follows: 32 | 33 | > Alternatively, see [Prisma schema reference](../../../reference/api-reference/prisma-schema-reference#model-field-scalar-types) for type mappings organized by Prisma type. 34 | 35 | | Data model | SQLite | 36 | | ---------- | ------------- | 37 | | `String` | `TEXT` | 38 | | `Boolean` | `BOOLEAN` | 39 | | `Int` | `INTEGER` | 40 | | `BigInt` | `INTEGER` | 41 | | `DateTime` | `NUMERIC` | 42 | | `Float` | `REAL` | 43 | | `Decimal` | `DECIMAL` | 44 | | `Json` | Not supported | 45 | | `Bytes` | Not supported | 46 | 47 | ## Connection details 48 | 49 | ### Connection URL 50 | 51 | The connection URL of a SQLite connector points to a file on your file system. For example, the following two paths are equivalent because the `.db` is in the same directory: 52 | 53 | ```prisma file=schema.prisma 54 | datasource db { 55 | provider = "sqlite" 56 | url = "file:./dev.db" 57 | } 58 | ``` 59 | 60 | is the same as: 61 | 62 | ```prisma file=schema.prisma 63 | datasource db { 64 | provider = "sqlite" 65 | url = "file:dev.db" 66 | } 67 | ``` 68 | 69 | You can also target files from the root or any other place in your file system: 70 | 71 | ```prisma file=schema.prisma 72 | datasource db { 73 | provider = "sqlite" 74 | url = "file:/Users/janedoe/dev.db" 75 | } 76 | ``` 77 | -------------------------------------------------------------------------------- /content/200-concepts/200-database-connectors/06-microsoft-sql-server.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'SQL Server' 3 | metaTitle: 'Microsoft SQL Server database connector (Reference)' 4 | metaDescription: 'This page explains how Prisma can connect to a Microsoft SQL Server database using the Microsoft SQL Server database connector.' 5 | preview: true 6 | --- 7 | 8 | 9 | 10 | The Microsoft SQL Server database connector is available as a Preview in [2.10.0](https://github.com/prisma/prisma/releases/tag/2.10.0). Refer to the [**Microsoft SQL Connector**](../../../../concepts/components/preview-features/sql-server) Preview page for tutorials, type mapping, and limitations. 11 | 12 | 13 | -------------------------------------------------------------------------------- /content/200-concepts/200-database-connectors/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Database connectors' 3 | metaTitle: '' 4 | metaDescription: '' 5 | staticLink: true 6 | toc: false 7 | --- 8 | 9 | ## Overview 10 | 11 | Prisma provides connectors for several databases. Refer to the [Database features](../../reference/database-reference/database-features) section for information about supported features and types for each database. 12 | 13 | ## In this section 14 | 15 | 16 | -------------------------------------------------------------------------------- /content/200-concepts/200-database-connectors/mongodb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/200-concepts/200-database-connectors/mongodb.png -------------------------------------------------------------------------------- /content/200-concepts/300-more/100-editor-setup.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Editor setup' 3 | metaTitle: 'Editor and IDE setup (Reference)' 4 | metaDescription: 'Learn how to configure your editor and IDEs for an optimal developer experience with Prisma.' 5 | tocDepth: 2 6 | --- 7 | 8 | 9 | 10 | This page describes how you can configure your editor for an optimal developer experience when using Prisma. 11 | 12 | If you don't see your editor here, please [open a feature request](https://github.com/prisma/prisma/issues/new?assignees=&labels=&template=feature_request.md&title=) and ask for dedicated support for your editor (e.g. for syntax highlighting and auto-formatting). 13 | 14 | 15 | 16 | ## VS Code 17 | 18 | You can install the [Prisma VS Code extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma). 19 | 20 | ## Community projects 21 | 22 | > **Note**: Community projects are not maintained or officially supported by Prisma and some features may by out of sync. Use at your own discretion. 23 | 24 | ### Emacs 25 | 26 | For Emacs you can use [emacs-prisma-mode](https://github.com/pimeys/emacs-prisma-mode). 27 | 28 | ### Vim 29 | 30 | [vim-prisma](https://github.com/pantharshit00/vim-prisma) is a plugin that provides file detection and syntax highlighting support for Prisma 2. 31 | 32 | ### Jetbrains IDE 33 | 34 | [Jetbrains](https://plugins.jetbrains.com/plugin/14240-prisma) offers an extension to support the Prisma Schema Language. 35 | -------------------------------------------------------------------------------- /content/200-concepts/300-more/400-comparisons/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Comparing Prisma' 3 | metaTitle: 'Comparing Prisma to other ORMs and ODMs.' 4 | metaDescription: 'Learn how Prisma compares to other ORMs, ORMs and database libraries, like TypeORM, Sequelize and Mongoose.' 5 | --- 6 | 7 | 8 | 9 | Find out how Prisma compares to ORMs and ODMs in the Node.js and TypeScript ecosystem. 10 | 11 | For a comprehensive overview of the most popular database libraries, read this article: [Top Node.js ORMs, Query Builders & Database Libraries in 2020 12 | ](https://www.prisma.io/dataguide/database-tools/top-nodejs-orms-query-builders-and-database-libraries-in-2020). 13 | 14 | 15 | 16 | ## In this section 17 | 18 | 19 | -------------------------------------------------------------------------------- /content/200-concepts/300-more/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'More' 3 | metaTitle: 'Telemetry and Editor Setup' 4 | metaDescription: 'In this section we cover other areas such as editor configuration for work with Prisma and telemetry.' 5 | staticLink: true 6 | toc: false 7 | --- 8 | 9 | ## In this section 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/200-concepts/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Concepts' 3 | metaTitle: 'Concepts' 4 | metaDescription: 'Concepts' 5 | toc: false 6 | --- 7 | 8 | ## In this section 9 | 10 | 11 | -------------------------------------------------------------------------------- /content/300-guides/010-schema-query-examples/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Example schemas and queries 3 | metaDescription: Example Prisma schemas that model real-life scenarios, and the types of queries they enable. 4 | hidePage: true 5 | --- 6 | 7 | 8 | 9 | A directory of example schemas and queries. 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/300-guides/050-database/100-developing-with-prisma-migrate/165-enable-native-database-functions.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Enable extensions for native database functions 3 | metaDecription: How to enable native database functions for projects that use Prisma Migrate. 4 | --- 5 | 6 | 7 | 8 | 9 | 10 | **MongoDB not supported**
11 | Prisma Migrate does not currently support the [MongoDB connector](../../../concepts/database-connectors/mongodb). 12 | 13 |
14 | 15 | Some [native database functions](/concepts/components/prisma-schema/features-without-psl-equivalent#native-database-functions) are part of optional extensions. You cannot use the function if the extension is not installed. If your project uses [Prisma Migrate](../../../concepts/components/prisma-migrate), you must install the extension as part of a migration. 16 | 17 | 18 | 19 | **Do not** manually install extensions - the [shadow database](../../../concepts/components/prisma-migrate/shadow-database) requires the same extensions, and since this database is created and deleted automatically, the only way to install extensions is to use migrations. 20 | 21 | 22 | 23 | The following example demonstrates how to install the `pgcrypto` extension as part of a migration: 24 | 25 | 1. Add the field with the native database function to your schema: 26 | 27 | ```prisma 28 | model User { 29 | id String @id @db.Uuid @default(dbgenerated("gen_random_uuid()")) 30 | } 31 | ``` 32 | 33 | If you include a cast operator (such as `::TEXT`), you must surround the entire function with parentheses: 34 | 35 | ```prisma 36 | @default(dbgenerated("(gen_random_uuid()::TEXT)") 37 | ``` 38 | 39 | 1. Use the `--create-only` flag to generate a new migration without applying it: 40 | 41 | ```terminal 42 | npx prisma migrate dev --create-only 43 | ``` 44 | 45 | 1. Open the generated `migration.sql` file and enable the `pgcrypto` module: 46 | 47 | ```sql 48 | CREATE EXTENSION IF NOT EXISTS pgcrypto; 49 | 50 | ADD COLUMN "id" UUID NOT NULL DEFAULT gen_random_uuid(), 51 | ADD PRIMARY KEY ("id"); 52 | ``` 53 | 54 | 1. Apply the migration: 55 | 56 | ```terminal 57 | npx prisma migrate dev 58 | ``` 59 | 60 | Each time you reset the database or add a new member to your team, all required functions are part of the migration history. 61 | 62 |
63 | -------------------------------------------------------------------------------- /content/300-guides/050-database/100-developing-with-prisma-migrate/168-include-unsupported-database-features.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Include unsupported database features 3 | metaDecription: How to include unsupported database features for projects that use Prisma Migrate. 4 | --- 5 | 6 | 7 | 8 | 9 | 10 | **MongoDB not supported**
11 | Prisma Migrate does not currently support the [MongoDB connector](../../../concepts/database-connectors/mongodb). 12 | 13 |
14 | 15 | Prisma Migrate uses the Prisma schema to determine what features to create in the database. However, some database features [cannot be represented in the Prisma schema](../../../concepts/components/prisma-schema/features-without-psl-equivalent) , including but not limited to: 16 | 17 | - Stored procedures 18 | - Triggers 19 | - Views 20 | - Partial indexes 21 | 22 | To add an unsupported feature to your database, you must [customize a migration](customizing-migrations) to include that feature before you apply it. 23 | 24 | 25 | 26 | 27 | 28 | The Prisma schema is able to represent [unsupported field types](../../../concepts/components/prisma-schema/features-without-psl-equivalent#unsupported-field-types) and [native database functions](enable-native-database-functions). 29 | 30 | 31 | 32 | 33 | 34 | To customize a migration to include an unsupported feature: 35 | 36 | 1. Use the `--create-only` flag to generate a new migration without applying it: 37 | 38 | ```terminal 39 | npx prisma migrate dev --create-only 40 | ``` 41 | 42 | 1. Open the generated `migration.sql` file and add the unsupported feature - for example, a partial index: 43 | 44 | ```sql 45 | CREATE UNIQUE INDEX tests_success_constraint ON posts (subject, target) 46 | WHERE success; 47 | ``` 48 | 49 | 1. Apply the migration: 50 | 51 | ```terminal 52 | npx prisma migrate dev 53 | ``` 54 | 55 | 1. Commit the modified migration to source control. 56 | 57 |
58 | -------------------------------------------------------------------------------- /content/300-guides/050-database/100-developing-with-prisma-migrate/deploy-db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/050-database/100-developing-with-prisma-migrate/deploy-db.png -------------------------------------------------------------------------------- /content/300-guides/050-database/100-developing-with-prisma-migrate/existing-database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/050-database/100-developing-with-prisma-migrate/existing-database.png -------------------------------------------------------------------------------- /content/300-guides/050-database/100-developing-with-prisma-migrate/migrate-team-dev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/050-database/100-developing-with-prisma-migrate/migrate-team-dev.png -------------------------------------------------------------------------------- /content/300-guides/050-database/100-developing-with-prisma-migrate/migration-history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/050-database/100-developing-with-prisma-migrate/migration-history.png -------------------------------------------------------------------------------- /content/300-guides/050-database/100-developing-with-prisma-migrate/new-dev-db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/050-database/100-developing-with-prisma-migrate/new-dev-db.png -------------------------------------------------------------------------------- /content/300-guides/050-database/900-advanced-database-tasks/06-cascading-deletes/cascading-deletes/cascading-deletes-illustration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/050-database/900-advanced-database-tasks/06-cascading-deletes/cascading-deletes/cascading-deletes-illustration.png -------------------------------------------------------------------------------- /content/300-guides/050-database/900-advanced-database-tasks/06-cascading-deletes/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Cascading deletes' 3 | metaTitle: 'Cascading deletes (Guide)' 4 | metaDescription: 'How to implement cascading deletes at database level.' 5 | --- 6 | 7 | 8 | 9 | Cascading deletes allow you to define how foreign key relationships should be handled when you delete a record. For example, when you delete a user, you might use a cascading delete to remove that user's extended profile from a related table. By contrast, you might _not_ want to delete that user's blog posts. 10 | 11 | The guides in this section describe how to implement cascading deletes manually in the database and verify the results in Prisma Client. 12 | 13 | 14 | 15 | In [2.26.0](https://github.com/prisma/prisma/releases/tag/2.26.0) and later it is possible to do cascading deletes using the **preview feature** [referential actions](../../../../concepts/components/prisma-schema/relations/referential-actions). 16 | 17 | 18 | 19 | ![](cascading-deletes/cascading-deletes-illustration.png) 20 | 21 | 22 | -------------------------------------------------------------------------------- /content/300-guides/050-database/900-advanced-database-tasks/07-data-validation/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Advanced data validation' 3 | metaTitle: 'Advanced data validation (Guides)' 4 | metaDescription: "Learn how to use the database's mechanism for validating input using CHECK constraints in this practical guide." 5 | toc: false 6 | --- 7 | 8 | 9 | 10 | All databases include a mechanism for validating input. In a SQL context, `CHECK` constraints allow you to specify a set of conditions a value must satisfy - for example, Column X should not be larger than Column Y. This section describes how to configure custom `CHECK` constraints. 11 | 12 | You can already define the following constraints in the Prisma schema: 13 | 14 | - [Field must be unique](../../../../concepts/components/prisma-schema/data-model#defining-a-unique-field) (`UNIQUE` constraint) 15 | - [Field is mandatory](../../../../concepts/components/prisma-schema/data-model#optional-and-mandatory-fields) (`NOT NULL` constraint) 16 | 17 | 18 | 19 | ## In this section 20 | 21 | 22 | -------------------------------------------------------------------------------- /content/300-guides/050-database/900-advanced-database-tasks/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Advanced database tasks 3 | metaTitle: Advanced database tasks (Guides) 4 | metaDescription: How to perform database tasks that are partially supported or not supported natively by Prisma. 5 | --- 6 | 7 | 8 | 9 | This section describes how to implement functionality that is partially supported or not supported natively by Prisma, and how to validate the changes. 10 | 11 | 12 | 13 | ## In this section 14 | 15 | 16 | -------------------------------------------------------------------------------- /content/300-guides/050-database/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Database guides 3 | navTitle: Database 4 | metaTitle: Database (Guides) 5 | metaDescription: Developing your database with Prisma, including migrations, seeding, prototyping, and troubleshooting production issues. 6 | staticLink: true 7 | --- 8 | 9 | 10 | 11 | 12 | 13 | ## In this section 14 | 15 | 16 | -------------------------------------------------------------------------------- /content/300-guides/100-performance-and-optimization/150-connection-management/200-configure-pg-bouncer.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Configure Prisma Client with PgBouncer 3 | --- 4 | 5 | 6 | 7 | PgBouncer holds a connection pool to the database and proxies incoming client connections by sitting between Prisma Client and the database. This reduces the number of processes a database has to handle at any given time. PgBouncer passes on a limited number of connections to the database and queues additional connections for delivery when space becomes available. 8 | 9 | 10 | 11 | ## Add pgbouncer to the connection URL 12 | 13 | To use Prisma Client with PgBouncer from a serverless function, add the `?pgbouncer=true` flag to the PostgreSQL connection URL: 14 | 15 | ``` 16 | postgresql://USER:PASSWORD@HOST:PORT/DATABASE?pgbouncer=true 17 | ``` 18 | 19 | ## Set PgBouncer to transaction mode 20 | 21 | Additionally, for Prisma Client to work reliably, PgBouncer must run in [**Transaction mode**](https://www.pgbouncer.org/features.html). 22 | 23 | _Transaction mode_ offers a connection for every transaction – a requirement for the Prisma query engine to work with PgBouncer. 24 | 25 |
26 | How `pgbouncer` mode works in Prisma 27 | 28 | - Prisma cleans up already present prepared statements in the connection by running `DEALLOCATE ALL` before preparing and executing Prisma Client queries. 29 | - Prisma opens a transaction for every query case – even when just reading data, allowing Prisma to use prepared statements. 30 | 31 |
32 | 33 | ## Prisma Migrate and PgBouncer workaround 34 | 35 | Prisma Migrate uses **database transactions** to check out the current state of the database and the migrations table. However, the Migration Engine is designed to use a **single connection to the database**, and does not support connection pooling with PgBouncer. If you attempt to run Prisma Migrate commands in any environment that uses PgBouncer for connection pooling, you might see the following error: 36 | 37 | ```bash 38 | Error: undefined: Database error 39 | Error querying the database: db error: ERROR: prepared statement "s0" already exists 40 | ``` 41 | 42 | To work around this issue, you must connect directly to the database rather than going through PgBouncer. How to achieve this depends on your setup or provider: 43 | 44 | - [Connecting directly to a PostgreSQL database hosted on Digital Ocean](https://github.com/prisma/prisma/issues/6157) 45 | - [Connecting directly to a PostgreSQL database hosted on ScaleGrid](https://github.com/prisma/prisma/issues/6701#issuecomment-824387959) 46 | -------------------------------------------------------------------------------- /content/300-guides/100-performance-and-optimization/150-connection-management/serverless-connections-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/100-performance-and-optimization/150-connection-management/serverless-connections-2.png -------------------------------------------------------------------------------- /content/300-guides/100-performance-and-optimization/150-connection-management/serverless-connections.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/100-performance-and-optimization/150-connection-management/serverless-connections.png -------------------------------------------------------------------------------- /content/300-guides/100-performance-and-optimization/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Performance and optimization 3 | staticLink: true 4 | metaDescription: 'How to integrate the Prisma toolset into your stack. Guides on performance, query optimization, and transactions' 5 | --- 6 | 7 | 8 | 9 | How to integrate the Prisma toolset into your stack. 10 | 11 | 12 | 13 | ## In this section 14 | 15 | 16 | -------------------------------------------------------------------------------- /content/300-guides/150-testing/Docker_Diagram_V1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/150-testing/Docker_Diagram_V1.png -------------------------------------------------------------------------------- /content/300-guides/150-testing/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Testing' 3 | navTitle: Testing 4 | metaTitle: 'Testing with Prisma' 5 | metaDescription: 'How to implement unit and integration testing with Prisma' 6 | staticLink: true 7 | --- 8 | 9 | 10 | 11 | This section describes how to approach testing an application that uses Prisma Client. 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /content/300-guides/200-deployment/100-deployment.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Deployment overview' 3 | metaTitle: 'Deploying projects using Prisma to the cloud' 4 | metaDescription: 'Learn more about the different deployment paradigms for Node.js and TypeScript applications and how they affect deploying an application using Prisma Client.' 5 | tocDepth: 2 6 | --- 7 | 8 | 9 | 10 | Projects using Prisma Client can be deployed to many different cloud platforms. Given the variety of cloud platforms and different names, it's noteworthy to mention the different deployment paradigms, as they affect the way you deploy an application using Prisma Client. 11 | 12 | 13 | 14 | ## Deployment paradigms 15 | 16 | Each paradigm has different tradeoffs that affect the performance, scalability, and operational costs of your application. 17 | 18 | Moreover, the user traffic pattern of your application is also an important factor to consider. For example, any application with consistent user traffic may be better suited for a [continuously running paradigm](#long-running-process-paas), whereas an application with sudden spikes may be better suited to [serverless](#serverless-faas). 19 | 20 | ### Long-running process (PaaS) 21 | 22 | Your Node.js process is continuously running and handles multiple requests. Your application can be deployed to a Platform-as-a-Service like [Heroku](./deployment-guides/deploying-to-heroku), as a Docker container to Kubernetes, or as a Node.js process on a virtual machine. 23 | 24 | See also: [Connection management in long-running processes](../performance-and-optimization/connection-management#long-running-processes) 25 | 26 | ### Serverless (FaaS) 27 | 28 | Node.js processes of your application (or subsets of it broken into functions) are started as requests come in. 29 | 30 | Serverless environments have the concept of warm starts, which means that for subsequent invocations of the same function, it may use an already existing container that has the allocated processes, memory, file system (`/tmp` is writable on AWS Lambda), and even DB connection still available. 31 | 32 | Typically, any piece of code [outside the handler](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-features.html#gettingstarted-features-programmingmodel) remains initialized. 33 | 34 | See also: [Connection management in serverless environments](../performance-and-optimization/connection-management#serverless-environments-faas) 35 | -------------------------------------------------------------------------------- /content/300-guides/200-deployment/110-deployment-guides/600-deploying-migrations-from-a-local-environment.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Deploying migrations from a local environment' 3 | metaTitle: 'Deploying migrations from a local environment' 4 | metaDescription: 'Learn how to deploy Node.js and TypeScript applications that are using Prisma Client locally.' 5 | tocDepth: 2 6 | --- 7 | 8 | 9 | 10 | There are two scenarios where you might consider deploying migrations directly from a local environment to a production environment. 11 | 12 | - You have a local CI/CD pipeline 13 | - You are [baselining](../../database/developing-with-prisma-migrate/add-prisma-migrate-to-a-project#baseline-your-production-environment) a production environment 14 | 15 | This page outlines some examples of how you can do that and **why we would generally not recommend it**. 16 | 17 | 18 | 19 | ## Local CI/CD pipeline 20 | 21 | If you do not have an automated CI/CD process, you can technically deploy new migrations from your local environment to production in the following ways: 22 | 23 | 1. Make sure your migration history is up to date. You can do this through running `prisma migrate dev`, which will generate a migration history from the latest changes made. 24 | 2. Swap your local connection URL for your production connection URL 25 | 26 | ```bash file=.env highlight=1;delete|3;add 27 | DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/my_local_database" 28 | 29 | DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/my_production_database" 30 | ``` 31 | 32 | 3. Run `prisma migrate deploy` 33 | 34 |
35 | ⛔{' '} 36 | 37 | We strongly discourage this solution due to the following reasons 38 | 39 |
40 | 41 | - You risk exposing your production database connection URL to version control. 42 | - You may accidentally use your production connection URL instead and in turn **override or delete your production database**. 43 | 44 |
45 | ✅ We recommend setting up an automated CI/CD pipeline 46 |
47 | 48 | The pipeline should handle deployment to staging and production environments, and use `migrate deploy` in a pipeline step. See the [deployment guides](./) for examples. 49 | 50 | ## Baselining a production database 51 | 52 | When you add Prisma Migrate to an **existing database**, you must [baseline](../../database/developing-with-prisma-migrate/add-prisma-migrate-to-a-project#baseline-your-production-environment) the production database. Baselining is performed **once**, and can be done from a local instance. 53 | 54 | ![](../../../doc-images/baseline-production-from-local.png) 55 | -------------------------------------------------------------------------------- /content/300-guides/200-deployment/110-deployment-guides/700-deploying-to-a-different-os.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Deploying to a different OS' 3 | metaTitle: 'Deploying to a different OS' 4 | metaDescription: 'Learn how to deploy Node.js and TypeScript applications that are using Prisma Client to a different operating system.' 5 | --- 6 | 7 | 8 | 9 | 10 | 11 | Prisma Client depends on the [query engine](../../../concepts/components/prisma-engines/query-engine) that is running as a binary on the same host as your application. 12 | 13 | The query engine is implemented in Rust and is used by Prisma in the form of executable binary files. The binary is downloaded when `prisma generate` is called. 14 | 15 | If you have developed your application on a Windows machine for example, and wish to upload to AWS Lambda, which is a Linux environment, you may encounter issues and be presented with some warnings in your terminal. 16 | 17 | To solve this, if you know ahead of time that you will be deploying to a different environment, you can use the [binary targets](/concepts/components/prisma-schema/generators#the-native-binary-target) and specify which of the [supported operating systems](/reference/api-reference/prisma-schema-reference#binarytargets-options) binaries should be included. 18 | 19 | > **Note**: If your OS isn't supported you can include a [custom binary](../../../concepts/components/prisma-engines#using-custom-engine-binaries). 20 | 21 | 22 | -------------------------------------------------------------------------------- /content/300-guides/200-deployment/110-deployment-guides/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Deployment guides' 3 | metaTitle: 'Platforms Prisma supports for deployment' 4 | metaDescription: 'Learn more about the different deployment paradigms for Node.js and TypeScript applications and how they affect deploying an application using Prisma Client.' 5 | tocDepth: 2 6 | --- 7 | 8 | 9 | 10 | This page outlines the platforms and services Prisma can be deployed to. 11 | 12 | > **Note**: If you have a working example of a project using Prisma with a service not on this list, let us know! 13 | 14 | 15 | 16 | ## Serverless and PaaS Platforms 17 | 18 | The following is an evolving list of serverless and PaaS (platform as a service) platforms that Prisma can be deployed to. 19 | 20 | ### Serverless Platforms 21 | 22 | - [AWS Lambda](deploying-to-aws-lambda) 23 | - [Serverless Framework, AWS Lambda](deploying-to-aws-lambda) 24 | - [Netlify](deploying-to-netlify) 25 | - [Vercel](deploying-to-vercel) 26 | - [Azure functions](deploying-to-azure-functions) 27 | - Firebase functions 28 | - GCP functions 29 | 30 | ### Paas Platforms 31 | 32 | - CodeSandbox 33 | - [Heroku](deploying-to-heroku) 34 | - Render 35 | - Railway 36 | - Fly 37 | 38 | ### Common combinations 39 | 40 | Prisma is also used in some major frameworks such as [Redwood](https://redwoodjs.com/) and [Blitz](https://blitzjs.com/). The following is a list of common combination found in the wild. 41 | 42 | - Vercel + Next 43 | - Vercel + Redwood 44 | - Netlify + Redwood 45 | - Vercel + Blitz 46 | - Heroku + Blitz 47 | - Render + Blitz 48 | -------------------------------------------------------------------------------- /content/300-guides/200-deployment/150-deploy-database-changes-with-prisma-migrate.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Deploying database changes with Prisma Migrate' 3 | navTitle: 'Deploying database changes' 4 | metaDescription: 'Learn how to deploy database changes with Prisma Migrate.' 5 | --- 6 | 7 | 8 | 9 | 10 | 11 | **MongoDB not supported**
12 | Prisma Migrate does not currently support the [MongoDB connector](../../concepts/database-connectors/mongodb). 13 | 14 |
15 | 16 | To apply pending migrations to development, staging, or testing environments, run the `migrate deploy` command as part of your CI/CD pipeline: 17 | 18 | ```terminal 19 | npx prisma migrate deploy 20 | ``` 21 | 22 | Exactly when to run `prisma migrate deploy` depends on your platform. For example, a simplified [Heroku](./deployment-guides/deploying-to-heroku) workflow includes: 23 | 24 | 1. Ensuring the `./prisma/migration` folder is in source control 25 | 2. Running `prisma migrate deploy` during the [release phase](https://devcenter.heroku.com/articles/release-phase) 26 | 27 | Ideally, `migrate deploy` should be part of an automated CI/CD pipeline, and we do not generally recommend [running this command locally to deploy changes to a production database](./deployment-guides/deploying-migrations-from-a-local-environment) (for example, by temporarily changing the `DATABASE_URL` environment variable). It is not generally considered good practice to store the production database URL locally. 28 | 29 | Beware that in order to run the `prisma migrate deploy` command, you need access to the `prisma` dependency that is typically added to the `devDependencies`. Some platforms like Vercel, prune development dependencies during the build, thereby preventing you from calling the command. This can be worked around by making the `prisma` a production dependency, by moving it to `dependencies` in your `package.json`. 30 | For more information about the `migrate deploy` command, see: 31 | 32 | - [`migrate deploy` reference](../../../reference/api-reference/command-reference#migrate-deploy) 33 | - [How `migrate deploy` works](../../../concepts/components/prisma-migrate#production-and-testing-environments) 34 | - [Production troubleshooting](../database/production-troubleshooting) 35 | 36 |
37 | -------------------------------------------------------------------------------- /content/300-guides/200-deployment/images/heroku-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/200-deployment/images/heroku-architecture.png -------------------------------------------------------------------------------- /content/300-guides/200-deployment/images/heroku-deployed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/200-deployment/images/heroku-deployed.png -------------------------------------------------------------------------------- /content/300-guides/200-deployment/images/netlify-admin-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/200-deployment/images/netlify-admin-ui.png -------------------------------------------------------------------------------- /content/300-guides/200-deployment/images/netlify-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/200-deployment/images/netlify-architecture.png -------------------------------------------------------------------------------- /content/300-guides/200-deployment/images/netlify-deployed-seed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/200-deployment/images/netlify-deployed-seed.png -------------------------------------------------------------------------------- /content/300-guides/200-deployment/images/netlify-deployed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/200-deployment/images/netlify-deployed.png -------------------------------------------------------------------------------- /content/300-guides/200-deployment/images/netlify-environment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/200-deployment/images/netlify-environment.png -------------------------------------------------------------------------------- /content/300-guides/200-deployment/images/netlify-fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/200-deployment/images/netlify-fork.png -------------------------------------------------------------------------------- /content/300-guides/200-deployment/images/netlify-init-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/200-deployment/images/netlify-init-1.png -------------------------------------------------------------------------------- /content/300-guides/200-deployment/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Deployment' 3 | metaTitle: 'Deploy a Node.js application with Prisma' 4 | metaDescription: 'How to deploy a Node.js application that uses Prisma Client and TypeScript to various cloud platforms.' 5 | staticLink: true 6 | toc: false 7 | --- 8 | 9 | 10 | 11 | This section describes how to deploy Node.js applications that use Prisma Client and TypeScript to various platforms. 12 | 13 | 14 | 15 | ## In this section 16 | 17 | 18 | -------------------------------------------------------------------------------- /content/300-guides/300-upgrade-guides/200-upgrading-to-latest/300-codemods.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Codemod' 3 | metaTitle: 'Codemod (Guides)' 4 | metaDescription: 'Use codemods to upgrade your codebase as Prisma changes and evolves.' 5 | --- 6 | 7 | 8 | 9 | `@prisma/codemods` helps you to upgrade your codebase as Prisma evolves and changes. For more information, see: https://github.com/prisma/codemods 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/300-guides/300-upgrade-guides/200-upgrading-to-latest/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Upgrading to latest' 3 | metaTitle: 'Upgrading to latest (Guides)' 4 | metaDescription: 'Upgrading your project to the latest version of Prisma.' 5 | --- 6 | 7 | 8 | 9 | To upgrade to the latest version of Prisma: 10 | 11 | 1. Review [release notes](https://github.com/prisma/prisma/releases) on GitHub for breaking changes and new features. 12 | 1. Upgrade **both** of the following packages to the same version: 13 | 14 | - [`prisma`](https://www.npmjs.com/package/prisma) 15 | - [`@prisma/client`](https://www.npmjs.com/package/@prisma/client) 16 | 17 | 1. Upgrade your codebase where applicable. Breaking changes may require you to change your Prisma schema or the way you use Prisma Client. 18 | 19 | 20 | 21 | [codemods](codemods) help you refactor your code to account for breaking changes - for example, the 2.12.0 codemod automatically renames `findOne` to `findUnique`. 22 | 23 | 24 | 25 | 26 | 27 | ## Enabling preview features 28 | 29 | Some releases include Preview features that are not considered production-ready, and must be enabled before you can use them. For more information about enabling Preview features, refer to the following documentation: 30 | 31 | - [Enable Prisma Client preview features](../../../concepts/components/preview-features/client-preview-features) 32 | - [Enable Prisma CLI preview features](../../../concepts/components/preview-features/cli-preview-features) 33 | 34 | ## dev distribution tag 35 | 36 | The `dev` [Npm distribution tag](http://npm.github.io/publishing-pkgs-docs/updating/using-tags.html) points to the most recent development version of the package, which is published for each commit to the main branch of `prisma/prisma`. You can use the `dev` distribution tag to verify a fix or test a feature before it is officially released. 37 | 38 | To install the latest `dev` distribution tag: 39 | 40 | ```terminal 41 | npm install @prisma/client@dev prisma@dev 42 | ``` 43 | 44 | 45 | 46 | Do not use the `dev` distribution tag in production - wait until the official release that contains the features and fixes you are interested in is released. For example, fixes present `@prisma/client@2.23.0-dev.25` will eventually be released as part of `@prisma/client@2.23.0`. 47 | 48 | 49 | -------------------------------------------------------------------------------- /content/300-guides/300-upgrade-guides/800-upgrade-from-prisma-1/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Upgrade from Prisma 1' 3 | metaTitle: 'Upgrade from Prisma 1 to Prisma 2' 4 | staticLink: false 5 | toc: false 6 | --- 7 | 8 | ## In this section 9 | 10 | 11 | -------------------------------------------------------------------------------- /content/300-guides/300-upgrade-guides/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Upgrading' 3 | metaTitle: 'Upgrading (Guides)' 4 | metaDescription: 'How to upgrade from Prisma 1 to Prisma 2.' 5 | staticLink: true 6 | toc: false 7 | --- 8 | 9 | ## In this section 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/300-guides/400-migrate-to-prisma/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Migrate to Prisma' 3 | metaTitle: 'Migrate to Prisma (Guides)' 4 | metaDescription: 'How to migrate to Prisma from other ORMs' 5 | staticLink: true 6 | toc: false 7 | --- 8 | 9 | ## In this section 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/300-guides/600-general-guides/100-database-workflows/04-unique-constraints-and-indexes/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Unique constraints' 3 | metaTitle: 'Add unique constraints & indexes to your database schema' 4 | toc: false 5 | --- 6 | 7 | ## Overview 8 | 9 | A unique constraint is a rule that ensures that all values in a column are different. For example, it is likely that you want user IDs and email addresses to be unique within a table. 10 | 11 | This section describes how to configure unique constraints for different databases, and the effect of these constraints on the Prisma schema and generated client. 12 | 13 | ![](unique-constraints-and-indexes/unique-constraint-illustration.png) 14 | 15 | ## In this section 16 | 17 | 18 | -------------------------------------------------------------------------------- /content/300-guides/600-general-guides/100-database-workflows/04-unique-constraints-and-indexes/unique-constraints-and-indexes/unique-constraint-illustration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/600-general-guides/100-database-workflows/04-unique-constraints-and-indexes/unique-constraints-and-indexes/unique-constraint-illustration.png -------------------------------------------------------------------------------- /content/300-guides/600-general-guides/100-database-workflows/05-foreign-keys/foreign-keys/foreign-keys-illustration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/300-guides/600-general-guides/100-database-workflows/05-foreign-keys/foreign-keys/foreign-keys-illustration.png -------------------------------------------------------------------------------- /content/300-guides/600-general-guides/100-database-workflows/05-foreign-keys/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Foreign keys' 3 | metaTitle: '' 4 | toc: false 5 | --- 6 | 7 | ## Overview 8 | 9 | A foreign key links data in one table to data in another table. For example, records in a `Posts` table might have a foreign key named `authorId` that refers to the `id` column of the `User` table. This relationship makes it possible to, for example, find all blog posts by a particular author. 10 | 11 | The Prisma schema represents tables as models, and connections between two models are called [relations](../../../../../../concepts/components/prisma-schema/relations). You can [filter and query by relations](../../../../concepts/components/prisma-client/relation-queries) - for example, you can get all posts where the author's email address contains _"prisma.io"_. 12 | 13 | This section describes how to configure foreign key relationships for different databases. When you introspect a database, these relationships are represented in the Prisma schema as **relations**. 14 | 15 | ![](foreign-keys/foreign-keys-illustration.png) 16 | 17 | ## In this section 18 | 19 | 20 | -------------------------------------------------------------------------------- /content/300-guides/600-general-guides/100-database-workflows/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Database workflows' 3 | metaTitle: 'Database workflows (Guides)' 4 | metaDescription: 'How to perform common database workflows such as configuring constraints and cascading deletes.' 5 | staticLink: false 6 | toc: false 7 | --- 8 | 9 | 10 | 11 | This section includes end-to-end guides for common database workflow such as configuring constraints or cascading deletes. 12 | 13 | ![](../../../doc-images/database-setup-illustration.png) 14 | 15 | 16 | 17 | ## In this section 18 | 19 | 20 | -------------------------------------------------------------------------------- /content/300-guides/600-general-guides/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'General guides' 3 | metaTitle: 'General Guides' 4 | metaDescription: 'General technology guides by Prisma. ' 5 | toc: false 6 | staticLink: true 7 | --- 8 | 9 | 10 | 11 | This section includes general technology guides that are not specific to Prisma. 12 | 13 | 14 | 15 | ## Prisma Data Guide 16 | 17 | Visit the [Prisma Data Guide](https://www.prisma.io/dataguide/) to learn how databases work, how to choose the right one, and how to use databases with your applications to their full potential. 18 | 19 | ## In this section 20 | 21 | 22 | -------------------------------------------------------------------------------- /content/300-guides/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Guides' 3 | metaTitle: 'Guides' 4 | metaDescription: 'Guides' 5 | toc: false 6 | --- 7 | 8 | 9 | 10 | This section includes end-to-end guides for upgrading and deploying Node.js applications that use Prisma, as well as guides for common database-related tasks. 11 | 12 | 13 | 14 | ## In this section 15 | 16 | 17 | -------------------------------------------------------------------------------- /content/400-reference/200-api-reference/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'API reference' 3 | metaTitle: 'API Reference' 4 | metaDescription: 'API Reference' 5 | toc: false 6 | staticLink: true 7 | --- 8 | 9 | ## In this section 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/400-reference/300-database-reference/03-supported-databases.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Supported databases' 3 | metaTitle: 'Databases supported by Prisma' 4 | metaDescription: 'This page lists all the databases and their versions that are supported by Prisma.' 5 | --- 6 | 7 | 8 | 9 | Prisma currently supports the following databases: 10 | 11 | | Database | Version | 12 | | ---------------------------- | ------- | 13 | | PostgreSQL | 9 | 14 | | PostgreSQL | 10 | 15 | | PostgreSQL | 11 | 16 | | PostgreSQL | 12 | 17 | | PostgreSQL | 13 | 18 | | MySQL | 5.6 | 19 | | MySQL | 5.7 | 20 | | MySQL | 8 | 21 | | MariaDB | 10 | 22 | | SQLite | \* | 23 | | AWS Aurora | \* | 24 | | AWS Aurora Serverless ¹ | \* | 25 | 26 | Note that a fixed version of SQLite is shipped with every Prisma release. 27 | 28 | ¹ This does not include support for [Data API for Aurora Serverless](https://github.com/prisma/prisma/issues/1964). 29 | 30 | 31 | 32 | ## Preview 33 | 34 | Support for the following databases is available as a Preview: 35 | 36 | | Database | Version | 37 | | -------------------- | ------- | 38 | | Microsoft SQL Server | 2019 | 39 | | Microsoft SQL Server | 2017 | 40 | | Azure SQL | \* | 41 | | MongoDB | 4.2+ | 42 | -------------------------------------------------------------------------------- /content/400-reference/300-database-reference/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Database reference' 3 | metaTitle: 'Database Reference' 4 | metaDescription: 'Database Reference' 5 | toc: false 6 | staticLink: true 7 | --- 8 | 9 | ## In this section 10 | 11 | 12 | -------------------------------------------------------------------------------- /content/400-reference/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Reference' 3 | metaTitle: 'Reference' 4 | metaDescription: 'Reference' 5 | toc: false 6 | --- 7 | 8 | ## In this section 9 | 10 | 11 | -------------------------------------------------------------------------------- /content/500-support/100-help-articles/300-finding-entities-based-on-relation.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Querying models based on their relations existence' 3 | metaTitle: 'Querying models based on their relations existence' 4 | metaDescription: 'Learn how you can query for entities where their relation exists or not' 5 | --- 6 | 7 | ## Problem 8 | 9 | Common use cases when querying for relations from a database are: 10 | 11 | - finding all the entities for table X where the relation Y doesn't exist 12 | - finding all the entities for table X where the relation Y has at least one item 13 | 14 | Taking a concrete example of users and posts as entities, this would translate to _"find the users that haven't created any posts"_ and _"find the users that have created at least one post"_. 15 | 16 | Read below to learn how this can be achieved with Prisma. 17 | 18 | ## Solution 19 | 20 | Consider this Prisma schema: 21 | 22 | ```prisma 23 | model User { 24 | id Int @id @default(autoincrement()) 25 | name String 26 | posts Post[] 27 | } 28 | 29 | model Post { 30 | id Int @id @default(autoincrement()) 31 | user User? @relation(fields: [userId], references: [id]) 32 | userId Int? 33 | } 34 | ``` 35 | 36 | You can now query for the **users that do not have any posts** as follows: 37 | 38 | ```js 39 | await prisma.user.findMany({ 40 | where: { posts: { none: {} } }, 41 | }) 42 | ``` 43 | 44 | This query returns all the users that haven't created any posts yet. 45 | 46 | In a similar way, you can query for **users that created at least one post** as follows: 47 | 48 | ```js 49 | await prisma.user.findMany({ 50 | where: { posts: { some: {} } }, 51 | }) 52 | ``` 53 | 54 | This query returns all the users that created at least one post. 55 | 56 | This article showed how you can query for entities based on if the relation exists. 57 | -------------------------------------------------------------------------------- /content/500-support/100-help-articles/400-nextjs-prisma-client-dev-practices.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Best practice for instantiating PrismaClient with Next.js' 3 | metaTitle: 'Best practice for instantiating PrismaClient with Next.js' 4 | metaDescription: 'Best practice for instantiating PrismaClient with Next.js' 5 | --- 6 | 7 | ## Problem 8 | 9 | Lots of users have come across this warning while working with [Next.js](https://nextjs.org/) in development: 10 | 11 | ``` 12 | warn(prisma-client) Already 10 Prisma Clients are actively running 13 | ``` 14 | 15 | There's a related [discussion](https://github.com/prisma/prisma/discussions/4399) and [issue](https://github.com/prisma/prisma/issues/5103) for the same. 16 | 17 | In development, the command `next dev` clears Node.js cache on run. This in turn initializes a new `PrismaClient` instance each time due to hot reloading that creates a connection to the database. This can quickly exhaust the database connections as each `PrismaClient` instance holds its own connection pool. 18 | 19 | ## Solution 20 | 21 | The solution in this case is to instantiate a single instance `PrismaClient` and save it on the [`global`](https://nodejs.org/api/globals.html#globals_global) object. Then we keep a check to only instantiate `PrismaClient` if it's not on the `global` object otherwise use the same instance again if already present to prevent instantiating extra `PrismaClient` instances. 22 | 23 | ```ts file=./db 24 | import { PrismaClient } from '@prisma/client' 25 | 26 | // Prevent multiple instances of Prisma Client in development 27 | declare const global: NodeJS.Global & { prisma?: PrismaClient } 28 | 29 | const prisma = global.prisma || new PrismaClient() 30 | if (process.env.NODE_ENV === 'development') global.prisma = prisma 31 | 32 | export default prisma 33 | ``` 34 | 35 | After creating this file, you can now import this `PrismaClient` instance anywhere in your Next.js `pages` as follows: 36 | 37 | ```ts 38 | // e.g. in `pages/index.tsx` 39 | import prisma from './db' 40 | 41 | export const getServerSideProps = async ({ req }) => { 42 | const token = req.headers.AUTHORIZATION 43 | const userId = await getUserId(token) 44 | const posts = await prisma.post.findMany({ 45 | where: { 46 | author: { id: userId }, 47 | }, 48 | }) 49 | return { props: { posts } } 50 | } 51 | ``` 52 | -------------------------------------------------------------------------------- /content/500-support/100-help-articles/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Help articles' 3 | metaTitle: 'Help articles (Support)' 4 | metaDescription: 'Common problems and how to solve them.' 5 | hidePage: false 6 | staticLink: true 7 | --- 8 | 9 | 10 | 11 | This section provides a number of common problems developers might be running into when using Prisma and provides short, practical solutions to resolve them. 12 | 13 | 14 | 15 | ## Help articles 16 | 17 | 18 | -------------------------------------------------------------------------------- /content/500-support/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Support' 3 | metaTitle: 'Support' 4 | metaDescription: 'Find out how to get help or raise an issue, ' 5 | hidePage: false 6 | --- 7 | 8 | ## Need help? 9 | 10 | Prisma has a large and supportive [community](https://prisma.io/community) of enthusiastic application developers which is most active on [Slack](https://slack.prisma.io) and on [GitHub](https://github.com/prisma/prisma). 11 | 12 | ## Ask a question about Prisma 13 | 14 | You can ask questions and initiate [discussions](https://github.com/prisma/prisma/discussions/) about Prisma-related topics in the `prisma` repository on GitHub. 15 | 16 | 21 | Ask a question 22 | 23 |
24 |
25 | 26 | ## Create a bug report for Prisma 27 | 28 | If you see an error message or run into an issue, please make sure to create a bug report! You can find [best practices for creating bug reports](creating-bug-reports) (like including additional debugging output) in these docs. 29 | 30 | 35 | Create bug report 36 | 37 |
38 |
39 | 40 | ## Submit a feature request 41 | 42 | If Prisma currently doesn't have a certain feature, be sure to check out the [roadmap](../about/roadmap) to see if this is already planned for the future. 43 | 44 | If the feature on the roadmap is linked to a GitHub issue, please make sure to leave a +1 on the issue and ideally a comment with your thoughts about the feature! 45 | 46 | 51 | Submit feature request 52 | 53 | -------------------------------------------------------------------------------- /content/600-about/01-about-the-docs.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'About the docs' 3 | metaTitle: 'About the Prisma documentation' 4 | metaDescription: 'This page gives a meta-overview about different topics that are relevant to better understand and navigate the Prisma documentation.' 5 | --- 6 | 7 | 8 | 9 | `User` and `Post` are the canonical models that are being used throughout the Prisma docs. This page gives some context on why these have been selected and how to interpret them. 10 | 11 | 12 | 13 | ## The `User` and `Post` data model 14 | 15 | The `User` and `Post` models have been selected for the following reasons: 16 | 17 | - These two models do not require domain-specific knowledge. 18 | - They are also commonly used as an example in the ORM space, making them familiar for users coming from other tools. 19 | - Having consistent models makes it easier for the reader when learning about different concepts, since there will be less context switching. 20 | - Less decision making and cognitive overhead for the docs authors. Using the same models reduces decision fatigue and is one less thing to worry about when trying to explain concepts. 21 | 22 | We are actively working on [adding more schema examples](https://github.com/prisma/docs/issues/1626) to the docs to provide you with starting points for common data models, such as e-commerce. 23 | 24 | ## Naming conventions for tables and columns 25 | 26 | Table names are generally spelled in [PascalCase](). Column names in [camelCase](). 27 | 28 | ## Embrace redundancy 29 | 30 | Meet the user where they are. 31 | -------------------------------------------------------------------------------- /content/600-about/02-style-guide/02-template.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Writing template' 3 | metaTitle: 'Writing template (About)' 4 | metaDescription: 'A template for writing Prisma Docs.' 5 | tocDepth: 2 6 | hidePage: false 7 | toc: true 8 | --- 9 | 10 | 11 | 12 | A short introduction that encourages visitors to read on. The `TopBlock` component is required for styling purposes. 13 | 14 | 15 | 16 | ## A section 17 | 18 | Break your page up into sections. Use the `tocDepth` frontmatter variable to determine how many levels the table of contents should have - 1 or 2. 19 | 20 | ### A subsection 21 | 22 | If possible, avoid too many deeply nested subsections. 23 | -------------------------------------------------------------------------------- /content/600-about/02-style-guide/03-frontmatter.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Frontmatter 3 | metaDescription: 'Supported frontmatter variables.' 4 | --- 5 | 6 | 7 | 8 | ## title 9 | 10 | The `

` title of the page. 11 | 12 | ## metaTitle 13 | 14 | The `` of the page - falls back to `title` (`h1`) 15 | 16 | ## <inlinecode>navTitle</inlinecode> 17 | 18 | Allows you to specify a different, usually shorter title for the left-hand navigation. 19 | 20 | ## <inlinecode>metaDescription</inlinecode> 21 | 22 | The `<meta name="description" content="" />` of the page. 23 | 24 | ## <inlinecode>staticLink</inlinecode> 25 | 26 | Turns the page into a non-linked heading in the left-hand navigation. For example: https://www.prisma.io/docs/concepts/overview 27 | 28 | > **Note**: The page still exists, but you can only navigate to it via the breadcrumb. 29 | 30 | ## <inlinecode>preview</inlinecode> 31 | 32 | Adds a `preview` label to a page in the left-hand navigation. 33 | 34 | ## <inlinecode>toc</inlinecode> 35 | 36 | Enable or disable table of contents navigation on the page (defaults to `false`). For example: 37 | 38 | ``` 39 | toc: true 40 | ``` 41 | 42 | ## <inlinecode>tocDepth</inlinecode> 43 | 44 | Controls the depth of headings to show in the ToC: 45 | 46 | ``` 47 | tocDepth: 2 48 | ``` 49 | 50 | > **Note**: Currently limited to 2 levels - `h2` and `h3` 51 | 52 | ## <inlinecode>hidePage</inlinecode> 53 | 54 | Hides page from all navigation (still visible through search). For example: 55 | 56 | ``` 57 | hidePage: true 58 | ``` 59 | 60 | <!-- 61 | 62 | langSwitcher?: string[] 63 | dbSwitcher?: string[] 64 | staticLink?: boolean 65 | duration?: string 66 | 67 | hidePage?: boolean 68 | tocDepth?: number 69 | codeStyle?: boolean --> 70 | -------------------------------------------------------------------------------- /content/600-about/06-limitations.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Limitations' 3 | metaTitle: 'Limitations' 4 | metaDescription: 'This page lists a number of current limitations of Prisma.' 5 | --- 6 | 7 | ## Overview 8 | 9 | This page describes features that are currently not supported by Prisma and are not planned to be supported. 10 | 11 | ## Long-running transactions 12 | 13 | Databases often offer "long-running transactions" as a feature. A transaction generally refers to a sequence of read/write operations that are guaranteed to either succeed or fail as a whole. 14 | 15 | Prisma offers a limited set of transactions in the form of [nested writes](../concepts/components/prisma-client/relation-queries#nested-writes). There currently is no plan to provide an API to allow a transaction API for long-running transactions. 16 | 17 | ✍ Read more about [**How Prisma supports transactions**](https://www.prisma.io/blog/how-prisma-supports-transactions-x45s1d5l0ww1/) on our blog. 18 | 19 | ## Records must be uniquely identifiable 20 | 21 | Prisma currently only supports models that have at least one unique field or combination of fields. In practice, this means that every Prisma model must have either at least one of the following attributes: 22 | 23 | - `@id` or `@@id` for a single- or multi-field primary key constraint (max one per model) 24 | - `@unique` or `@@unique` for a single- or multi-field unique constraint 25 | 26 | ## Manual database connection handling 27 | 28 | When using Prisma, the database connections are handled on an [engine](https://github.com/prisma/prisma-engines)-level. This means they're not exposed to the developer and it's not possible to manually access them. 29 | 30 | ## Prisma Migrate limitations 31 | 32 | See: [Prisma Migrate limitations and known issues](../concepts/components/prisma-migrate/prisma-migrate-limitations-issues) 33 | -------------------------------------------------------------------------------- /content/600-about/07-roadmap.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Roadmap' 3 | metaTitle: 'Prisma Roadmap – See what we are working on next' 4 | metaDescription: 'Want to know what we are up to? Our roadmap provides an overview of our priorities and where we are planning to take Prisma next.' 5 | --- 6 | 7 | <TopBlock> 8 | 9 | Our roadmap helps us share our current priorities: what we are currently working on and what we are planning to work on in the near term. This reflects our _current plans_ today, and the content is subject to change at any time. Actual results and plans may differ as a result of changing our product strategy or reacting to demands from our user base. 10 | 11 | You can [check out the full roadmap here](https://pris.ly/roadmap). 12 | 13 | </TopBlock> 14 | -------------------------------------------------------------------------------- /content/600-about/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'About' 3 | metaTitle: 'About' 4 | metaDescription: 'About' 5 | toc: false 6 | hidePage: false 7 | --- 8 | 9 | ## In this section 10 | 11 | <Subsections /> 12 | -------------------------------------------------------------------------------- /content/doc-images/baseline-production-from-local.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/doc-images/baseline-production-from-local.png -------------------------------------------------------------------------------- /content/doc-images/connect-sql-server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/doc-images/connect-sql-server.png -------------------------------------------------------------------------------- /content/doc-images/cursor-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/doc-images/cursor-1.png -------------------------------------------------------------------------------- /content/doc-images/cursor-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/doc-images/cursor-2.png -------------------------------------------------------------------------------- /content/doc-images/cursor-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/doc-images/cursor-3.png -------------------------------------------------------------------------------- /content/doc-images/database-setup-illustration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/doc-images/database-setup-illustration.png -------------------------------------------------------------------------------- /content/doc-images/database-tables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/doc-images/database-tables.png -------------------------------------------------------------------------------- /content/doc-images/new-query.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/doc-images/new-query.png -------------------------------------------------------------------------------- /content/doc-images/offset-skip-take.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/doc-images/offset-skip-take.png -------------------------------------------------------------------------------- /content/doc-images/prisma-introspection-development-workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/doc-images/prisma-introspection-development-workflow.png -------------------------------------------------------------------------------- /content/doc-images/prisma-migrate-development-workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/content/doc-images/prisma-migrate-development-workflow.png -------------------------------------------------------------------------------- /functions/index.js: -------------------------------------------------------------------------------- 1 | const { PrismaClient } = require('@prisma/client') 2 | 3 | const client = new PrismaClient() 4 | 5 | exports.handler = async function (event, context, callback) { 6 | const body = JSON.parse(event.body) 7 | if (!body.pageUrl) { 8 | throw new Error(`Please provide a pageUrl`) 9 | } 10 | 11 | if (!body.sentiment) { 12 | throw new Error(`Please provide a sentiment`) 13 | } 14 | 15 | if (!['Happy', 'Unhappy'].includes(body.sentiment)) { 16 | throw new Error(`Please provide "Happy" or "Unhappy" as the sentiment`) 17 | } 18 | const pageUrl = stripTrailingSlash(body.pageUrl) 19 | 20 | await client.feedback.create({ 21 | data: { 22 | pageUrl, 23 | ip: event.headers['x-forwarded-for'], 24 | userAgent: event.headers['user-agent'], 25 | sentiment: body.sentiment, 26 | }, 27 | }) 28 | 29 | return { 30 | statusCode: 200, 31 | body: JSON.stringify({ success: true }), 32 | } 33 | } 34 | 35 | function stripTrailingSlash(url) { 36 | return url.replace(/\/$/, '') 37 | } 38 | -------------------------------------------------------------------------------- /gatsby-browser.js: -------------------------------------------------------------------------------- 1 | const { init, trackPage } = require('./src/utils/stats') 2 | const { goToNav } = require('./src/utils/goToNavItem') 3 | 4 | exports.onClientEntry = () => { 5 | init() 6 | } 7 | 8 | exports.onRouteUpdate = ({ location }) => { 9 | trackPage(location.pathname) 10 | goToNav(location.pathname) // This may not work anymore due to the new scroll behavior of the sidebar 11 | } 12 | -------------------------------------------------------------------------------- /gatsby-ssr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Implement Gatsby's SSR (Server Side Rendering) APIs in this file. 3 | * 4 | * See: https://www.gatsbyjs.org/docs/ssr-apis/ 5 | */ 6 | 7 | // You can delete this file if you're not using it 8 | -------------------------------------------------------------------------------- /images.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.png' 2 | declare module '*.jpg' 3 | declare module '*.jpeg' 4 | declare module '*.gif' 5 | -------------------------------------------------------------------------------- /jest.setup.js: -------------------------------------------------------------------------------- 1 | import 'jest-dom/extend-expect' 2 | import 'react-testing-library/cleanup-after-each' 3 | 4 | global.___loader = { 5 | enqueue: jest.fn(), 6 | } 7 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | command = "npm run build" 3 | functions = "functions/" 4 | 5 | [[plugins]] 6 | package = "netlify-plugin-gatsby-cache" 7 | 8 | [context.production.environment] 9 | INDEX_ALGOLIA = "true" 10 | 11 | [[headers]] 12 | for = "/*" 13 | [headers.values] 14 | Access-Control-Allow-Origin = "https://www.prisma.io" 15 | Strict-Transport-Security = "max-age=63072000; includeSubDomains; preload" 16 | Content-Security-Policy = "default-src data: 'unsafe-inline' 'unsafe-eval' https:; script-src data: 'unsafe-inline' 'unsafe-eval' https: blob:; style-src data: 'unsafe-inline' https:; img-src data: https: blob:; font-src data: https:; connect-src https: wss: blob:; media-src https: blob:; object-src https:; child-src https: data: blob:; form-action https:; block-all-mixed-content" 17 | X-Frame-Options = "DENY" 18 | X-Content-Type-Options = "nosniff" 19 | Referrer-Policy = "no-referrer" 20 | Feature-Policy = "microphone 'none'; geolocation 'none'" 21 | 22 | [[redirects]] 23 | from = "/docs/*" 24 | to = "/:splat" 25 | status = 200 26 | force = true 27 | -------------------------------------------------------------------------------- /plugins/gatsby-plugin-page-list/gatsby-node.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const fsPromises = require('fs').promises 3 | const url = require('url') 4 | 5 | const publicPath = `./public` 6 | 7 | // Excluded paths from page listing as they're redirected to the page with the language and db selected 8 | // https://github.com/prisma/homepage-v8/blob/b972182ebee2c824e6b2981088907b215d9bfee0/public/_redirects#L75-L78 9 | const excludedPaths = [ 10 | '/getting-started/quickstart', 11 | '/getting-started/setup-prisma/add-to-existing-project', 12 | '/getting-started/setup-prisma/start-from-scratch-sql ', 13 | '/getting-started/setup-prisma/start-from-scratch-prisma-migrate', 14 | ] 15 | 16 | exports.onPostBuild = async ({ graphql, pathPrefix, basePath = pathPrefix }, pluginOptions) => { 17 | const outputFile = path.join(publicPath, '/pages.json') 18 | 19 | const query = ` 20 | { 21 | site { 22 | siteMetadata { 23 | siteUrl 24 | pathPrefix 25 | } 26 | } 27 | allSitePage { 28 | edges { 29 | node { 30 | path 31 | context { 32 | seoTitle 33 | id 34 | } 35 | } 36 | } 37 | } 38 | }` 39 | const { data } = await graphql(query) 40 | 41 | // Construct the pages json by iterating over the mdx files. 42 | const pages = data.allSitePage.edges 43 | .map((edge, i) => { 44 | // Skip the 404 pages and pages without seoTitle 45 | if (!edge.node.context || !edge.node.context.seoTitle) return null 46 | console.log(edge.node.path) 47 | // Skip explicitly excluded paths 48 | if (excludedPaths.includes(edge.node.path)) return null 49 | 50 | return { 51 | title: edge.node.context.seoTitle, 52 | url: url.resolve( 53 | data.site.siteMetadata.siteUrl, 54 | path.join(data.site.siteMetadata.pathPrefix, edge.node.path) 55 | ), 56 | } 57 | }) 58 | .filter((edge) => edge !== null) 59 | 60 | await fsPromises.writeFile(outputFile, JSON.stringify(pages)) 61 | } 62 | -------------------------------------------------------------------------------- /plugins/gatsby-plugin-page-list/index.js: -------------------------------------------------------------------------------- 1 | // noop 2 | -------------------------------------------------------------------------------- /plugins/gatsby-plugin-page-list/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-plugin-page-list", 3 | "version": "1.0.0", 4 | "description": "Create a json file with all pages and titles", 5 | "main": "index.js", 6 | "license": "MIT" 7 | } 8 | -------------------------------------------------------------------------------- /plugins/gatsby-remark-check-links-numberless/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-remark-check-links-numberless", 3 | "version": "1.0.0", 4 | "description": "Transformed links checker", 5 | "main": "index.js", 6 | "author": "Nilufar Bava <nilubava@gmail.com>", 7 | "license": "ISC", 8 | "keywords": [ 9 | "gatsby", 10 | "gatsby-plugin" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /plugins/gatsby-remark-to-absoluteurl/index.js: -------------------------------------------------------------------------------- 1 | var visit = require('unist-util-visit') 2 | const path = require('path') 3 | 4 | function withPathPrefix(url, pathPrefix) { 5 | const prefixed = pathPrefix + url 6 | return prefixed.replace(/\/\//, '/') 7 | } 8 | 9 | const pathSep = '/' 10 | 11 | module.exports = function plugin( 12 | { markdownAST, markdownNode, pathPrefix, getNode }, 13 | { redirects = [] } = {} 14 | ) { 15 | function visitor(node) { 16 | //To convert all uppercase links to lowercase (if used by mistake) 17 | node.url = node.url.toLowerCase() 18 | 19 | node.originalUrl = node.url 20 | if ( 21 | markdownNode.fields && 22 | markdownNode.fields.slug && 23 | !node.url.startsWith('/') && 24 | !node.url.startsWith('#') && 25 | !node.url.startsWith('mailto:') && 26 | !/^https?:\/\//.test(node.url) 27 | ) { 28 | const parent = getNode(markdownNode.parent) 29 | const newUrl = path 30 | .resolve( 31 | markdownNode.fields.slug 32 | .replace(`${pathSep}index`, '') 33 | .replace(/\d{2,}-/g, '') 34 | .replace(/\/$/, '') 35 | .split(pathSep) 36 | .slice(0, parent.name === 'index' ? undefined : -1) 37 | .join(pathSep) || '/', 38 | node.url 39 | ) 40 | .replace(/\/?(\?|#|$)/, '/$1') 41 | 42 | if (/^..\\/.test(newUrl)) { 43 | //Code specifically for local run, to fix broken links on 44 | let newUrl2 = path.resolve( 45 | markdownNode.fields.slug.replace(/(\/.+)\/.*/, '$1').replace(/\/\d{2,}-/g, '/'), 46 | node.url 47 | ) 48 | 49 | newUrl2 = newUrl2 50 | .replace(/\\/g, '/') 51 | .slice(2) 52 | .replace(/(^.*)#.*/, '$1') 53 | const isRedirectPath = redirects.find((url) => newUrl2.includes(url.from)) 54 | if (isRedirectPath) newUrl2 = isRedirectPath.to 55 | 56 | let hashVal = node.url.match(/#.*/) 57 | if (hashVal) newUrl2 += hashVal[0] 58 | 59 | node.url = newUrl2.replace(/^([^#]*)$/, '$1/') 60 | } else { 61 | const isRedirectPath = redirects.find((url) => newUrl.includes(url.from)) 62 | node.url = withPathPrefix( 63 | isRedirectPath ? newUrl.replace(isRedirectPath.from, isRedirectPath.to) : newUrl, 64 | pathPrefix 65 | ) 66 | } 67 | } 68 | } 69 | 70 | visit(markdownAST, 'link', visitor) 71 | 72 | return markdownAST 73 | } 74 | -------------------------------------------------------------------------------- /plugins/gatsby-remark-to-absoluteurl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-remark-to-absoluteurl", 3 | "version": "1.0.0", 4 | "description": "Relative to absolute url", 5 | "main": "index.js", 6 | "author": "Nilufar Bava <nilubava@gmail.com>", 7 | "license": "ISC", 8 | "keywords": [ 9 | "gatsby", 10 | "gatsby-plugin" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /prisma/migrations/20201216150604_init/migration.sql: -------------------------------------------------------------------------------- 1 | -- CreateEnum 2 | CREATE TYPE "public"."Sentiment" AS ENUM ('Happy', 'Unhappy'); 3 | 4 | -- CreateTable 5 | CREATE TABLE "Feedback" ( 6 | "id" SERIAL, 7 | "pageUrl" TEXT NOT NULL, 8 | "userAgent" TEXT NOT NULL, 9 | "ip" TEXT NOT NULL, 10 | "sentiment" "Sentiment" NOT NULL, 11 | "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, 12 | 13 | PRIMARY KEY ("id") 14 | ); 15 | -------------------------------------------------------------------------------- /prisma/migrations/20201216150920_add_feedback_text/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Feedback" ADD COLUMN "feedback" TEXT, 3 | ALTER COLUMN "userAgent" DROP NOT NULL, 4 | ALTER COLUMN "ip" DROP NOT NULL; 5 | -------------------------------------------------------------------------------- /prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | datasource db { 2 | provider = "postgresql" 3 | url = env("POSTGRES_URL") 4 | } 5 | 6 | generator client { 7 | provider = "prisma-client-js" 8 | binaryTargets = ["native", "rhel-openssl-1.0.x"] 9 | } 10 | 11 | model Feedback { 12 | id Int @id @default(autoincrement()) 13 | pageUrl String 14 | userAgent String? 15 | ip String? 16 | sentiment Sentiment 17 | feedback String? 18 | createdAt DateTime @default(now()) 19 | } 20 | 21 | enum Sentiment { 22 | Happy 23 | Unhappy 24 | } 25 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["config:base"], 4 | "schedule": ["before 8am on the first day of the month"], 5 | "ignoreDeps": ["gatsby-plugin-algolia"], 6 | "dependencyDashboard": true, 7 | "packageRules": [ 8 | { 9 | "groupName": "@prisma/lens", 10 | "schedule": ["at any time"], 11 | "automerge": true, 12 | "packageNames": ["@prisma/lens"] 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE "public"."User" ( 2 | id SERIAL PRIMARY KEY NOT NULL, 3 | name VARCHAR(255), 4 | email VARCHAR(255) UNIQUE NOT NULL 5 | ); 6 | 7 | CREATE TABLE "public"."Post" ( 8 | id SERIAL PRIMARY KEY NOT NULL, 9 | title VARCHAR(255) NOT NULL, 10 | "createdAt" TIMESTAMP NOT NULL DEFAULT now(), 11 | content TEXT, 12 | published BOOLEAN NOT NULL DEFAULT false, 13 | "authorId" INTEGER NOT NULL, 14 | FOREIGN KEY ("authorId") REFERENCES "public"."User"(id) 15 | ); 16 | 17 | CREATE TABLE "public"."Profile" ( 18 | id SERIAL PRIMARY KEY NOT NULL, 19 | bio TEXT, 20 | "userId" INTEGER UNIQUE NOT NULL, 21 | FOREIGN KEY ("userId") REFERENCES "public"."User"(id) 22 | ); -------------------------------------------------------------------------------- /src/components/button/AccentButton.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | import Button from './Button' 3 | import { theme } from '@prisma/lens/dist/web' 4 | 5 | export enum AccentColor { 6 | RED = 'RED', 7 | ORANGE = 'ORANGE', 8 | PURPLE = 'PURPLE', 9 | } 10 | 11 | export const AccentButton = styled(Button)<{ color: AccentColor }>` 12 | background: ${(p) => colorForOption(p.color)}; 13 | color: ${theme.colors.white}; 14 | &:hover { 15 | background: ${(p) => hoverColorForOption(p.color)}; 16 | } 17 | ` 18 | 19 | const colorForOption = (color?: AccentColor) => { 20 | switch (color) { 21 | case AccentColor.RED: 22 | return theme.colors.red600 23 | case AccentColor.ORANGE: 24 | return theme.colors.orange600 25 | default: 26 | return theme.colors.purple600 27 | } 28 | } 29 | 30 | const hoverColorForOption = (color?: AccentColor) => { 31 | switch (color) { 32 | case AccentColor.RED: 33 | return theme.colors.red700 34 | case AccentColor.ORANGE: 35 | return theme.colors.orange700 36 | default: 37 | return theme.colors.purple700 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/components/button/PrimaryButton.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | import Button from './Button' 3 | import { theme } from '@prisma/lens/dist/web' 4 | 5 | export const PrimaryButton = styled(Button)` 6 | background: ${theme.colors.gray700}; 7 | color: ${theme.colors.white}; 8 | &:hover { 9 | background: ${theme.colors.gray600}; 10 | } 11 | ` 12 | -------------------------------------------------------------------------------- /src/components/button/SecondaryButton.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | import Button from './Button' 3 | import { theme } from '@prisma/lens/dist/web' 4 | 5 | export const SecondaryButton = styled(Button)` 6 | background: ${theme.colors.gray300}; 7 | color: ${theme.colors.text}; 8 | &:hover { 9 | background: ${theme.colors.gray200}; 10 | } 11 | ` 12 | -------------------------------------------------------------------------------- /src/components/button/SpecialButton.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | import Button from './Button' 3 | import { theme } from '@prisma/lens/dist/web' 4 | 5 | export const SpecialButton = styled(Button)` 6 | background: ${theme.colors.green500}; 7 | color: ${theme.colors.white}; 8 | &:hover { 9 | background: ${theme.colors.green600}; 10 | } 11 | ` 12 | -------------------------------------------------------------------------------- /src/components/button/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './PrimaryButton' 2 | export * from './SecondaryButton' 3 | export * from './SpecialButton' 4 | export * from './AccentButton' 5 | export { ButtonSize } from './Button' 6 | -------------------------------------------------------------------------------- /src/components/customMdx/admonition.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled from 'styled-components' 3 | import { theme } from '@prisma/lens/dist/web' 4 | import { AlertCircle } from 'react-feather' 5 | 6 | interface AdmonitionType { 7 | type?: string 8 | } 9 | 10 | type AdmonitionProps = React.ReactNode & AdmonitionType 11 | 12 | const colorMap: any = { 13 | info: theme.colors.gray200, 14 | warning: theme.colors.orange300, 15 | alert: theme.colors.red600, 16 | } 17 | 18 | const Admonition = ({ children, type, ...props }: AdmonitionProps) => { 19 | return ( 20 | <AdmonitionWrapper {...props} type={type}> 21 | {type === 'alert' && ( 22 | <span className="alert-circle"> 23 | <AlertCircle color="white" /> 24 | </span> 25 | )} 26 | {children} 27 | </AdmonitionWrapper> 28 | ) 29 | } 30 | 31 | export default Admonition 32 | 33 | const AdmonitionWrapper = styled.span<{ type?: string }>` 34 | font-family: Inter; 35 | font-style: normal; 36 | font-weight: 600; 37 | font-size: 16px; 38 | line-height: 24px; 39 | color: ${theme.colors.gray600} !important; 40 | padding-left: ${(p) => (p.type === 'alert' ? '3rem' : '1.5rem')}; 41 | padding-bottom: 8px; 42 | padding-bottom: 8px; 43 | margin: 2rem 0px; 44 | position: relative; 45 | display: flex; 46 | pre { 47 | font-weight: normal; 48 | } 49 | 50 | &::before { 51 | content: ''; 52 | position: absolute; 53 | width: 8px; 54 | height: 100%; 55 | left: 0px; 56 | background: ${(p) => (p.type ? colorMap[p.type] : colorMap['info'])} !important; 57 | border-radius: 5px; 58 | } 59 | 60 | &.alert { 61 | min-height: 50px; 62 | } 63 | 64 | .alert-circle { 65 | position: absolute; 66 | width: 34px; 67 | height: 100%; 68 | left: 0px; 69 | display: flex; 70 | justify-content: center; 71 | padding: 12px 0; 72 | background: ${(p) => (p.type ? colorMap[p.type] : colorMap['info'])} !important; 73 | border-radius: 5px; 74 | } 75 | 76 | code { 77 | color: ${theme.colors.gray600} !important; 78 | } 79 | 80 | p { 81 | margin: 0; 82 | } 83 | ` 84 | -------------------------------------------------------------------------------- /src/components/customMdx/codeBlock.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled from 'styled-components' 3 | 4 | interface CodeProps { 5 | languages?: string[] 6 | } 7 | 8 | type CodeBlockProps = CodeProps & React.ReactNode 9 | 10 | const CodeBlock = ({ languages, children }: CodeBlockProps) => { 11 | const [activeIndex, setActiveIndex] = React.useState(0) 12 | const child: any = React.Children.toArray(children)[activeIndex] 13 | const code = child && child.props && child.props.children 14 | 15 | return ( 16 | <Wrapper> 17 | {languages && Array.isArray(languages) && ( 18 | <Tabs> 19 | {languages.map((lang, index) => { 20 | const setCurrentActive = () => setActiveIndex(index) 21 | return ( 22 | <div 23 | className={`tab ${index === activeIndex ? 'active' : ''}`} 24 | key={lang} 25 | data-index={`${index}`} 26 | onClick={setCurrentActive} 27 | > 28 | {lang} 29 | </div> 30 | ) 31 | })} 32 | </Tabs> 33 | )} 34 | {code} 35 | </Wrapper> 36 | ) 37 | } 38 | 39 | export default CodeBlock 40 | 41 | const Tabs = styled.div` 42 | display: flex; 43 | .tab { 44 | margin-right: 10px; 45 | color: ${(p) => p.theme.colors.gray600}; 46 | cursor: pointer; 47 | } 48 | 49 | .tab.active { 50 | font-weight: 600; 51 | color: ${(p) => p.theme.colors.gray900}; 52 | } 53 | ` 54 | const Wrapper = styled.div` 55 | margin-top: 2rem; 56 | position: relative; 57 | ` 58 | -------------------------------------------------------------------------------- /src/components/customMdx/collapsible.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled from 'styled-components' 3 | import ArrowRight from '../../icons/ArrowRight' 4 | 5 | type CollapseProps = React.ReactNode 6 | let index = 0 7 | 8 | const getRemainingChildren = (children: any) => 9 | children.filter((child: any) => !(child.props && child.props.originalType === 'summary')) 10 | 11 | const CollapseBox = ({ children, ...props }: CollapseProps) => { 12 | const titleChild = 13 | children && children.find((child: any) => child.props && child.props.originalType === 'summary') 14 | const title = titleChild && titleChild.props.children 15 | return ( 16 | <Wrapper {...props}> 17 | <Tab> 18 | <Input id={`tab-${++index}`} type="checkbox" name="tab" /> 19 | <StyledArrow /> 20 | <Label htmlFor={`tab-${index}`}>{title}</Label> 21 | <TabContent className="tab-content">{getRemainingChildren(children)}</TabContent> 22 | </Tab> 23 | </Wrapper> 24 | ) 25 | } 26 | 27 | export default CollapseBox 28 | 29 | const Wrapper = styled.div` 30 | margin-bottom: ${(p) => p.theme.space[16]}; 31 | ` 32 | 33 | const Tab = styled.div` 34 | position: relative; 35 | overflow: hidden; 36 | .tab-content { 37 | transition: max-height 0.35s; 38 | } 39 | &:before { 40 | content: ''; 41 | position: absolute; 42 | width: 8px; 43 | height: 100%; 44 | left: 0px; 45 | background: ${(p) => p.theme.colors.gray100}; 46 | border-radius: ${(p) => p.theme.radii.small}; 47 | } 48 | p { 49 | margin-top: ${(p) => p.theme.space[8]}; 50 | } 51 | ` 52 | 53 | const Label = styled.label` 54 | position: relative; 55 | display: block; 56 | color: #0c344b; 57 | font-weight: 600; 58 | line-height: 1.5; 59 | padding-left: ${(p) => p.theme.space[32]}; 60 | cursor: pointer; 61 | ` 62 | 63 | const TabContent = styled.div` 64 | max-height: 0; 65 | overflow: hidden; 66 | color: ${(p) => p.theme.colors.gray800}; 67 | transition: max-height 0.35s, padding 0.35s; 68 | padding-left: 36px; 69 | padding-bottom: 0; 70 | ` 71 | 72 | const Input = styled.input` 73 | position: absolute; 74 | opacity: 0; 75 | z-index: -1; 76 | &:checked ~ .tab-content { 77 | max-height: 2000px; 78 | padding-bottom: ${(p) => p.theme.space[8]}; 79 | } 80 | ` 81 | 82 | const StyledArrow = styled(ArrowRight)` 83 | position: absolute; 84 | left: 18px; 85 | top: 8px; 86 | transition: transform 0.15s; 87 | input:checked + & { 88 | transform: rotate(90deg); 89 | } 90 | ` 91 | -------------------------------------------------------------------------------- /src/components/customMdx/copy.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled from 'styled-components' 3 | import * as CopyToClipboard from 'react-copy-to-clipboard' 4 | 5 | interface CopyProps { 6 | text: string 7 | } 8 | 9 | type CopyButtonProps = CopyProps & React.ReactNode 10 | 11 | const CopyButton = ({ text, children }: CopyButtonProps) => { 12 | const [copied, setCopied] = React.useState(false) 13 | let copyTimer: any 14 | 15 | const onCopyContent = () => { 16 | setCopied(true) 17 | copyTimer = window.setTimeout(() => setCopied(false), 500) 18 | } 19 | 20 | return ( 21 | <CopyToClipboard text={text} onCopy={onCopyContent}> 22 | <CopyComponent> 23 | {copied && ( 24 | <div className="indicator" style={{ color: 'var(--list-bullet-color)' }}> 25 | Copied 26 | </div> 27 | )} 28 | {children} 29 | </CopyComponent> 30 | </CopyToClipboard> 31 | ) 32 | } 33 | 34 | export default CopyButton 35 | 36 | const CopyComponent = styled.div` 37 | font-family: ${(p) => p.theme.fonts.text}; 38 | & { 39 | position: relative; 40 | cursor: pointer; 41 | display: inline-block; 42 | } 43 | @keyframes copying { 44 | 0% { 45 | opacity: 0; 46 | transform: translate(-50%, 0); 47 | } 48 | 50% { 49 | opacity: 1; 50 | } 51 | 100% { 52 | opacity: 0; 53 | transform: translate(-50%, 30px); 54 | } 55 | } 56 | .indicator { 57 | position: absolute; 58 | top: 20px; 59 | left: 0; 60 | transform: translate(-50%, 0); 61 | animation: copying 700ms linear; 62 | } 63 | ` 64 | -------------------------------------------------------------------------------- /src/components/customMdx/fileWithIcon.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled from 'styled-components' 3 | import File from '../../icons/File' 4 | import Display from '../../icons/Display' 5 | import Code from '../../icons/Code' 6 | import Database from '../../icons/Database' 7 | import Prisma from '../../icons/Prisma' 8 | 9 | interface FileWithIconProps { 10 | text: string[] 11 | icon: keyof typeof icons 12 | } 13 | 14 | const icons = { 15 | file: <File />, 16 | database: <Database />, 17 | display: <Display />, 18 | code: <Code />, 19 | prisma: <Prisma />, 20 | } 21 | const FileNameWrapper = styled.span` 22 | color: inherit; 23 | display: inline-flex; 24 | align-items: center; 25 | svg { 26 | margin-right: ${(p) => p.theme.space[8]}; 27 | } 28 | @media (max-width: ${(p) => p.theme.breakpoints.tablet}) { 29 | font-size: ${(p) => p.theme.fontSizes[14]}; 30 | } 31 | ` 32 | 33 | const FileWithIcon = ({ icon, text }: FileWithIconProps) => ( 34 | <FileNameWrapper> 35 | {icons[icon]} 36 | {text} 37 | </FileNameWrapper> 38 | ) 39 | 40 | export default FileWithIcon 41 | -------------------------------------------------------------------------------- /src/components/customMdx/footnote.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled from 'styled-components' 3 | 4 | type FootNoteProps = React.ReactNode 5 | 6 | const FootNote = ({ children, ...props }: FootNoteProps) => { 7 | return <FootNoteWrapper {...props}>{children}</FootNoteWrapper> 8 | } 9 | 10 | export default FootNote 11 | 12 | const FootNoteWrapper = styled.div` 13 | * { 14 | font-size: 0.9em; 15 | font-style: italic; 16 | } 17 | ` 18 | -------------------------------------------------------------------------------- /src/components/customMdx/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import SwitchTech from './switchTech' 3 | import CodeBlock from './codeBlock' 4 | import TabbedContent from './tabbedContent' 5 | import ParallelBlocks from './parallelBlocks' 6 | import CodeWithResult from './codeWithResult' 7 | import Code from './code' 8 | import CollapseBox from './collapsible' 9 | import Table from './table' 10 | import ButtonLink from './button' 11 | import FileWithIcon from './fileWithIcon' 12 | import Subsections from './subSections' 13 | import TopBlock from './topBlock' 14 | import FootNote from './footnote' 15 | import Admonition from './admonition' 16 | import Quiz from './quiz' 17 | import Tip from './tip' 18 | import NavigationLinksContainer from './navigationLinksContainer' 19 | 20 | export default { 21 | h1: () => <h1 style={{ display: 'none' }} />, 22 | h2: ({ id, ...props }: any) => <h2 id={id.replace(/inlinecode/g, '')} {...props} />, 23 | h3: ({ id, ...props }: any) => <h3 id={id.replace(/inlinecode/g, '')} {...props} />, 24 | h4: ({ id, ...props }: any) => <h4 id={id.replace(/inlinecode/g, '')} {...props} />, 25 | a: ({ href, ...props }: any) => ( 26 | <a href={href ? href.replace(/inlinecode/g, '') : ''} {...props} /> 27 | ), 28 | p: (props: any) => <p className="paragraph" {...props} />, 29 | ul: (props: any) => <ul className="list" {...props} />, 30 | ol: (props: any) => <ol className="o-list" {...props} />, 31 | CodeBlock, 32 | TabbedContent, 33 | ParallelBlocks, 34 | CodeWithResult, 35 | SwitchTech, 36 | FileWithIcon, 37 | inlineCode: (props: any) => <code className="inline-code" {...props} />, 38 | code: Code, 39 | details: CollapseBox, 40 | table: Table, 41 | ButtonLink, 42 | Subsections, 43 | TopBlock, 44 | FootNote, 45 | Admonition, 46 | img: (props: any) => ( 47 | <a href={props.src} target="_blank"> 48 | <img {...props} /> 49 | </a> 50 | ), 51 | AlgoliaTerm: () => <span style={{ display: 'none' }} />, 52 | Quiz, 53 | Tip: (props: any) => <Tip>{props.children}</Tip>, 54 | NavigationLinksContainer: (props: any) => ( 55 | <NavigationLinksContainer {...props}>{props.children}</NavigationLinksContainer> 56 | ), 57 | } 58 | -------------------------------------------------------------------------------- /src/components/customMdx/navigationLinksContainer.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled from 'styled-components' 3 | 4 | interface Props { 5 | isFirstLink?: boolean 6 | } 7 | 8 | const ButtonContainer = styled.section<Props>` 9 | display: flex; 10 | justify-content: ${(props) => (props.isFirstLink ? 'flex-end' : 'space-between')}; 11 | align-items: center; 12 | padding: 1rem 0 1rem 0; 13 | border-top: solid 2px ${(p) => p.theme.colors.gray100}; 14 | padding-top: 2rem; 15 | margin: 2rem 0; 16 | ` 17 | 18 | const NavigationLinksContainer: React.FC<Props> = ({ children, isFirstLink }) => { 19 | return <ButtonContainer isFirstLink={isFirstLink}>{children}</ButtonContainer> 20 | } 21 | 22 | export default NavigationLinksContainer 23 | -------------------------------------------------------------------------------- /src/components/customMdx/parallelBlocks.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled from 'styled-components' 3 | 4 | type CodeBlockProps = React.ReactNode 5 | 6 | const ParallelBlocks = ({ children }: CodeBlockProps) => { 7 | const blockContent = 8 | children && children.filter((child: any) => child.props && child.props.originalType === 'block') 9 | return ( 10 | <Wrapper> 11 | {blockContent.map((block: any, i: number) => ( 12 | <Block key={i}> 13 | <div className="blockHeading">{block.props.content}</div> 14 | <div className="blockContent">{block.props.children}</div> 15 | </Block> 16 | ))} 17 | </Wrapper> 18 | ) 19 | } 20 | 21 | export default ParallelBlocks 22 | 23 | const Block = styled.div` 24 | flex: 1 1 0px; 25 | margin-right: 0.5rem; 26 | &:last-of-type { 27 | margin: 0; 28 | } 29 | .blockHeading { 30 | font-weight: 600; 31 | font-size: ${(p) => p.theme.fontSizes[14]}; 32 | svg { 33 | margin-right: ${(p) => p.theme.space[8]}; 34 | } 35 | } 36 | 37 | .blockContent { 38 | height: calc(100% - 2em); 39 | 40 | .pre-highlight, 41 | pre { 42 | height: 100%; 43 | } 44 | } 45 | 46 | @media (max-width: ${(p) => p.theme.breakpoints.tablet}) and (min-width: 0px) { 47 | .pre-highlight { 48 | margin: 0; 49 | } 50 | &:first-of-type .pre-highlight { 51 | margin-right: 0; 52 | margin-left: -${(p) => p.theme.space[24]}; 53 | } 54 | &:last-of-type .pre-highlight { 55 | margin-left: 0; 56 | margin-right: -${(p) => p.theme.space[24]}; 57 | } 58 | } 59 | ` 60 | const Wrapper = styled.div` 61 | display: flex; 62 | margin-top: ${(p) => p.theme.space[32]}; 63 | ` 64 | -------------------------------------------------------------------------------- /src/components/customMdx/prism/prism-prisma.js: -------------------------------------------------------------------------------- 1 | import Prism from 'prism-react-renderer/prism' 2 | ;(typeof global !== 'undefined' ? global : window).Prism = Prism 3 | Prism.languages.prisma = Prism.languages.extend('clike', { 4 | keyword: /\b(?:datasource|enum|generator|model|type)\b/, 5 | 'type-class-name': /(\b()\s+)[\w.\\]+/, 6 | }) 7 | 8 | Prism.languages.javascript['class-name'][0].pattern = 9 | /(\b(?:model|datasource|enum|generator|type)\s+)[\w.\\]+/ 10 | 11 | Prism.languages.insertBefore('prisma', 'function', { 12 | annotation: { 13 | pattern: /(^|[^.])@+\w+/, 14 | lookbehind: true, 15 | alias: 'punctuation', 16 | }, 17 | }) 18 | 19 | Prism.languages.insertBefore('prisma', 'punctuation', { 20 | 'type-args': /\b(?:references|fields):/, 21 | }) 22 | 23 | Prism.languages.json5 = Prism.languages.js 24 | -------------------------------------------------------------------------------- /src/components/customMdx/switchTech.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled from 'styled-components' 3 | 4 | interface CodeProps { 5 | technologies?: string[] 6 | } 7 | 8 | type CodeBlockProps = CodeProps & React.ReactNode 9 | 10 | const SwitchTech = ({ technologies, children }: CodeBlockProps) => { 11 | return <SwitchWrapper id={`techswitch-${technologies.join('-')}`}>{children}</SwitchWrapper> 12 | } 13 | 14 | export default SwitchTech 15 | 16 | const SwitchWrapper = styled.section` 17 | display: none; 18 | position: relative; 19 | &.show { 20 | display: block; 21 | } 22 | ` 23 | -------------------------------------------------------------------------------- /src/components/customMdx/tabbedContent/DefaultTabOS.tsx: -------------------------------------------------------------------------------- 1 | export const defaultOSIndex = (tabs: any[]): number => { 2 | let detectedOS = 'unkown' 3 | 4 | // Check user OS 5 | if (navigator.appVersion.indexOf('Mac') != -1 || navigator.appVersion.indexOf('Linux') != -1) 6 | detectedOS = 'unix' 7 | if (navigator.appVersion.indexOf('Win') != -1) detectedOS = 'windows' 8 | 9 | const matchedOS = (tab: any) => tab.props.defaultKey === detectedOS 10 | const index = tabs.findIndex(matchedOS) 11 | 12 | return index !== -1 ? index : 0 13 | } 14 | -------------------------------------------------------------------------------- /src/components/customMdx/tabbedContent/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled from 'styled-components' 3 | 4 | import { defaultOSIndex } from './DefaultTabOS' 5 | 6 | enum DefaultTabType { 7 | OS = 'OS', 8 | } 9 | 10 | interface CodeProps { 11 | tabs?: any[] 12 | defaultTabType?: DefaultTabType 13 | } 14 | 15 | type CodeBlockProps = CodeProps & React.ReactNode 16 | 17 | const TabbedContent = ({ tabs, defaultTabType, children }: CodeBlockProps) => { 18 | const [activeIndex, setActiveIndex] = React.useState(0) 19 | const tabContent = 20 | children && 21 | children.filter((child: any) => child.props && child.props.originalType === 'tab')[activeIndex] 22 | 23 | React.useEffect(() => { 24 | if (tabs && tabs.length > 1) { 25 | // check if any default tab behaviour has been stipulated 26 | switch (defaultTabType) { 27 | case DefaultTabType.OS: { 28 | setActiveIndex(defaultOSIndex(tabs)) 29 | break 30 | } 31 | default: { 32 | break 33 | } 34 | } 35 | } // else the current default of [0] will remain 36 | }, []) 37 | 38 | return ( 39 | <Wrapper> 40 | {tabs && Array.isArray(tabs) && ( 41 | <Tabs> 42 | {tabs.map((tab: any, index: number) => { 43 | const setCurrentActive = () => setActiveIndex(index) 44 | return ( 45 | <div 46 | className={`tabHeading ${index === activeIndex ? 'active' : ''}`} 47 | key={index} 48 | data-index={`${index}`} 49 | onClick={setCurrentActive} 50 | > 51 | {tab} 52 | </div> 53 | ) 54 | })} 55 | </Tabs> 56 | )} 57 | {tabContent} 58 | </Wrapper> 59 | ) 60 | } 61 | 62 | export default TabbedContent 63 | 64 | const Tabs = styled.div` 65 | display: flex; 66 | .tabHeading { 67 | margin-right: 10px; 68 | font-weight: 600; 69 | color: ${(p) => p.theme.colors.gray600}; 70 | cursor: pointer; 71 | font-size: ${(p) => p.theme.fontSizes[14]}; 72 | display: flex; 73 | align-items: center; 74 | padding: 3px 5px; 75 | svg { 76 | margin-right: ${(p) => p.theme.space[8]}; 77 | } 78 | } 79 | 80 | .tabHeading.active { 81 | color: ${(p) => p.theme.colors.gray900}; 82 | background: ${(p) => p.theme.colors.gray100}; 83 | border-radius: ${(p) => p.theme.radii.small}; 84 | svg path { 85 | stroke: ${(p) => p.theme.colors.gray600}; 86 | } 87 | } 88 | ` 89 | const Wrapper = styled.div` 90 | margin-top: ${(p) => p.theme.space[24]}; 91 | position: relative; 92 | font-size: ${(p) => p.theme.fontSizes[14]}; 93 | 94 | tab pre > * { 95 | margin-top: 0.5em; 96 | } 97 | ` 98 | -------------------------------------------------------------------------------- /src/components/customMdx/table.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled from 'styled-components' 3 | 4 | type TableProps = React.ReactNode 5 | 6 | const Table = ({ children, ...props }: TableProps) => { 7 | return ( 8 | <TableWrapper> 9 | <table {...props}>{children}</table> 10 | </TableWrapper> 11 | ) 12 | } 13 | 14 | export default Table 15 | 16 | const TableWrapper = styled.div` 17 | overflow-x: auto; 18 | margin-top: 1em; 19 | @media (min-width: 0px) and (max-width: ${(p) => p.theme.breakpoints.tablet}) { 20 | margin-right: -${(p) => p.theme.space[24]}; 21 | margin-left: -${(p) => p.theme.space[24]}; 22 | 23 | table { 24 | border-left: 0; 25 | border-right: 0; 26 | border-radius: 0 !important; 27 | } 28 | } 29 | ` 30 | -------------------------------------------------------------------------------- /src/components/customMdx/tip.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled from 'styled-components' 3 | 4 | const Wrapper = styled.section` 5 | padding: 1rem; 6 | background-color: ${(p) => p.theme.colors.gray100}; 7 | border-radius: 8px; 8 | min-height: 100px; 9 | margin: 2rem 0; 10 | position: relative; 11 | 12 | &::before { 13 | content: '💡'; 14 | position: absolute; 15 | display: flex; 16 | justify-content: center; 17 | align-items: center; 18 | font-size: 1.1rem; 19 | top: -15px; 20 | left: -10px; 21 | width: 50px; 22 | height: 50px; 23 | border-bottom-right-radius: 50%; 24 | background-color: white; 25 | z-index: 999; 26 | } 27 | 28 | & > div { 29 | margin-left: 1.5rem; 30 | } 31 | ` 32 | 33 | const Tip = ({ children }: any) => { 34 | return ( 35 | <Wrapper> 36 | <div>{children}</div> 37 | </Wrapper> 38 | ) 39 | } 40 | 41 | export default Tip 42 | -------------------------------------------------------------------------------- /src/components/customMdx/topBlock.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled from 'styled-components' 3 | 4 | type TopBlockProps = React.ReactNode 5 | 6 | const TopBlock = ({ children, ...props }: TopBlockProps) => { 7 | return <TopBlockWrapper {...props}>{children}</TopBlockWrapper> 8 | } 9 | 10 | export default TopBlock 11 | 12 | const TopBlockWrapper = styled.section` 13 | /* padding: ${(p) => p.theme.space[4]} ${(p) => p.theme.space[40]}; */ 14 | ` 15 | -------------------------------------------------------------------------------- /src/components/footer.tsx: -------------------------------------------------------------------------------- 1 | import Link from '../components/link' 2 | import * as React from 'react' 3 | import styled from 'styled-components' 4 | import { WebsiteFooter } from '@prisma/lens/dist/web' 5 | import NewsLetter from '../components/newsletter' 6 | 7 | type FooterViewProps = { 8 | footerProps: FooterProps 9 | } 10 | 11 | const FooterWrapper = styled.div` 12 | background: transparent; 13 | width: 100%; 14 | display: flex; 15 | justify-content: center; 16 | color: ${(p) => p.theme.colors.gray500}; 17 | > * { 18 | .group { 19 | a { 20 | color: currentcolor !important; 21 | text-decoration: none; 22 | 23 | &:hover { 24 | color: ${(p) => p.theme.colors.gray600} !important; 25 | } 26 | } 27 | } 28 | @media (min-width: 0px) and (max-width: ${(p) => p.theme.breakpoints.tablet}) { 29 | flex-direction: column; 30 | padding: ${(p) => p.theme.fontSizes[48]} 0.5rem; 31 | } 32 | } 33 | ` 34 | 35 | const FooterSec = ({ footerProps }: FooterViewProps) => { 36 | const { newsletter } = footerProps 37 | return ( 38 | <FooterWrapper> 39 | <WebsiteFooter newsletterComponent={<NewsLetter newsletter={newsletter} />} /> 40 | </FooterWrapper> 41 | ) 42 | } 43 | 44 | export default FooterSec 45 | -------------------------------------------------------------------------------- /src/components/image.tsx: -------------------------------------------------------------------------------- 1 | import { graphql, useStaticQuery } from 'gatsby' 2 | import Img from 'gatsby-image' 3 | import * as React from 'react' 4 | 5 | /* 6 | * This component is built using `gatsby-image` to automatically serve optimized 7 | * images with lazy loading and reduced file sizes. The image is loaded using a 8 | * `StaticQuery`, which allows us to load the image from directly within this 9 | * component, rather than having to pass the image data down from pages. 10 | * 11 | * For more information, see the docs: 12 | * - `gatsby-image`: https://gatsby.app/gatsby-image 13 | * - `StaticQuery`: https://gatsby.app/staticquery 14 | */ 15 | 16 | const Image = () => { 17 | const { placeholderImage } = useStaticQuery(graphql` 18 | query { 19 | placeholderImage: file(relativePath: { eq: "gatsby-astronaut.png" }) { 20 | childImageSharp { 21 | fluid(maxWidth: 300) { 22 | ...GatsbyImageSharpFluid 23 | } 24 | } 25 | } 26 | } 27 | `) 28 | 29 | return <Img fluid={placeholderImage.childImageSharp.fluid} /> 30 | } 31 | export default Image 32 | -------------------------------------------------------------------------------- /src/components/link.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link as GatsbyLink } from 'gatsby' 3 | import isAbsoluteUrl from 'is-absolute-url' 4 | 5 | interface LinkProps { 6 | to: string | null 7 | activeClassName?: string 8 | partiallyActive?: string 9 | getProps?: any 10 | } 11 | 12 | const Link = ({ 13 | to, 14 | activeClassName, 15 | partiallyActive, 16 | getProps, 17 | ...props 18 | }: LinkProps & React.ReactNode) => 19 | !to || isAbsoluteUrl(to) ? ( 20 | <a href={to} {...props}> 21 | {props.children} 22 | </a> 23 | ) : ( 24 | <GatsbyLink 25 | to={to} 26 | activeClassName={activeClassName} 27 | partiallyActive={partiallyActive} 28 | getProps={getProps} 29 | {...props} 30 | /> 31 | ) 32 | 33 | export default Link 34 | -------------------------------------------------------------------------------- /src/components/newsletter/mailChimp.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Subscribe to mailchimp 3 | * 4 | * TODO: better align with mailchimp, this is using an undocumented API 5 | * https://stackoverflow.com/questions/5188418/jquery-ajax-post-not-working-with-mailchimp/16369887#16369887 6 | */ 7 | 8 | export default async function subscribe(email: string): Promise<void> { 9 | await fetch( 10 | `https://coo.us14.list-manage.com/subscribe/post-json?u=dbacf466dc6e90901d8936391&id=83e066a034&EMAIL=${encodeURIComponent( 11 | email 12 | )}&c=?`, 13 | { 14 | method: 'GET', 15 | mode: 'no-cors', 16 | } 17 | ) 18 | // no-cors doesn't give us any information, so this is just a fire & pray 19 | return 20 | } 21 | -------------------------------------------------------------------------------- /src/components/newsletter/valid.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Test for an invalid email 3 | */ 4 | 5 | export function email(email: string): string | Error { 6 | email = email.toLowerCase() 7 | const re = 8 | /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ 9 | if (!re.test(email)) { 10 | return new Error(`invalid email: ${email}`) 11 | } 12 | return email 13 | } 14 | -------------------------------------------------------------------------------- /src/components/parentTitleComp.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled from 'styled-components' 3 | import { useAllArticlesQuery } from '../hooks/useAllArticlesQuery' 4 | import { getParentTitle } from '../utils/parentTitle' 5 | import { AllArticles } from '../interfaces/AllArticles.interface' 6 | import Link from './link' 7 | 8 | const BreadcrumbTitle = styled.div` 9 | color: ${(p) => p.theme.colors.gray600} !important; 10 | line-height: 1rem; 11 | font-weight: normal; 12 | margin: 0; 13 | a { 14 | color: ${(p) => p.theme.colors.gray600} !important; 15 | text-decoration: none; 16 | 17 | &:hover, 18 | &:focus { 19 | color: ${(p) => p.theme.colors.gray700} !important; 20 | text-decoration: underline; 21 | cursor: pointer; 22 | } 23 | } 24 | ` 25 | 26 | interface ParentTitleProps { 27 | slug: string 28 | nonLink?: boolean 29 | } 30 | 31 | const ParentTitle = ({ slug, nonLink }: ParentTitleProps) => { 32 | const { allMdx }: AllArticles = useAllArticlesQuery() 33 | const parentTitle = getParentTitle(slug, allMdx) 34 | if (parentTitle.length === 0) { 35 | return null 36 | } 37 | return ( 38 | <BreadcrumbTitle> 39 | {parentTitle.map((part: any, index: number) => ( 40 | <span key={index}> 41 | {part.link && !nonLink ? ( 42 | <Link to={part.link}> 43 | <span className={`${part.codeStyle ? 'inline-code' : ''}`}>{part.title}</span> 44 | </Link> 45 | ) : ( 46 | <span className={`${part.codeStyle ? 'inline-code' : ''}`}>{part.title}</span> 47 | )} 48 | {parentTitle.length !== index + 1 ? ' / ' : ''} 49 | </span> 50 | ))} 51 | </BreadcrumbTitle> 52 | ) 53 | } 54 | 55 | export default ParentTitle 56 | -------------------------------------------------------------------------------- /src/components/search/hitComps.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { Snippet } from 'react-instantsearch-dom' 3 | import Link from '../link' 4 | import styled from 'styled-components' 5 | import ParentTitle from '../parentTitleComp' 6 | 7 | const HitComp = styled.div` 8 | padding: ${(p) => p.theme.space[24]} ${(p) => p.theme.space[40]} !important; 9 | font-family: ${(p) => p.theme.fonts.text}; 10 | font-style: normal; 11 | font-weight: normal; 12 | font-size: ${(p) => p.theme.fontSizes[16]}; 13 | line-height: ${(p) => p.theme.space[24]}; 14 | border-bottom: 1px solid ${(p) => p.theme.colors.gray300}; 15 | // max-height: 150px; 16 | &:last-item { 17 | border: 0; 18 | } 19 | a { 20 | color: ${(p) => p.theme.colors.gray900} !important; 21 | display: block; 22 | } 23 | h4 { 24 | font-weight: normal; 25 | } 26 | h3 { 27 | font-weight: 600; 28 | line-height: 28px; 29 | letter-spacing: -0.01em; 30 | margin: 10px 0; 31 | } 32 | &:hover, 33 | &:focus { 34 | background: ${(p) => p.theme.colors.gray100}; 35 | } 36 | mark { 37 | color: ${(p) => p.theme.colors.blue600} !important; 38 | background: #ebf8ff; 39 | padding: 2px; 40 | font-weight: bold; 41 | } 42 | 43 | .more { 44 | color: ${(p) => p.theme.colors.blue600}; 45 | font-size: ${(p) => p.theme.fontSizes[14]}; 46 | width: fit-content; 47 | margin: 10px 0 0; 48 | } 49 | 50 | @media (min-width: 0px) and (max-width: ${(p) => p.theme.breakpoints.tablet}) { 51 | max-height: fit-content; 52 | padding: ${(p) => p.theme.space[24]} !important; 53 | } 54 | ` 55 | 56 | const DocHit = ({ hit, selected }: any) => 57 | hit._distinctSeqID == 0 ? ( 58 | <HitComp style={{ background: selected ? '#F7FAFC' : 'white' }}> 59 | <Link style={{ boxShadow: `none`, textDecoration: 'none' }} to={hit.path}> 60 | <ParentTitle slug={hit.slug} nonLink={true} /> 61 | <h3> 62 | <Snippet hit={hit} attribute="title" tagName="mark" /> /{' '} 63 | <span style={{ color: 'var(--code-inner-color)' }}> 64 | <Snippet hit={hit} attribute="heading" tagName="mark" /> 65 | </span> 66 | </h3> 67 | <Snippet hit={hit} attribute="content" tagName="mark" /> 68 | {hit.moreCount > 1 && <p className="more">... More results on this page</p>} 69 | </Link> 70 | </HitComp> 71 | ) : null 72 | 73 | export default DocHit 74 | -------------------------------------------------------------------------------- /src/components/search/overlay.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled from 'styled-components' 3 | import styledTS from 'styled-components-ts' 4 | 5 | interface Props { 6 | visible: boolean 7 | hideSearch: () => void 8 | } 9 | 10 | const Overlay = ({ visible, hideSearch }: Props) => { 11 | const [transition, setTransition] = React.useState(false) 12 | 13 | React.useEffect(() => { 14 | setTimeout(() => { 15 | setTransition(true) 16 | }, 1000) 17 | }) 18 | 19 | return <StyledOverlay isVisible={visible} isTransitioning={transition} onClick={hideSearch} /> 20 | } 21 | 22 | const StyledOverlay = styledTS<{ isVisible: boolean; isTransitioning: boolean }>(styled.div)` 23 | position: fixed; 24 | top: 0; 25 | left: 0; 26 | right: 0; 27 | bottom: 0; 28 | background: rgba(8, 35, 51, 0.3); 29 | opacity: 0; 30 | pointer-events: none; 31 | z-index: 10000; 32 | 33 | ${(p) => p.isTransitioning && 'transition: opacity 0.25s ease-in-out;'} 34 | ${(p) => (p.isVisible ? 'opacity: 1; pointer-events: all;' : 'opacity: 0; pointer-events: none;')} 35 | ` 36 | 37 | export default Overlay 38 | -------------------------------------------------------------------------------- /src/components/select.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled from 'styled-components' 3 | import Select, { components } from 'react-select' 4 | 5 | interface SelectProps { 6 | items: any[] 7 | onChange: (item: any) => void 8 | selectedItem: any 9 | width?: number 10 | DropdownIndicator: any 11 | IndicatorSeperator: any 12 | Option: any 13 | SingleValue: any 14 | } 15 | 16 | const SelectComponent = (props: SelectProps) => { 17 | const { 18 | selectedItem, 19 | onChange, 20 | items, 21 | DropdownIndicator, 22 | IndicatorSeperator, 23 | Option, 24 | SingleValue, 25 | } = props 26 | const width = props.width || 160 27 | 28 | const handleChange = (newValue: any) => { 29 | onChange({ technology: newValue.value }) 30 | } 31 | 32 | const options = items.map((it) => ({ value: it.technology, label: it.technology })) 33 | 34 | const selectedOption = options.filter((ff) => ff.value === selectedItem.technology) 35 | 36 | const SelectContainer = (props: any) => { 37 | return ( 38 | <components.SelectContainer {...props} className="select-container"> 39 | {props.children} 40 | </components.SelectContainer> 41 | ) 42 | } 43 | return ( 44 | <SelectComponentWrapper> 45 | <Select 46 | width={width} 47 | options={options} 48 | defaultValue={selectedOption} 49 | onChange={handleChange} 50 | components={{ DropdownIndicator, IndicatorSeperator, Option, SingleValue, SelectContainer }} 51 | /> 52 | </SelectComponentWrapper> 53 | ) 54 | } 55 | 56 | export default SelectComponent 57 | 58 | const SelectComponentWrapper = styled.div` 59 | .select-container { 60 | > div:first-child { 61 | height: 38px; 62 | border-color: #e2e8f0; 63 | border-radius: 5px; 64 | } 65 | } 66 | ` as any 67 | -------------------------------------------------------------------------------- /src/components/sidebar/tree.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react' 2 | import TreeNode from './treeNode' 3 | import { AllEdges } from '../../interfaces/AllArticles.interface' 4 | import { createGlobalState } from 'react-hooks-global-state' 5 | import { useLocation } from '@reach/router' 6 | import { calculateTreeData } from '../../utils/treeData' 7 | 8 | let defaultCollapsed: any = {} 9 | 10 | const initialState = { collapsedState: defaultCollapsed } 11 | const { useGlobalState } = createGlobalState(initialState) 12 | 13 | const Tree = ({ edges }: AllEdges) => { 14 | const location = useLocation() 15 | 16 | let [treeData] = useState(() => { 17 | return calculateTreeData(edges, defaultCollapsed, location) 18 | }) 19 | 20 | const [collapsed, setCollapsed] = useGlobalState('collapsedState') 21 | const toggle = (label: string, toggleContent: boolean, parents?: string[]) => { 22 | setCollapsed({ 23 | ...collapsed, 24 | [label]: !toggleContent ? false : !collapsed[label], 25 | }) 26 | if (parents) { 27 | parents.forEach((parent) => { 28 | if (parent && collapsed[parent] !== null) { 29 | setCollapsed({ 30 | ...collapsed, 31 | [parent]: false, 32 | }) 33 | } 34 | }) 35 | } 36 | } 37 | return <TreeNode setCollapsed={toggle} collapsed={collapsed} {...treeData} location={location} /> 38 | } 39 | 40 | export default Tree 41 | -------------------------------------------------------------------------------- /src/components/topSection.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import styled from 'styled-components' 3 | import ParentTitle from './parentTitleComp' 4 | import SwitcherBlock from './switcherBlock' 5 | 6 | const TopSectionWrapper = styled.div` 7 | position: relative; 8 | 9 | .tech-switch-block { 10 | position: relative; 11 | } 12 | 13 | @media (min-width: 0px) and (max-width: ${(p) => p.theme.breakpoints.phone}) { 14 | .tech-switch-block { 15 | width: 100%; 16 | } 17 | } 18 | ` 19 | const Header = styled.div` 20 | display: flex; 21 | justify-content: space-between; 22 | align-items: center; 23 | @media (min-width: 0px) and (max-width: ${(p) => p.theme.breakpoints.phone}) { 24 | flex-direction: column; 25 | align-items: baseline; 26 | } 27 | ` 28 | 29 | const MainTitle = styled.h1` 30 | font-family: ${(p) => p.theme.fonts.display}; 31 | font-size: ${(p) => p.theme.fontSizes[40]} !important; 32 | font-style: normal; 33 | font-weight: bold; 34 | letter-spacing: -0.02em; 35 | color: ${(p) => p.theme.colors.gray900}; 36 | margin: 0; 37 | margin-top: 4px; 38 | &.inline-code { 39 | font-size: ${(p) => p.theme.fontSizes[32]}; 40 | padding: 0px 0.2em; 41 | line-height: 3rem; 42 | } 43 | @media (min-width: 0px) and (max-width: ${(p) => p.theme.breakpoints.tablet}) { 44 | font-size: ${(p) => p.theme.fontSizes[24]}; 45 | } 46 | ` 47 | 48 | const TopSection = ({ 49 | location, 50 | navigate, 51 | title, 52 | slug, 53 | langSwitcher, 54 | dbSwitcher, 55 | toc, 56 | codeStyle, 57 | }: any) => { 58 | return ( 59 | <TopSectionWrapper> 60 | <Header> 61 | <div className="title"> 62 | <ParentTitle slug={slug} /> 63 | <MainTitle className={`${codeStyle ? 'inline-code' : ''}`}>{title}</MainTitle> 64 | </div> 65 | <div className="tech-switch-block"> 66 | {(langSwitcher || dbSwitcher) && ( 67 | <SwitcherBlock 68 | langSwitcher={langSwitcher} 69 | dbSwitcher={dbSwitcher} 70 | navigate={navigate} 71 | location={location} 72 | slug={slug} 73 | /> 74 | )} 75 | </div> 76 | </Header> 77 | </TopSectionWrapper> 78 | ) 79 | } 80 | 81 | export default TopSection 82 | -------------------------------------------------------------------------------- /src/hooks/useAllArticlesQuery.ts: -------------------------------------------------------------------------------- 1 | import { graphql, useStaticQuery } from 'gatsby' 2 | import { AllArticles } from '../interfaces/AllArticles.interface' 3 | 4 | export const useAllArticlesQuery = () => { 5 | const { allMdx }: AllArticles = useStaticQuery(graphql` 6 | query { 7 | allMdx { 8 | edges { 9 | node { 10 | frontmatter { 11 | title 12 | duration 13 | staticLink 14 | experimental 15 | preview 16 | earlyaccess 17 | langSwitcher 18 | dbSwitcher 19 | hidePage 20 | codeStyle 21 | } 22 | fields { 23 | slug 24 | modSlug 25 | } 26 | } 27 | } 28 | } 29 | } 30 | `) 31 | 32 | return { allMdx } 33 | } 34 | -------------------------------------------------------------------------------- /src/hooks/useLayoutQuery.ts: -------------------------------------------------------------------------------- 1 | import { graphql, useStaticQuery } from 'gatsby' 2 | import { LayoutQueryData } from '../interfaces/Layout.interface' 3 | 4 | export const useLayoutQuery = () => { 5 | const { site }: LayoutQueryData = useStaticQuery(graphql` 6 | query SiteTitleQuery { 7 | site { 8 | siteMetadata { 9 | # change siteMetaData in 'gatsby-config.js' 10 | title 11 | footer { 12 | newsletter { 13 | text 14 | } 15 | } 16 | header { 17 | secondLevelHeaderMenuItems { 18 | type 19 | to 20 | bucketName 21 | text 22 | } 23 | } 24 | } 25 | } 26 | } 27 | `) 28 | 29 | return { site } 30 | } 31 | -------------------------------------------------------------------------------- /src/hooks/useWindowDimensions.ts: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react' 2 | 3 | function getWindowDimensions() { 4 | let width = 0 5 | let height = 0 6 | if (typeof window !== `undefined`) { 7 | width = window.innerWidth 8 | height = window.innerHeight 9 | } 10 | 11 | return { 12 | width, 13 | height, 14 | } 15 | } 16 | 17 | export default function useWindowDimensions() { 18 | const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions()) 19 | 20 | useEffect(() => { 21 | function handleResize() { 22 | setWindowDimensions(getWindowDimensions()) 23 | } 24 | 25 | window.addEventListener('resize', handleResize) 26 | return () => window.removeEventListener('resize', handleResize) 27 | }, []) 28 | 29 | return windowDimensions 30 | } 31 | -------------------------------------------------------------------------------- /src/html.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | 4 | export default function HTML(props) { 5 | return ( 6 | <html {...props.htmlAttributes}> 7 | <head> 8 | <meta charSet="utf-8" /> 9 | <meta httpEquiv="x-ua-compatible" content="ie=edge" /> 10 | {props.headComponents} 11 | </head> 12 | <body {...props.bodyAttributes}> 13 | {props.preBodyComponents} 14 | <div key={`body`} id="___gatsby" dangerouslySetInnerHTML={{ __html: props.body }} /> 15 | {props.postBodyComponents} 16 | </body> 17 | </html> 18 | ) 19 | } 20 | 21 | HTML.propTypes = { 22 | htmlAttributes: PropTypes.object, 23 | headComponents: PropTypes.array, 24 | bodyAttributes: PropTypes.object, 25 | preBodyComponents: PropTypes.array, 26 | body: PropTypes.string, 27 | postBodyComponents: PropTypes.array, 28 | } 29 | -------------------------------------------------------------------------------- /src/icons/ArrowDown.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default (props: any) => ( 4 | <svg 5 | width="8" 6 | height="6" 7 | viewBox="0 0 8 6" 8 | fill="none" 9 | xmlns="http://www.w3.org/2000/svg" 10 | {...props} 11 | > 12 | <path 13 | d="M7.27575 0.5C7.88863 0.5 8.22342 1.18191 7.83107 1.63107L4.74043 5.16916C4.3551 5.61028 3.6449 5.61028 3.25957 5.16916L0.168926 1.63107C-0.223425 1.18191 0.111375 0.5 0.724247 0.5L7.27575 0.5Z" 14 | fill="#A0AEC0" 15 | /> 16 | </svg> 17 | ) 18 | -------------------------------------------------------------------------------- /src/icons/ArrowEmail.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default (props: any) => ( 4 | <svg 5 | width="32" 6 | height="32" 7 | viewBox="0 0 32 32" 8 | fill="none" 9 | xmlns="http://www.w3.org/2000/svg" 10 | {...props} 11 | > 12 | <circle cx="16" cy="16" r="16" fill="#E2E8F0"> 13 | <title>Subscribe to Prisma newsletter 14 | 15 | 22 | 23 | ) 24 | -------------------------------------------------------------------------------- /src/icons/ArrowRight.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default (props: any) => ( 4 | 12 | 16 | 17 | ) 18 | -------------------------------------------------------------------------------- /src/icons/Clear.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default (props: any) => ( 4 | 12 | 19 | 20 | ) 21 | -------------------------------------------------------------------------------- /src/icons/Code.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default (props: any) => ( 4 | 12 | 19 | 25 | 32 | 33 | ) 34 | -------------------------------------------------------------------------------- /src/icons/Copy.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default (props: any) => ( 4 | 12 | 13 | 20 | 27 | 28 | ) 29 | -------------------------------------------------------------------------------- /src/icons/Database.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default (props: any) => ( 4 | 12 | 19 | 26 | 33 | 34 | ) 35 | -------------------------------------------------------------------------------- /src/icons/Display.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default (props: any) => ( 4 | 12 | 19 | 26 | 33 | 34 | ) 35 | -------------------------------------------------------------------------------- /src/icons/Down.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default () => ( 4 | 5 | 6 | This page was not helpful. 7 | 8 | 15 | 16 | ) 17 | -------------------------------------------------------------------------------- /src/icons/DownChevron.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default (props: any) => ( 4 | 5 | 12 | 13 | ) 14 | -------------------------------------------------------------------------------- /src/icons/Email.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default (props: any) => ( 4 | 12 | 19 | 26 | 27 | ) 28 | -------------------------------------------------------------------------------- /src/icons/ExternalLink.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default () => ( 4 | 5 | 12 | 19 | 26 | 27 | ) 28 | -------------------------------------------------------------------------------- /src/icons/Facebook.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default () => ( 4 | 5 | 12 | 13 | ) 14 | -------------------------------------------------------------------------------- /src/icons/File.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default (props: any) => ( 4 | 12 | 19 | 26 | 27 | ) 28 | -------------------------------------------------------------------------------- /src/icons/GitGrey.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default () => ( 4 | 5 | 12 | 13 | ) 14 | -------------------------------------------------------------------------------- /src/icons/HashLink.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default (props: any) => ( 4 | 12 | 19 | 26 | 33 | 40 | 41 | ) 42 | -------------------------------------------------------------------------------- /src/icons/Prisma.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default (props: any) => ( 4 | 12 | 19 | 20 | ) 21 | -------------------------------------------------------------------------------- /src/icons/PrismaLogoGrey.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default () => ( 4 | 5 | 11 | 12 | ) 13 | -------------------------------------------------------------------------------- /src/icons/RightChevron.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default (props: any) => ( 4 | 5 | 12 | 13 | ) 14 | -------------------------------------------------------------------------------- /src/icons/Search.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default (props: any) => ( 4 | 12 | 19 | 26 | 27 | ) 28 | -------------------------------------------------------------------------------- /src/icons/SearchSlash.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default (props: any) => ( 4 | 12 | 13 | 14 | 15 | ) 16 | -------------------------------------------------------------------------------- /src/icons/Slack.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default () => ( 4 | 5 | 12 | 19 | 26 | 33 | 40 | 47 | 54 | 61 | 62 | ) 63 | -------------------------------------------------------------------------------- /src/icons/Twitter.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default () => ( 4 | 5 | 12 | 13 | ) 14 | -------------------------------------------------------------------------------- /src/icons/Up.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default () => ( 4 | 5 | 6 | This page was helpful. 7 | 8 | 15 | 16 | ) 17 | -------------------------------------------------------------------------------- /src/icons/UpChevron.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default (props: any) => ( 4 | 5 | 12 | 13 | ) 14 | -------------------------------------------------------------------------------- /src/icons/Youtube.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default () => ( 4 | 5 | 12 | 19 | 20 | ) 21 | -------------------------------------------------------------------------------- /src/icons/home/CLI.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | export default () => ( 3 | 4 | 5 | 12 | 19 | 20 | ) 21 | -------------------------------------------------------------------------------- /src/icons/home/DbLink.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | export default () => ( 3 | 4 | 10 | 11 | 18 | 25 | 26 | ) 27 | -------------------------------------------------------------------------------- /src/icons/home/Schema.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | export default () => ( 3 | 4 | 5 | 12 | 19 | 26 | 33 | 40 | 41 | ) 42 | -------------------------------------------------------------------------------- /src/icons/technologies/Flow.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default () => ( 4 | 5 | 9 | 10 | 11 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | ) 28 | -------------------------------------------------------------------------------- /src/icons/technologies/JS.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default () => ( 4 | 5 | 9 | 13 | 17 | 21 | 22 | ) 23 | -------------------------------------------------------------------------------- /src/icons/technologies/MongoDB.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export default () => ( 4 | 5 | 6 | 7 | 11 | 15 | 19 | 20 | 28 | 29 | 30 | 31 | 32 | 33 | ) 34 | -------------------------------------------------------------------------------- /src/icons/technologies/NodeJS.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export const NodeJS = () => ( 4 | 5 | 6 | 11 | 12 | ) 13 | -------------------------------------------------------------------------------- /src/icons/technologies/Typescript.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | export const Typescript = () => ( 4 | 5 | 6 | 13 | 14 | ) 15 | -------------------------------------------------------------------------------- /src/images/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/src/images/favicon-16x16.png -------------------------------------------------------------------------------- /src/images/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/src/images/favicon-32x32.png -------------------------------------------------------------------------------- /src/images/list-dot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/src/images/list-dot.png -------------------------------------------------------------------------------- /src/interfaces/AllArticles.interface.ts: -------------------------------------------------------------------------------- 1 | import { EdgeNode } from './EdgeNode.interface' 2 | 3 | export interface AllEdges { 4 | edges?: [EdgeNode] | EdgeNode[] 5 | } 6 | 7 | export interface AllArticles { 8 | allMdx: AllEdges 9 | } 10 | export interface AllArticlesQueryData { 11 | data: AllArticles 12 | } 13 | -------------------------------------------------------------------------------- /src/interfaces/Article.interface.ts: -------------------------------------------------------------------------------- 1 | export interface ArticleFields { 2 | slug: string 3 | modSlug: string 4 | } 5 | 6 | export interface ArticleFrontmatter { 7 | title: string 8 | navTitle?: string 9 | metaTitle?: string 10 | metaDescription?: string 11 | langSwitcher?: string[] 12 | dbSwitcher?: string[] 13 | staticLink?: boolean 14 | duration?: string 15 | experimental?: boolean 16 | preview?: boolean 17 | earlyaccess?: boolean 18 | toc?: boolean 19 | hidePage?: boolean 20 | tocDepth?: number 21 | codeStyle?: boolean 22 | } 23 | 24 | export interface ArticleData { 25 | mdx: { 26 | fields: ArticleFields 27 | tableOfContents: TableOfContents 28 | body: string 29 | parent: any 30 | frontmatter: ArticleFrontmatter 31 | } 32 | site: { 33 | siteMetadata: { 34 | docsLocation: string 35 | } 36 | } 37 | } 38 | 39 | export interface ArticleQueryData { 40 | data: ArticleData 41 | } 42 | 43 | export interface Fields { 44 | fields: ArticleFields 45 | } 46 | 47 | export interface TableOfContents { 48 | items: { 49 | url: string 50 | title: string 51 | items?: any[] 52 | }[] 53 | } 54 | -------------------------------------------------------------------------------- /src/interfaces/EdgeNode.interface.ts: -------------------------------------------------------------------------------- 1 | import { ArticleFrontmatter } from './Article.interface' 2 | import { ArticleFields } from './Article.interface' 3 | 4 | export interface EdgeNode { 5 | node: { 6 | frontmatter: { [Property in keyof ArticleFrontmatter]: ArticleFrontmatter[Property] } 7 | fields: { [Property in keyof ArticleFields]: ArticleFields[Property] } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/interfaces/Layout.interface.ts: -------------------------------------------------------------------------------- 1 | export interface HeaderProps { 2 | secondLevelHeaderMenuItems: { text: string; type: string; to: string; bucketName: string }[] 3 | } 4 | 5 | export interface FooterProps { 6 | newsletter: { text: string } 7 | } 8 | 9 | interface SiteMeta { 10 | siteMetadata: { 11 | header: HeaderProps 12 | title: string 13 | footer: FooterProps 14 | } 15 | } 16 | 17 | export interface LayoutQueryData { 18 | site: SiteMeta 19 | } 20 | 21 | export interface CreatePageContext { 22 | pageContext: { 23 | seoTitle: string 24 | seoDescription: string 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/layouts/articleLayout.tsx: -------------------------------------------------------------------------------- 1 | import { RouterProps } from '@reach/router' 2 | import * as React from 'react' 3 | import { ArticleQueryData } from '../interfaces/Article.interface' 4 | import Layout from '../components/layout' 5 | import TopSection from '../components/topSection' 6 | import PageBottom from '../components/pageBottom' 7 | import SEO from '../components/seo' 8 | import { graphql } from 'gatsby' 9 | import MDXRenderer from 'gatsby-plugin-mdx/mdx-renderer' 10 | import { useNavigate } from '@reach/router' 11 | import { CreatePageContext } from 'src/interfaces/Layout.interface' 12 | 13 | type ArticleLayoutProps = ArticleQueryData & RouterProps & CreatePageContext 14 | 15 | const ArticleLayout = ({ 16 | data, 17 | pageContext: { seoTitle, seoDescription }, 18 | ...props 19 | }: ArticleLayoutProps) => { 20 | if (!data) { 21 | return null 22 | } 23 | const { 24 | mdx: { 25 | fields: { slug, modSlug }, 26 | frontmatter: { title, langSwitcher, dbSwitcher, toc, tocDepth, codeStyle }, 27 | body, 28 | parent, 29 | tableOfContents, 30 | }, 31 | site: { 32 | siteMetadata: { docsLocation }, 33 | }, 34 | } = data 35 | const navigate = useNavigate() 36 | return ( 37 | 43 | 44 |
45 | 54 |
55 | {body} 56 | 57 |
58 | ) 59 | } 60 | 61 | export default ArticleLayout 62 | 63 | export const query = graphql` 64 | query ($id: String!) { 65 | site { 66 | siteMetadata { 67 | docsLocation 68 | } 69 | } 70 | mdx(fields: { id: { eq: $id } }) { 71 | fields { 72 | slug 73 | modSlug 74 | } 75 | body 76 | parent { 77 | ... on File { 78 | relativePath 79 | } 80 | } 81 | tableOfContents 82 | frontmatter { 83 | title 84 | metaTitle 85 | metaDescription 86 | langSwitcher 87 | dbSwitcher 88 | toc 89 | tocDepth 90 | codeStyle 91 | } 92 | } 93 | } 94 | ` 95 | -------------------------------------------------------------------------------- /src/pages/404.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import Layout from '../components/layout' 3 | import styled from 'styled-components' 4 | 5 | const NotFoundWrapper = styled.div` 6 | font-family: 'Inter'; 7 | margin-top: 200px; 8 | padding: ${(p) => p.theme.space[40]}; 9 | display: flex; 10 | flex-direction: column; 11 | align-items: center; 12 | h1 { 13 | font-weight: bold; 14 | } 15 | ` 16 | 17 | const NotFoundPage = () => ( 18 | 19 | 20 |

404 | NOT FOUND

21 | You just hit a route that doesn't exist! 22 |
23 |
24 | ) 25 | 26 | export default NotFoundPage 27 | -------------------------------------------------------------------------------- /src/utils/goToNavItem.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | goToNav(pathname) { 3 | var currentElem = document.getElementById(pathname.replace(/\/$/, '')) 4 | const sidebarElem = document.getElementById('sidebar-holder') 5 | if (currentElem && sidebarElem) { 6 | var topPos = currentElem.getBoundingClientRect().top - 250 7 | sidebarElem.scrollTo(0, topPos) 8 | } 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/parentTitle.ts: -------------------------------------------------------------------------------- 1 | import { urlGenerator } from './urlGenerator' 2 | 3 | export const getParentTitle = (slug: string, allMdx?: any) => { 4 | const allContent = 5 | allMdx && 6 | allMdx.edges && 7 | allMdx.edges.map((mdx: any) => ({ 8 | ...mdx.node.fields, 9 | title: mdx.node.frontmatter.title, 10 | staticLink: mdx.node.frontmatter.staticLink, 11 | codeStyle: mdx.node.frontmatter.codeStyle, 12 | })) 13 | allContent?.map((content: any) => { 14 | content.parentTitle = [] 15 | const parts = content.slug.split('/') 16 | const slicedParts = parts.slice( 17 | 1, 18 | parts[parts.length - 1] === 'index' ? parts.length - 2 : parts.length - 1 19 | ) 20 | slicedParts.forEach((part: any) => { 21 | const parent = allContent.find((ac: any) => { 22 | const parentParts = ac.slug.split('/') 23 | return ( 24 | parentParts[parentParts.length - 1] === 'index' && 25 | parentParts[parentParts.length - 2] === part 26 | ) 27 | }) 28 | if (parent) { 29 | // const parts = parent.slug.split('/') 30 | // const topLevel = parts.length == 3 && parts[parts.length - 1] === 'index' ? true : false 31 | content.parentTitle.push({ 32 | title: parent?.title, 33 | codeStyle: parent?.codeStyle, 34 | link: urlGenerator(parent.modSlug), 35 | // link: topLevel || parent.staticLink ? null : urlGenerator(parent.modSlug), 36 | }) 37 | } 38 | }) 39 | }) 40 | const currentSlug = allContent.find((mdx: any) => mdx.modSlug === slug) 41 | return currentSlug ? currentSlug.parentTitle : [] 42 | } 43 | -------------------------------------------------------------------------------- /src/utils/stats.js: -------------------------------------------------------------------------------- 1 | const ReactGA = require('react-ga') 2 | 3 | const GA_TRACKING_ID = 'UA-74131346-14' 4 | const GA_ADDRESS = 'https://www.prisma.io/gastats.js' 5 | const COLLECT_ADDRESS = 'https://stats.prisma.workers.dev' 6 | 7 | module.exports = { 8 | init() { 9 | ReactGA.initialize(GA_TRACKING_ID, { 10 | gaAddress: GA_ADDRESS, 11 | }) 12 | 13 | const ga = ReactGA.ga() 14 | ga('set', 'anonymizeIp', true) 15 | ga((u) => { 16 | // Override sendHitTask to proxy tracking requests 17 | u.set('sendHitTask', (model) => { 18 | const xhr = new XMLHttpRequest() 19 | xhr.open('POST', COLLECT_ADDRESS, true) 20 | xhr.send(model.get('hitPayload')) 21 | }) 22 | }) 23 | }, 24 | 25 | trackPage(page) { 26 | const { host } = window.location 27 | 28 | if (host.includes('netlify') || host.includes('localhost')) { 29 | return // exclude netlify previews from analytics 30 | } 31 | ReactGA.pageview(page) 32 | }, 33 | } 34 | -------------------------------------------------------------------------------- /src/utils/stringify.ts: -------------------------------------------------------------------------------- 1 | export function stringify(children: any): string { 2 | if (typeof children === 'string') { 3 | return children 4 | } 5 | 6 | if (typeof children === 'undefined') { 7 | return '' 8 | } 9 | 10 | if (children === null) { 11 | return '' 12 | } 13 | 14 | if (children.props && children.props.children) { 15 | children = children.props.children 16 | } 17 | if (children.props && children.props.children) { 18 | children = children.props.children 19 | } 20 | 21 | /** 22 | * Necessary because now the pointer changed!!!! 23 | */ 24 | if (typeof children === 'string') { 25 | return children 26 | } 27 | 28 | if (Array.isArray(children)) { 29 | return children 30 | .map((el) => { 31 | if (typeof el === 'string') { 32 | return el 33 | } else { 34 | return stringify(el) 35 | } 36 | }) 37 | .join('') 38 | } 39 | 40 | return '' 41 | } 42 | -------------------------------------------------------------------------------- /src/utils/urlGenerator.ts: -------------------------------------------------------------------------------- 1 | export const urlGenerator = (path: string) => { 2 | return path.replace(/\d{2,}-/g, '') 3 | } 4 | -------------------------------------------------------------------------------- /static/social/docs-social.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuergaosi233/docs/eee16132ee9b4f55a5d6c4a9101fb7e4e5205c03/static/social/docs-social.png -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "target": "es6", 5 | "module": "commonjs", 6 | "lib": ["dom", "es6", "es2017", "esnext.asynciterable"], 7 | "sourceMap": true, 8 | "outDir": "./dist", 9 | "jsx": "react", 10 | "moduleResolution": "node", 11 | "removeComments": true, 12 | "noImplicitAny": true, 13 | "strictNullChecks": true, 14 | "strictFunctionTypes": true, 15 | "noImplicitThis": true, 16 | "noUnusedLocals": true, 17 | "noUnusedParameters": true, 18 | "noImplicitReturns": true, 19 | "noFallthroughCasesInSwitch": true, 20 | "allowSyntheticDefaultImports": false, 21 | "skipLibCheck": true, 22 | "baseUrl": "." 23 | }, 24 | "exclude": ["node_modules"], 25 | "include": [ 26 | "./src/**/*.tsx", 27 | "./src/**/*.ts", 28 | "./images.d.ts", 29 | "src/layouts/articleLayout.js", 30 | "src/layouts/articleLayout.jsx", 31 | "src/pages/404.jsx", 32 | "src/pages/404.js" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": ["tslint:recommended"], 4 | "jsRules": {}, 5 | "rules": { 6 | "no-console": false, 7 | "member-access": false, 8 | "object-literal-sort-keys": false, 9 | "ordered-imports": false, 10 | "interface-name": false, 11 | "no-submodule-imports": false, 12 | "quotemark": [true, "single", "jsx-double"], 13 | "arrow-parens": false 14 | }, 15 | "rulesDirectory": [] 16 | } 17 | --------------------------------------------------------------------------------