UNPKG

zenstack

Version:

FullStack enhancement for Prisma ORM: seamless integration from database to UI

147 lines 8 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.description = exports.name = void 0; exports.trackPrismaSchemaError = trackPrismaSchemaError; const sdk_1 = require("@zenstackhq/sdk"); const ast_1 = require("@zenstackhq/sdk/ast"); const prisma_1 = require("@zenstackhq/sdk/prisma"); const colors_1 = __importDefault(require("colors")); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const strip_color_1 = __importDefault(require("strip-color")); const telemetry_1 = __importDefault(require("../../telemetry")); const exec_utils_1 = require("../../utils/exec-utils"); const pkg_utils_1 = require("../../utils/pkg-utils"); const schema_generator_1 = require("./schema-generator"); exports.name = 'Prisma'; exports.description = 'Generating Prisma schema'; const run = (model, options, _dmmf, _globalOptions) => __awaiter(void 0, void 0, void 0, function* () { // deal with calculation of the default output location const output = options.output ? (0, sdk_1.resolvePath)(options.output, options) : getDefaultPrismaOutputFile(options.schemaPath); const mergedOptions = Object.assign(Object.assign({}, options), { output }); const { warnings, shortNameMap } = yield new schema_generator_1.PrismaSchemaGenerator(model).generate(mergedOptions); // the path to import the prisma client from let prismaClientPath = '@prisma/client'; // the real path where the prisma client was generated let clientOutputDir = '.prisma/client'; // the path to the prisma client dts file let prismaClientDtsPath = undefined; if (options.generateClient !== false) { let generateCmd = `prisma generate --schema "${output}"`; if (typeof options.generateArgs === 'string') { generateCmd += ` ${options.generateArgs}`; } try { // run 'prisma generate' yield (0, exec_utils_1.execPackage)(generateCmd, { stdio: 'ignore' }); } catch (_a) { yield trackPrismaSchemaError(output); try { // run 'prisma generate' again with output to the console yield (0, exec_utils_1.execPackage)(generateCmd); } catch (_b) { // noop } throw new sdk_1.PluginError(exports.name, `Failed to run "prisma generate"`); } // extract user-provided prisma client output path const generator = model.declarations.find((d) => (0, ast_1.isGeneratorDecl)(d) && d.fields.some((f) => f.name === 'provider' && (0, sdk_1.getLiteral)(f.value) === 'prisma-client-js')); const clientOutputField = generator === null || generator === void 0 ? void 0 : generator.fields.find((f) => f.name === 'output'); const clientOutput = (0, sdk_1.getLiteral)(clientOutputField === null || clientOutputField === void 0 ? void 0 : clientOutputField.value); if (clientOutput) { if (path_1.default.isAbsolute(clientOutput)) { prismaClientPath = clientOutput; } else { // first get absolute path based on prisma schema location const absPath = path_1.default.resolve(path_1.default.dirname(output), clientOutput); // then make it relative to the zmodel schema location prismaClientPath = (0, sdk_1.normalizedRelative)(path_1.default.dirname(options.schemaPath), absPath); } // record custom location where the prisma client was generated clientOutputDir = prismaClientPath; } // get PrismaClient dts path if (clientOutput) { // if a custom prisma client output path is configured, first try treating // clientOutputDir as a relative path and locate the index.d.ts file prismaClientDtsPath = path_1.default.resolve(path_1.default.dirname(options.schemaPath), clientOutputDir, 'index.d.ts'); } if (!prismaClientDtsPath || !fs_1.default.existsSync(prismaClientDtsPath)) { // if the file does not exist, try node module resolution try { // the resolution is relative to the schema path by default let resolveBase = path_1.default.dirname(options.schemaPath); if (!clientOutput) { // PrismaClient is generated into the default location, considering symlinked // environments like pnpm, we need to first resolve "@prisma/client",and then // resolve the ".prisma/client/index.d.ts" file relative to that resolveBase = path_1.default.dirname(require.resolve('@prisma/client', { paths: [resolveBase] })); } const prismaClientResolvedPath = require.resolve(clientOutputDir, { paths: [resolveBase] }); prismaClientDtsPath = path_1.default.join(path_1.default.dirname(prismaClientResolvedPath), 'index.d.ts'); } catch (err) { console.warn(colors_1.default.yellow(`Could not resolve PrismaClient type declaration path. This may break plugins that depend on it.`)); } } } else { console.warn(colors_1.default.yellow('Skipping prisma client generation because "generateClient" is set to false. This may break plugins that depend on the prisma client.')); } // load the result DMMF const dmmf = yield (0, prisma_1.getDMMF)({ datamodel: fs_1.default.readFileSync(output, 'utf-8'), }); return { warnings, dmmf, prismaClientPath, prismaClientDtsPath, shortNameMap }; }); function getDefaultPrismaOutputFile(schemaPath) { var _a; // handle override from package.json const pkgJsonPath = (0, pkg_utils_1.findUp)(['package.json'], path_1.default.dirname(schemaPath)); if (pkgJsonPath) { const pkgJson = JSON.parse(fs_1.default.readFileSync(pkgJsonPath, 'utf-8')); if (typeof ((_a = pkgJson === null || pkgJson === void 0 ? void 0 : pkgJson.zenstack) === null || _a === void 0 ? void 0 : _a.prisma) === 'string') { if (path_1.default.isAbsolute(pkgJson.zenstack.prisma)) { return pkgJson.zenstack.prisma; } else { // resolve relative to package.json return path_1.default.resolve(path_1.default.dirname(pkgJsonPath), pkgJson.zenstack.prisma); } } } return (0, sdk_1.resolvePath)('./prisma/schema.prisma', { schemaPath }); } function trackPrismaSchemaError(schema) { return __awaiter(this, void 0, void 0, function* () { try { yield (0, prisma_1.getDMMF)({ datamodel: fs_1.default.readFileSync(schema, 'utf-8') }); } catch (err) { if (err instanceof Error) { // eslint-disable-next-line @typescript-eslint/no-var-requires telemetry_1.default.track('prisma:error', { command: 'generate', message: (0, strip_color_1.default)(err.message) }); } } }); } exports.default = run; //# sourceMappingURL=index.js.map