Skip to main content
Glama

Prisma MCP Server

Official
by prisma
Apache 2.0
4
44,192
  • Linux
  • Apple
loadConfigFromFile.ts8.91 kB
import path from 'node:path' import process from 'node:process' import { Debug } from '@prisma/driver-adapter-utils' import { defaultConfig } from './defaultConfig' import type { PrismaConfigInternal } from './defineConfig' import { loadConfigFromPackageJson } from './loadConfigFromPackageJson' import { parseDefaultExport } from './PrismaConfig' const debug = Debug('prisma:config:loadConfigFromFile') // Note: as of c12@3.1.0, config extensions are tried in the following order, regardless of how we pass them // to `jiti` or to `jitiOptions.extensions`. // See: https://github.com/unjs/c12/blob/1efbcbce0e094a8f8a0ba676324affbef4a0ba8b/src/loader.ts#L35-L42 export const SUPPORTED_EXTENSIONS = ['.js', '.ts', '.mjs', '.cjs', '.mts', '.cts'] as const satisfies string[] type LoadConfigFromFileInput = { /** * The path to the config file to load. If not provided, we will attempt to find a config file in the `configRoot` directory. */ configFile?: string /** * The directory to search for the config file in. Defaults to the current working directory. */ configRoot?: string } export type LoadConfigFromFileError = | { /** * The config file was not found at the specified path. */ _tag: 'ConfigFileNotFound' } | { _tag: 'ConfigLoadError' error: Error } | { _tag: 'ConfigFileSyntaxError' error: Error } | { _tag: 'UnknownError' error: Error } export type InjectFormatters = { dim: (data: string) => string log: (data: string) => void warn: (data: string) => void link: (data: string) => string } export type ConfigDiagnostic = | { _tag: 'log' value: (formatters: InjectFormatters) => () => void } | { _tag: 'warn' value: (formatters: InjectFormatters) => () => void } export type ConfigFromFile = | { resolvedPath: string config: PrismaConfigInternal error?: never diagnostics: ConfigDiagnostic[] } | { resolvedPath: string config?: never error: LoadConfigFromFileError diagnostics: ConfigDiagnostic[] } | { resolvedPath: null config: PrismaConfigInternal error?: never diagnostics: ConfigDiagnostic[] } /** * Load a Prisma config file from the given directory. * This function may fail, but it will never throw. * The possible error is returned in the result object, so the caller can handle it as needed. */ export async function loadConfigFromFile({ configFile, configRoot = process.cwd(), }: LoadConfigFromFileInput): Promise<ConfigFromFile> { const start = performance.now() const getTime = () => `${(performance.now() - start).toFixed(2)}ms` const diagnostics = [] as ConfigDiagnostic[] const deprecatedPrismaConfigFromJson = await loadConfigFromPackageJson(configRoot) if (deprecatedPrismaConfigFromJson) { diagnostics.push({ _tag: 'warn', value: ({ warn, link }) => () => warn( `The configuration property \`package.json#prisma\` is deprecated and will be removed in Prisma 7. Please migrate to a Prisma config file (e.g., \`prisma.config.ts\`). For more information, see: ${link('https://pris.ly/prisma-config')}\n`, ), } as const) } try { const { configModule, resolvedPath, error } = await loadConfigTsOrJs(configRoot, configFile) if (error) { return { resolvedPath, error, diagnostics, } } debug(`Config file loaded in %s`, getTime()) if (resolvedPath === null) { debug(`No config file found in the current working directory %s`, configRoot) return { resolvedPath: null, config: defaultConfig(), diagnostics } } let parsedConfig: PrismaConfigInternal | undefined try { parsedConfig = parseDefaultExport(configModule) } catch (e) { const error = e as Error return { resolvedPath, error: { _tag: 'ConfigFileSyntaxError', error, }, diagnostics, } } // Note: this line fixes https://github.com/prisma/prisma/issues/27609. diagnostics.push({ _tag: 'log', value: ({ log, dim }) => () => log(dim(`Loaded Prisma config from ${path.relative(configRoot, resolvedPath)}.\n`)), }) const prismaConfig = transformPathsInConfigToAbsolute(parsedConfig, resolvedPath) if (deprecatedPrismaConfigFromJson) { diagnostics.push({ _tag: 'warn', value: ({ warn, link }) => () => warn(`The Prisma config file in ${path.relative( configRoot, resolvedPath, )} overrides the deprecated \`package.json#prisma\` property in ${path.relative( configRoot, deprecatedPrismaConfigFromJson.loadedFromFile, )}. For more information, see: ${link('https://pris.ly/prisma-config')}\n`), }) } return { config: { ...prismaConfig, loadedFromFile: resolvedPath, }, resolvedPath, diagnostics, } } catch (e) { // As far as we know, this branch should be unreachable. const error = e as Error return { resolvedPath: configRoot, error: { _tag: 'UnknownError', error, }, diagnostics, } } } async function loadConfigTsOrJs(configRoot: string, configFile: string | undefined) { const { loadConfig: loadConfigWithC12 } = await import('c12') const { deepmerge } = await import('deepmerge-ts') try { const { config, configFile: _resolvedPath, meta, } = await loadConfigWithC12({ cwd: configRoot, // configuration base name name: 'prisma', // the config file to load (without file extensions), defaulting to `${cwd}.${name}` configFile, // do not load .env files dotenv: false, // do not load RC config rcFile: false, // do not extend remote config files giget: false, // do not extend the default config extend: false, // do not load from nearest package.json packageJson: false, // @ts-expect-error: this is a type-error in `c12` itself merger: deepmerge, jitiOptions: { interopDefault: true, moduleCache: false, extensions: SUPPORTED_EXTENSIONS, }, }) // Note: c12 apparently doesn't normalize paths on Windows, causing issues with Windows tests. const resolvedPath = _resolvedPath ? path.normalize(_resolvedPath) : undefined const doesConfigFileExist = resolvedPath !== undefined && meta !== undefined if (configFile && !doesConfigFileExist) { debug(`The given config file was not found at %s`, resolvedPath) return { require: null, resolvedPath: path.join(configRoot, configFile), error: { _tag: 'ConfigFileNotFound' } as const, } as const } if (doesConfigFileExist) { const extension = path.extname(path.basename(resolvedPath)) if (!(SUPPORTED_EXTENSIONS as string[]).includes(extension)) { return { configModule: config, resolvedPath, error: { _tag: 'ConfigLoadError', error: new Error(`Unsupported Prisma config file extension: ${extension}`), } as const, } as const } } return { configModule: config, resolvedPath: doesConfigFileExist ? resolvedPath : null, error: null, } as const } catch (e) { const error = e as Error debug('jiti import failed: %s', error.message) // Extract the location of config file that couldn't be read from jiti's wrapped BABEL_PARSE_ERROR message. const configFileMatch = error.message.match(/prisma\.config\.(\w+)/) const extension = configFileMatch?.[1] const filenameWithExtension = path.join(configRoot, extension ? `prisma.config.${extension}` : '') debug('faulty config file: %s', filenameWithExtension) return { error: { _tag: 'ConfigLoadError', error, } as const, resolvedPath: filenameWithExtension, } as const } } function transformPathsInConfigToAbsolute( prismaConfig: PrismaConfigInternal, resolvedPath: string, ): PrismaConfigInternal { function resolvePath(value: string | undefined) { if (!value) { return undefined } return path.resolve(path.dirname(resolvedPath), value) } return { ...prismaConfig, schema: resolvePath(prismaConfig.schema), migrations: { ...prismaConfig.migrations, path: resolvePath(prismaConfig.migrations?.path), }, typedSql: { ...prismaConfig.typedSql, path: resolvePath(prismaConfig.typedSql?.path), }, views: { ...prismaConfig.views, path: resolvePath(prismaConfig.views?.path), }, } }

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