Skip to content

Commit e4885b0

Browse files
authored
fix(cli): improve compatibility for executing prisma commands (#401)
* fix(cli): improve compatibility for executing prisma commands * update
1 parent 94679db commit e4885b0

File tree

6 files changed

+62
-28
lines changed

6 files changed

+62
-28
lines changed

packages/cli/src/actions/action-utils.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,15 @@ export function getSchemaFile(file?: string) {
1919
if (!fs.existsSync(pkgJsonConfig.schema)) {
2020
throw new CliError(`Schema file not found: ${pkgJsonConfig.schema}`);
2121
}
22-
return pkgJsonConfig.schema;
22+
if (fs.statSync(pkgJsonConfig.schema).isDirectory()) {
23+
const schemaPath = path.join(pkgJsonConfig.schema, 'schema.zmodel');
24+
if (!fs.existsSync(schemaPath)) {
25+
throw new CliError(`Schema file not found: ${schemaPath}`);
26+
}
27+
return schemaPath;
28+
} else {
29+
return pkgJsonConfig.schema;
30+
}
2331
}
2432

2533
if (fs.existsSync('./zenstack/schema.zmodel')) {

packages/cli/src/actions/db.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import fs from 'node:fs';
2-
import { execPackage } from '../utils/exec-utils';
2+
import { execPrisma } from '../utils/exec-utils';
33
import { generateTempPrismaSchema, getSchemaFile, handleSubProcessError } from './action-utils';
44

55
type Options = {
@@ -27,15 +27,15 @@ async function runPush(options: Options) {
2727
try {
2828
// run prisma db push
2929
const cmd = [
30-
'prisma db push',
30+
'db push',
3131
` --schema "${prismaSchemaFile}"`,
3232
options.acceptDataLoss ? ' --accept-data-loss' : '',
3333
options.forceReset ? ' --force-reset' : '',
3434
' --skip-generate',
3535
].join('');
3636

3737
try {
38-
await execPackage(cmd);
38+
execPrisma(cmd);
3939
} catch (err) {
4040
handleSubProcessError(err);
4141
}

packages/cli/src/actions/migrate.ts

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import fs from 'node:fs';
22
import path from 'node:path';
33
import { CliError } from '../cli-error';
4-
import { execPackage } from '../utils/exec-utils';
4+
import { execPrisma } from '../utils/exec-utils';
55
import { generateTempPrismaSchema, getSchemaFile } from './action-utils';
66

77
type CommonOptions = {
@@ -64,69 +64,65 @@ export async function run(command: string, options: CommonOptions) {
6464
}
6565
}
6666

67-
async function runDev(prismaSchemaFile: string, options: DevOptions) {
67+
function runDev(prismaSchemaFile: string, options: DevOptions) {
6868
try {
6969
const cmd = [
70-
'prisma migrate dev',
70+
'migrate dev',
7171
` --schema "${prismaSchemaFile}"`,
7272
' --skip-generate',
73-
options.name ? ` --name ${options.name}` : '',
73+
options.name ? ` --name "${options.name}"` : '',
7474
options.createOnly ? ' --create-only' : '',
7575
].join('');
76-
77-
await execPackage(cmd);
76+
execPrisma(cmd);
7877
} catch (err) {
7978
handleSubProcessError(err);
8079
}
8180
}
8281

83-
async function runReset(prismaSchemaFile: string, options: ResetOptions) {
82+
function runReset(prismaSchemaFile: string, options: ResetOptions) {
8483
try {
8584
const cmd = [
86-
'prisma migrate reset',
85+
'migrate reset',
8786
` --schema "${prismaSchemaFile}"`,
8887
' --skip-generate',
8988
options.force ? ' --force' : '',
9089
].join('');
91-
92-
await execPackage(cmd);
90+
execPrisma(cmd);
9391
} catch (err) {
9492
handleSubProcessError(err);
9593
}
9694
}
9795

98-
async function runDeploy(prismaSchemaFile: string, _options: DeployOptions) {
96+
function runDeploy(prismaSchemaFile: string, _options: DeployOptions) {
9997
try {
100-
const cmd = ['prisma migrate deploy', ` --schema "${prismaSchemaFile}"`].join('');
101-
102-
await execPackage(cmd);
98+
const cmd = ['migrate deploy', ` --schema "${prismaSchemaFile}"`].join('');
99+
execPrisma(cmd);
103100
} catch (err) {
104101
handleSubProcessError(err);
105102
}
106103
}
107104

108-
async function runStatus(prismaSchemaFile: string, _options: StatusOptions) {
105+
function runStatus(prismaSchemaFile: string, _options: StatusOptions) {
109106
try {
110-
await execPackage(`prisma migrate status --schema "${prismaSchemaFile}"`);
107+
execPrisma(`migrate status --schema "${prismaSchemaFile}"`);
111108
} catch (err) {
112109
handleSubProcessError(err);
113110
}
114111
}
115112

116-
async function runResolve(prismaSchemaFile: string, options: ResolveOptions) {
113+
function runResolve(prismaSchemaFile: string, options: ResolveOptions) {
117114
if (!options.applied && !options.rolledBack) {
118115
throw new CliError('Either --applied or --rolled-back option must be provided');
119116
}
120117

121118
try {
122119
const cmd = [
123-
'prisma migrate resolve',
120+
'migrate resolve',
124121
` --schema "${prismaSchemaFile}"`,
125-
options.applied ? ` --applied ${options.applied}` : '',
126-
options.rolledBack ? ` --rolled-back ${options.rolledBack}` : '',
122+
options.applied ? ` --applied "${options.applied}"` : '',
123+
options.rolledBack ? ` --rolled-back "${options.rolledBack}"` : '',
127124
].join('');
128-
129-
await execPackage(cmd);
125+
execPrisma(cmd);
130126
} catch (err) {
131127
handleSubProcessError(err);
132128
}

packages/cli/src/utils/exec-utils.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { execSync as _exec, type ExecSyncOptions } from 'child_process';
2+
import { fileURLToPath } from 'url';
23

34
/**
45
* Utility for executing command synchronously and prints outputs on current console
@@ -24,3 +25,18 @@ export function execPackage(
2425
const packageManager = process?.versions?.['bun'] ? 'bunx' : 'npx';
2526
execSync(`${packageManager} ${cmd}`, options);
2627
}
28+
29+
/**
30+
* Utility for running prisma commands
31+
*/
32+
export function execPrisma(args: string, options?: Omit<ExecSyncOptions, 'env'> & { env?: Record<string, string> }) {
33+
let prismaPath: string;
34+
if (typeof import.meta.resolve === 'function') {
35+
// esm
36+
prismaPath = fileURLToPath(import.meta.resolve('prisma/build/index.js'));
37+
} else {
38+
// cjs
39+
prismaPath = require.resolve('prisma/build/index.js');
40+
}
41+
execSync(`node ${prismaPath} ${args}`, options);
42+
}

packages/cli/test/generate.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,21 @@ describe('CLI generate command test', () => {
4545
expect(fs.existsSync(path.join(workDir, 'bar/schema.ts'))).toBe(true);
4646
});
4747

48+
it('should respect package.json schema dir config', () => {
49+
const workDir = createProject(model);
50+
fs.mkdirSync(path.join(workDir, 'foo'));
51+
fs.renameSync(path.join(workDir, 'zenstack/schema.zmodel'), path.join(workDir, 'foo/schema.zmodel'));
52+
fs.rmdirSync(path.join(workDir, 'zenstack'));
53+
const pkgJson = JSON.parse(fs.readFileSync(path.join(workDir, 'package.json'), 'utf8'));
54+
pkgJson.zenstack = {
55+
schema: './foo',
56+
output: './bar',
57+
};
58+
fs.writeFileSync(path.join(workDir, 'package.json'), JSON.stringify(pkgJson, null, 2));
59+
runCli('generate', workDir);
60+
expect(fs.existsSync(path.join(workDir, 'bar/schema.ts'))).toBe(true);
61+
});
62+
4863
it('should respect lite option', () => {
4964
const workDir = createProject(model);
5065
runCli('generate --lite', workDir);

packages/cli/test/migrate.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ model User {
99
}
1010
`;
1111

12-
// skip due to timeout in CI
13-
describe.skip('CLI migrate commands test', () => {
12+
describe('CLI migrate commands test', () => {
1413
it('should generate a database with migrate dev', () => {
1514
const workDir = createProject(model);
1615
runCli('migrate dev --name init', workDir);

0 commit comments

Comments
 (0)