Skip to main content
Glama

Prisma MCP Server

Official
by prisma
Apache 2.0
4
44,213
  • Linux
  • Apple
validate.test.ts16.5 kB
import { stripVTControlCharacters } from 'node:util' import { serialize } from '@prisma/get-platform/src/test-utils/jestSnapshotSerializer' import path from 'path' import { isRustPanic, validate } from '../..' import { getSchemaWithPath } from '../../cli/getSchema' import type { MultipleSchemas, SchemaFileInput } from '../../utils/schemaFileInput' import { fixturesPath } from '../__utils__/fixtures' jest.setTimeout(10_000) function restoreEnvSnapshot(snapshot: NodeJS.ProcessEnv) { for (const key of Object.keys(process.env)) { if (!(key in snapshot)) { delete process.env[key] } } for (const [key, value] of Object.entries(snapshot)) { if (value === undefined) { delete process.env[key] } else { process.env[key] = value } } } if (process.env.CI) { // 10s is not always enough for the "big schema" test on macOS CI. jest.setTimeout(60_000) } describe('validate', () => { // Note: to run these tests locally, prepend the env vars `FORCE_COLOR=0` and `CI=1` to your test command, // as `chalk` follows different conventions than the Rust `colored` crate (and uses `FORCE_COLOR=0` to disable colors rather than `NO_COLOR=1`). describe.skip('colors', () => { // backup env vars const OLD_ENV = { ...process.env } beforeEach(() => { // jest.resetModules() restoreEnvSnapshot(OLD_ENV) delete process.env.NO_COLOR process.env.FORCE_COLOR = '0' process.env.CI = '1' }) afterEach(() => { // reset env vars to backup state restoreEnvSnapshot(OLD_ENV) }) test('failures should have colors by default', () => { expect.assertions(1) const schema = ` datasource db { ` const schemas: MultipleSchemas = [['/* schemaPath */', schema]] try { validate({ schemas }) } catch (e) { expect(e.message).toMatchInlineSnapshot(` "Prisma schema validation - (validate wasm) Error code: P1012 error: Error validating: This line is invalid. It does not start with any known Prisma schema keyword. --> schema.prisma:2  |   1 |   2 |  datasource db {  3 |   |  Validation Error Count: 1 [Context: validate] Prisma CLI Version : 0.0.0" `) } }) // Note(jkomyno): this fails locally because the colored crate used in Wasm forces the coloring on tty (but apparently not on CI?). // On standard terminals, the NO_COLOR env var is actually working as expected (it prints plain uncolored text). // See: https://github.com/prisma/prisma-private/issues/210 test('failures should not have colors when the NO_COLOR env var is set', () => { process.env.NO_COLOR = '1' expect.assertions(1) const schema = ` datasource db { ` const schemas: MultipleSchemas = [['/* schemaPath */', schema]] try { validate({ schemas }) } catch (e) { expect(e.message).toMatchInlineSnapshot(` "Prisma schema validation - (validate wasm) Error code: P1012 error: Error validating: This line is invalid. It does not start with any known Prisma schema keyword. --> schema.prisma:2 | 1 | 2 | datasource db { 3 | | Validation Error Count: 1 [Context: validate] Prisma CLI Version : 0.0.0" `) } }) }) describe('errors', () => { describe('single file', () => { test('model with autoincrement should fail if sqlite', () => { expect.assertions(1) const schema = ` datasource db { provider = "sqlite" url = "file:dev.db" } model User { id Int @default(autoincrement()) email String @unique @@map("users") }` const schemas: MultipleSchemas = [['schema.prisma', schema]] try { validate({ schemas }) } catch (e) { expect(stripVTControlCharacters(e.message)).toMatchInlineSnapshot(` "Prisma schema validation - (validate wasm) Error code: P1012 error: Error parsing attribute "@default": The \`autoincrement()\` default value is used on a non-id field even though the datasource does not support this. --> schema.prisma:7 | 6 | model User { 7 | id Int @default(autoincrement()) 8 | email String @unique | error: Error parsing attribute "@default": The \`autoincrement()\` default value is used on a non-indexed field even though the datasource does not support this. --> schema.prisma:7 | 6 | model User { 7 | id Int @default(autoincrement()) 8 | email String @unique | Validation Error Count: 2 [Context: validate] Prisma CLI Version : 0.0.0" `) } }) test('model with autoincrement should fail if mysql', () => { expect.assertions(1) const schema = ` datasource db { provider = "mysql" url = env("MY_MYSQL_DB") } model User { id Int @default(autoincrement()) email String @unique @@map("users") }` const schemas: MultipleSchemas = [['schema.prisma', schema]] try { validate({ schemas }) } catch (e) { expect(stripVTControlCharacters(e.message)).toMatchInlineSnapshot(` "Prisma schema validation - (validate wasm) Error code: P1012 error: Error parsing attribute "@default": The \`autoincrement()\` default value is used on a non-indexed field even though the datasource does not support this. --> schema.prisma:7 | 6 | model User { 7 | id Int @default(autoincrement()) 8 | email String @unique | Validation Error Count: 1 [Context: validate] Prisma CLI Version : 0.0.0" `) } }) test(`throws an error when the given datamodel is of the wrong type`, () => { expect.assertions(2) try { // @ts-expect-error validate({ schemas: [[true, true]] }) } catch (e) { expect(isRustPanic(e)).toBe(true) expect(serialize(e.message)).toMatchInlineSnapshot(` ""RuntimeError: panicked at prisma-fmt/src/validate.rs:0:0: Failed to deserialize ValidateParams: data did not match any variant of untagged enum SchemaFileInput at line 1 column 29"" `) } }) test('validation errors', () => { expect.assertions(1) const schema = `generator client { provider = "prisma-client-js" } datasource my_db { provider = "sqlite" url = "file:dev.db" } model User { id String @id @default(cuid()) id String @id @default(cuid()) name String email String @unique status String @default("") permissions Permission @default() permissions Permission @default("") posts Post[] posts Post[] } model Post { id String @id @default(cuid()) name String email String @unique createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } enum Permission { ADMIN USER OWNER COLLABORATOR } ` const schemas: MultipleSchemas = [['schema.prisma', schema]] try { validate({ schemas }) } catch (e) { expect(stripVTControlCharacters(e.message)).toMatchInlineSnapshot(` "Prisma schema validation - (validate wasm) Error code: P1012 error: Field "id" is already defined on model "User". --> schema.prisma:12 | 11 | id String @id @default(cuid()) 12 | id String @id @default(cuid()) | error: Field "permissions" is already defined on model "User". --> schema.prisma:17 | 16 | permissions Permission @default() 17 | permissions Permission @default("") | error: Field "posts" is already defined on model "User". --> schema.prisma:19 | 18 | posts Post[] 19 | posts Post[] | error: Error validating model "User": At most one field must be marked as the id field with the \`@id\` attribute. --> schema.prisma:10 | 9 | 10 | model User { 11 | id String @id @default(cuid()) 12 | id String @id @default(cuid()) 13 | name String 14 | email String @unique 15 | status String @default("") 16 | permissions Permission @default() 17 | permissions Permission @default("") 18 | posts Post[] 19 | posts Post[] 20 | } | error: Argument "value" is missing. --> schema.prisma:16 | 15 | status String @default("") 16 | permissions Permission @default() | error: Error parsing attribute "@default": Expected an enum value, but found \`""\`. --> schema.prisma:17 | 16 | permissions Permission @default() 17 | permissions Permission @default("") | Validation Error Count: 6 [Context: validate] Prisma CLI Version : 0.0.0" `) } }) }) describe('multiple files', () => { test(`panics when the given datamodel isn't an array of string tuples`, () => { expect.assertions(3) try { // @ts-expect-error validate({ schemas: [['schema.prisma', true]] }) } catch (e) { expect(isRustPanic(e)).toBe(true) expect(serialize(e.message)).toMatchInlineSnapshot(` ""RuntimeError: panicked at prisma-fmt/src/validate.rs:0:0: Failed to deserialize ValidateParams: data did not match any variant of untagged enum SchemaFileInput at line 1 column 40"" `) expect(e.rustStack).toBeTruthy() } }) test('validation errors', () => { expect.assertions(1) const datamodel1 = /* prisma */ ` generator client { provider = "prisma-client-js" } datasource my_db { provider = "sqlite" url = "file:dev.db" } model User { id String @id @default(cuid()) id String @id @default(cuid()) name String email String @unique status String @default("") permissions Permission @default() permissions Permission @default("") posts Post[] posts Post[] } ` const datamodel2 = /* prisma */ ` model Post { id String @id @default(cuid()) name String email String @unique createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } enum Permission { ADMIN USER OWNER COLLABORATOR } ` const datamodel: SchemaFileInput = [ ['schema.prisma', datamodel1], ['schema2.prisma', datamodel2], ] try { validate({ schemas: datamodel }) } catch (e) { // TODO: patch engines to fix this message, it should group errors by the different filenames. expect(stripVTControlCharacters(e.message)).toMatchInlineSnapshot(` "Prisma schema validation - (validate wasm) Error code: P1012 error: Field "id" is already defined on model "User". --> schema.prisma:13 | 12 | id String @id @default(cuid()) 13 | id String @id @default(cuid()) | error: Field "permissions" is already defined on model "User". --> schema.prisma:18 | 17 | permissions Permission @default() 18 | permissions Permission @default("") | error: Field "posts" is already defined on model "User". --> schema.prisma:20 | 19 | posts Post[] 20 | posts Post[] | error: Error validating model "User": At most one field must be marked as the id field with the \`@id\` attribute. --> schema.prisma:11 | 10 | 11 | model User { 12 | id String @id @default(cuid()) 13 | id String @id @default(cuid()) 14 | name String 15 | email String @unique 16 | status String @default("") 17 | permissions Permission @default() 18 | permissions Permission @default("") 19 | posts Post[] 20 | posts Post[] 21 | } | error: Argument "value" is missing. --> schema.prisma:17 | 16 | status String @default("") 17 | permissions Permission @default() | error: Error parsing attribute "@default": Expected an enum value, but found \`""\`. --> schema.prisma:18 | 17 | permissions Permission @default() 18 | permissions Permission @default("") | Validation Error Count: 6 [Context: validate] Prisma CLI Version : 0.0.0" `) } }) }) }) describe('success', () => { test('simple model, no datasource', () => { const schema /* prisma */ = `model A { id Int @id name String }` const schemas: MultipleSchemas = [['schema.prisma', schema]] validate({ schemas }) }) test('simple model, sqlite', () => { const schema /* prisma */ = `datasource db { provider = "sqlite" url = "file:dev.db" } model A { id Int @id name String }` const schemas: MultipleSchemas = [['schema.prisma', schema]] validate({ schemas }) }) test('chinook introspected schema', async () => { const { schemas } = await getSchemaWithPath(path.join(fixturesPath, 'chinook.prisma')) validate({ schemas }) }) test('odoo introspected schema', async () => { const { schemas } = await getSchemaWithPath(path.join(fixturesPath, 'odoo.prisma')) validate({ schemas }) }) }) })

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/prisma/prisma'

If you have feedback or need assistance with the MCP directory API, please join our Discord server