ClientFile.ts•4.04 kB
import path from 'node:path'
import { BinaryTarget, ClientEngineType, getClientEngineType } from '@prisma/internals'
import * as ts from '@prisma/ts-builders'
import { ModuleFormat } from '../../module-format'
import { buildNFTAnnotations } from '../../utils/buildNFTAnnotations'
import { GenerateContext } from '../GenerateContext'
import { modelExports } from '../ModelExports'
import { getPrismaClientClassDocComment } from '../PrismaClient'
import { TSClientOptions } from '../TSClient'
const jsDocHeader = `/*
* This file should be your main import to use Prisma. Through it you get access to all the models, enums, and input types.
* If you're looking for something you can import in the client-side of your application, please refer to the \`browser.ts\` file instead.
*
* 🟢 You can import this file directly.
*/
`
export function createClientFile(context: GenerateContext, options: TSClientOptions): string {
const clientEngineType = getClientEngineType(options.generator)
options.generator.config.engineType = clientEngineType
const imports = [
ts.moduleImport(context.runtimeImport).asNamespace('runtime'),
ts.moduleImport(context.importFileName('./enums')).asNamespace('$Enums'),
ts.moduleImport(context.importFileName('./internal/class')).asNamespace('$Class'),
ts.moduleImport(context.importFileName('./internal/prismaNamespace')).asNamespace('Prisma'),
].map((i) => ts.stringify(i))
const exports = [
ts.moduleExportFrom(context.importFileName('./enums')).asNamespace('$Enums'),
ts.moduleExportFrom(context.importFileName('./enums')),
ts
.moduleExport(
ts
.constDeclaration('PrismaClient')
.setValue(ts.functionCall('$Class.getPrismaClientClass', [ts.namedValue('__dirname')])),
)
.setDocComment(getPrismaClientClassDocComment(context)),
ts.moduleExport(
ts
.typeDeclaration(
'PrismaClient',
ts
.namedType('$Class.PrismaClient')
.addGenericArgument(ts.namedType('LogOpts'))
.addGenericArgument(ts.namedType('OmitOpts'))
.addGenericArgument(ts.namedType('ExtArgs')),
)
.addGenericParameter(
ts.genericParameter('LogOpts').extends(ts.namedType('Prisma.LogLevel')).default(ts.neverType),
)
.addGenericParameter(
ts
.genericParameter('OmitOpts')
.extends(ts.namedType('Prisma.PrismaClientOptions').subKey('omit'))
.default(ts.namedType('Prisma.PrismaClientOptions').subKey('omit')),
)
.addGenericParameter(
ts
.genericParameter('ExtArgs')
.extends(ts.namedType('runtime.Types.Extensions.InternalArgs'))
.default(ts.namedType('runtime.Types.Extensions.DefaultArgs')),
),
),
].map((e) => ts.stringify(e))
const binaryTargets =
clientEngineType === ClientEngineType.Library
? (Object.keys(options.binaryPaths.libqueryEngine ?? {}) as BinaryTarget[])
: (Object.keys(options.binaryPaths.queryEngine ?? {}) as BinaryTarget[])
// get relative output dir for it to be preserved even after bundling, or
// being moved around as long as we keep the same project dir structure.
const relativeOutdir = path.relative(process.cwd(), options.outputDir)
return `${jsDocHeader}
${buildPreamble(options.edge, options.moduleFormat)}
${imports.join('\n')}
${exports.join('\n')}
export { Prisma }
${buildNFTAnnotations(options.edge || !options.copyEngine, clientEngineType, binaryTargets, relativeOutdir)}
${modelExports(context).join('\n')}
`
}
function buildPreamble(edge: boolean, moduleFormat: ModuleFormat): string {
if (edge) {
return `\
globalThis['__dirname'] = '/'
`
}
let preamble = `\
import * as process from 'node:process'
import * as path from 'node:path'
`
if (moduleFormat === 'esm') {
preamble += `\
import { fileURLToPath } from 'node:url'
globalThis['__dirname'] = path.dirname(fileURLToPath(import.meta.url))
`
}
return preamble
}