diff --git a/packages/schema/src/cli/cli-util.ts b/packages/schema/src/cli/cli-util.ts index 000e92ca7..85c38e82a 100644 --- a/packages/schema/src/cli/cli-util.ts +++ b/packages/schema/src/cli/cli-util.ts @@ -7,15 +7,15 @@ import { AstNode, getDocument, LangiumDocument, LangiumDocuments, Mutable } from import { NodeFileSystem } from 'langium/node'; import path from 'path'; import semver from 'semver'; +import { TextDocument } from 'vscode-languageserver-textdocument'; import { URI } from 'vscode-uri'; import { PLUGIN_MODULE_NAME, STD_LIB_MODULE_NAME } from '../language-server/constants'; +import { ZModelFormatter } from '../language-server/zmodel-formatter'; import { createZModelServices, ZModelServices } from '../language-server/zmodel-module'; import { mergeBaseModel, resolveImport, resolveTransitiveImports } from '../utils/ast-utils'; +import { findPackageJson } from '../utils/pkg-utils'; import { getVersion } from '../utils/version-utils'; import { CliError } from './cli-error'; -import { ZModelFormatter } from '../language-server/zmodel-formatter'; -import { TextDocument } from 'vscode-languageserver-textdocument'; -import { getPackageJson } from '../utils/pkg-utils'; // required minimal version of Prisma export const requiredPrismaVersion = '4.8.0'; @@ -279,13 +279,19 @@ export async function formatDocument(fileName: string) { } export function getDefaultSchemaLocation() { - let location = path.resolve('schema.zmodel'); - // handle override from package.json - const pkgJson = getPackageJson(); - if (typeof pkgJson?.zenstack?.schema === 'string') { - location = path.resolve(pkgJson.zenstack.schema); + const pkgJsonPath = findPackageJson(); + if (pkgJsonPath) { + const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8')); + if (typeof pkgJson?.zenstack?.schema === 'string') { + if (path.isAbsolute(pkgJson.zenstack.schema)) { + return pkgJson.zenstack.schema; + } else { + // resolve relative to package.json + return path.resolve(path.dirname(pkgJsonPath), pkgJson.zenstack.schema); + } + } } - return location; + return path.resolve('schema.zmodel'); } diff --git a/packages/schema/src/plugins/prisma/schema-generator.ts b/packages/schema/src/plugins/prisma/schema-generator.ts index 508e379f3..1d59f7429 100644 --- a/packages/schema/src/plugins/prisma/schema-generator.ts +++ b/packages/schema/src/plugins/prisma/schema-generator.ts @@ -48,7 +48,7 @@ import { name } from '.'; import { getStringLiteral } from '../../language-server/validator/utils'; import telemetry from '../../telemetry'; import { execSync } from '../../utils/exec-utils'; -import { getPackageJson } from '../../utils/pkg-utils'; +import { findPackageJson } from '../../utils/pkg-utils'; import { ModelFieldType, AttributeArg as PrismaAttributeArg, @@ -441,15 +441,19 @@ export default class PrismaSchemaGenerator { } export function getDefaultPrismaOutputFile(schemaPath: string) { - let result: string | undefined; - // handle override from package.json - const pkgJson = getPackageJson(); - if (typeof pkgJson.zenstack?.prisma === 'string') { - result = path.resolve(pkgJson.zenstack.prisma); - } else { - result = './prisma/schema.prisma'; + const pkgJsonPath = findPackageJson(path.dirname(schemaPath)); + if (pkgJsonPath) { + const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8')); + if (typeof pkgJson?.zenstack?.prisma === 'string') { + if (path.isAbsolute(pkgJson.zenstack.prisma)) { + return pkgJson.zenstack.prisma; + } else { + // resolve relative to package.json + return path.resolve(path.dirname(pkgJsonPath), pkgJson.zenstack.prisma); + } + } } - return resolvePath(result, { schemaPath }); + return resolvePath('./prisma/schema.prisma', { schemaPath }); } diff --git a/packages/schema/src/utils/pkg-utils.ts b/packages/schema/src/utils/pkg-utils.ts index ffb9b0aea..ca4ca127d 100644 --- a/packages/schema/src/utils/pkg-utils.ts +++ b/packages/schema/src/utils/pkg-utils.ts @@ -85,9 +85,25 @@ export function ensurePackage( } } -export function getPackageJson() { - const pkgJsonPath = path.join(process.cwd(), 'package.json'); - if (fs.existsSync(pkgJsonPath)) { +export function findPackageJson(searchPath?: string) { + let currDir = searchPath ?? process.cwd(); + while (currDir) { + const pkgJsonPath = path.join(currDir, 'package.json'); + if (fs.existsSync(pkgJsonPath)) { + return pkgJsonPath; + } + const up = path.resolve(currDir, '..'); + if (up === currDir) { + return undefined; + } + currDir = up; + } + return undefined; +} + +export function getPackageJson(searchPath?: string) { + const pkgJsonPath = findPackageJson(searchPath); + if (pkgJsonPath) { return JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8')); } else { return undefined;