Skip to content

Commit 8398575

Browse files
authored
Merge pull request #87 from zenstackhq/dev
merge dev to main
2 parents 04323de + 23ce49b commit 8398575

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+209
-96
lines changed

.prettierignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
packages/language/src/generated/**
2+
**/schema.ts

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "zenstack-v3",
3-
"version": "3.0.0-alpha.9",
3+
"version": "3.0.0-alpha.10",
44
"description": "ZenStack",
55
"packageManager": "[email protected]",
66
"scripts": {

packages/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"publisher": "zenstack",
44
"displayName": "ZenStack CLI",
55
"description": "FullStack database toolkit with built-in access control and automatic API generation.",
6-
"version": "3.0.0-alpha.9",
6+
"version": "3.0.0-alpha.10",
77
"type": "module",
88
"author": {
99
"name": "ZenStack Team"

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { findUp } from '@zenstackhq/common-helpers';
12
import { loadDocument } from '@zenstackhq/language';
23
import { PrismaSchemaGenerator } from '@zenstackhq/sdk';
34
import colors from 'colors';
@@ -13,6 +14,14 @@ export function getSchemaFile(file?: string) {
1314
return file;
1415
}
1516

17+
const pkgJsonConfig = getPkgJsonConfig(process.cwd());
18+
if (pkgJsonConfig.schema) {
19+
if (!fs.existsSync(pkgJsonConfig.schema)) {
20+
throw new CliError(`Schema file not found: ${pkgJsonConfig.schema}`);
21+
}
22+
return pkgJsonConfig.schema;
23+
}
24+
1625
if (fs.existsSync('./zenstack/schema.zmodel')) {
1726
return './zenstack/schema.zmodel';
1827
} else if (fs.existsSync('./schema.zmodel')) {
@@ -51,3 +60,26 @@ export async function generateTempPrismaSchema(zmodelPath: string) {
5160
fs.writeFileSync(prismaSchemaFile, prismaSchema);
5261
return prismaSchemaFile;
5362
}
63+
64+
export function getPkgJsonConfig(startPath: string) {
65+
const result: { schema: string | undefined; output: string | undefined } = { schema: undefined, output: undefined };
66+
const pkgJsonFile = findUp(['package.json'], startPath, false);
67+
68+
if (!pkgJsonFile) {
69+
return result;
70+
}
71+
72+
let pkgJson: any = undefined;
73+
try {
74+
pkgJson = JSON.parse(fs.readFileSync(pkgJsonFile, 'utf8'));
75+
} catch {
76+
return result;
77+
}
78+
79+
if (pkgJson.zenstack && typeof pkgJson.zenstack === 'object') {
80+
result.schema = pkgJson.zenstack.schema && path.resolve(path.dirname(pkgJsonFile), pkgJson.zenstack.schema);
81+
result.output = pkgJson.zenstack.output && path.resolve(path.dirname(pkgJsonFile), pkgJson.zenstack.output);
82+
}
83+
84+
return result;
85+
}

packages/cli/src/actions/db.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,16 @@ async function runPush(options: Options) {
2626

2727
try {
2828
// run prisma db push
29-
const cmd = `prisma db push --schema "${prismaSchemaFile}"${
30-
options.acceptDataLoss ? ' --accept-data-loss' : ''
31-
}${options.forceReset ? ' --force-reset' : ''} --skip-generate`;
29+
const cmd = [
30+
'prisma db push',
31+
` --schema "${prismaSchemaFile}"`,
32+
options.acceptDataLoss ? ' --accept-data-loss' : '',
33+
options.forceReset ? ' --force-reset' : '',
34+
' --skip-generate',
35+
].join('');
36+
3237
try {
33-
await execPackage(cmd, {
34-
stdio: 'inherit',
35-
});
38+
await execPackage(cmd);
3639
} catch (err) {
3740
handleSubProcessError(err);
3841
}

packages/cli/src/actions/generate.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { PrismaSchemaGenerator, TsSchemaGenerator, type CliGenerator } from '@ze
44
import colors from 'colors';
55
import fs from 'node:fs';
66
import path from 'node:path';
7-
import { getSchemaFile, loadSchemaDocument } from './action-utils';
7+
import { getPkgJsonConfig, getSchemaFile, loadSchemaDocument } from './action-utils';
88

99
type Options = {
1010
schema?: string;
@@ -20,7 +20,7 @@ export async function run(options: Options) {
2020
const schemaFile = getSchemaFile(options.schema);
2121

2222
const model = await loadSchemaDocument(schemaFile);
23-
const outputPath = options.output ?? path.dirname(schemaFile);
23+
const outputPath = getOutputPath(options, schemaFile);
2424

2525
// generate TS schema
2626
const tsSchemaFile = path.join(outputPath, 'schema.ts');
@@ -55,6 +55,18 @@ const client = new ZenStackClient(schema, {
5555
}
5656
}
5757

58+
function getOutputPath(options: Options, schemaFile: string) {
59+
if (options.output) {
60+
return options.output;
61+
}
62+
const pkgJsonConfig = getPkgJsonConfig(process.cwd());
63+
if (pkgJsonConfig.output) {
64+
return pkgJsonConfig.output;
65+
} else {
66+
return path.dirname(schemaFile);
67+
}
68+
}
69+
5870
async function runPlugins(model: Model, outputPath: string, tsSchemaFile: string) {
5971
const plugins = model.declarations.filter(isPlugin);
6072
for (const plugin of plugins) {

packages/cli/src/actions/migrate.ts

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,42 +53,45 @@ export async function run(command: string, options: CommonOptions) {
5353

5454
async function runDev(prismaSchemaFile: string, options: DevOptions) {
5555
try {
56-
await execPackage(
57-
`prisma migrate dev --schema "${prismaSchemaFile}" --skip-generate${options.name ? ` --name ${options.name}` : ''}${options.createOnly ? ' --create-only' : ''}`,
58-
{
59-
stdio: 'inherit',
60-
},
61-
);
56+
const cmd = [
57+
'prisma migrate dev',
58+
` --schema "${prismaSchemaFile}"`,
59+
' --skip-generate',
60+
options.name ? ` --name ${options.name}` : '',
61+
options.createOnly ? ' --create-only' : '',
62+
].join('');
63+
64+
await execPackage(cmd);
6265
} catch (err) {
6366
handleSubProcessError(err);
6467
}
6568
}
6669

6770
async function runReset(prismaSchemaFile: string, options: ResetOptions) {
6871
try {
69-
await execPackage(`prisma migrate reset --schema "${prismaSchemaFile}"${options.force ? ' --force' : ''}`, {
70-
stdio: 'inherit',
71-
});
72+
const cmd = ['prisma migrate reset', ` --schema "${prismaSchemaFile}"`, options.force ? ' --force' : ''].join(
73+
'',
74+
);
75+
76+
await execPackage(cmd);
7277
} catch (err) {
7378
handleSubProcessError(err);
7479
}
7580
}
7681

7782
async function runDeploy(prismaSchemaFile: string, _options: DeployOptions) {
7883
try {
79-
await execPackage(`prisma migrate deploy --schema "${prismaSchemaFile}"`, {
80-
stdio: 'inherit',
81-
});
84+
const cmd = ['prisma migrate deploy', ` --schema "${prismaSchemaFile}"`].join('');
85+
86+
await execPackage(cmd);
8287
} catch (err) {
8388
handleSubProcessError(err);
8489
}
8590
}
8691

8792
async function runStatus(prismaSchemaFile: string, _options: StatusOptions) {
8893
try {
89-
await execPackage(`prisma migrate status --schema "${prismaSchemaFile}"`, {
90-
stdio: 'inherit',
91-
});
94+
await execPackage(`prisma migrate status --schema "${prismaSchemaFile}"`);
9295
} catch (err) {
9396
handleSubProcessError(err);
9497
}

packages/cli/test/generate.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,19 @@ describe('CLI generate command test', () => {
4141
runCli('generate --save-prisma-schema "../prisma/schema.prisma"', workDir);
4242
expect(fs.existsSync(path.join(workDir, 'prisma/schema.prisma'))).toBe(true);
4343
});
44+
45+
it('should respect package.json config', () => {
46+
const workDir = createProject(model);
47+
fs.mkdirSync(path.join(workDir, 'foo'));
48+
fs.renameSync(path.join(workDir, 'zenstack/schema.zmodel'), path.join(workDir, 'foo/schema.zmodel'));
49+
fs.rmdirSync(path.join(workDir, 'zenstack'));
50+
const pkgJson = JSON.parse(fs.readFileSync(path.join(workDir, 'package.json'), 'utf8'));
51+
pkgJson.zenstack = {
52+
schema: './foo/schema.zmodel',
53+
output: './bar',
54+
};
55+
fs.writeFileSync(path.join(workDir, 'package.json'), JSON.stringify(pkgJson, null, 2));
56+
runCli('generate', workDir);
57+
expect(fs.existsSync(path.join(workDir, 'bar/schema.ts'))).toBe(true);
58+
});
4459
});

packages/common-helpers/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zenstackhq/common-helpers",
3-
"version": "3.0.0-alpha.9",
3+
"version": "3.0.0-alpha.10",
44
"description": "ZenStack Common Helpers",
55
"type": "module",
66
"scripts": {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import fs from 'fs';
2+
import path from 'path';
3+
4+
/**
5+
* A type named FindUp that takes a type parameter e which extends boolean.
6+
*/
7+
export type FindUpResult<Multiple extends boolean> = Multiple extends true ? string[] | undefined : string | undefined;
8+
9+
/**
10+
* Find and return file paths by searching parent directories based on the given names list and current working directory (cwd) path.
11+
* Optionally return a single path or multiple paths.
12+
* If multiple allowed, return all paths found.
13+
* If no paths are found, return undefined.
14+
*
15+
* @param names An array of strings representing names to search for within the directory
16+
* @param cwd A string representing the current working directory
17+
* @param multiple A boolean flag indicating whether to search for multiple levels. Useful for finding node_modules directories...
18+
* @param An array of strings representing the accumulated results used in multiple results
19+
* @returns Path(s) to a specific file or folder within the directory or parent directories
20+
*/
21+
export function findUp<Multiple extends boolean = false>(
22+
names: string[],
23+
cwd: string = process.cwd(),
24+
multiple: Multiple = false as Multiple,
25+
result: string[] = [],
26+
): FindUpResult<Multiple> {
27+
if (!names.some((name) => !!name)) return undefined;
28+
const target = names.find((name) => fs.existsSync(path.join(cwd, name)));
29+
if (multiple === false && target) return path.join(cwd, target) as FindUpResult<Multiple>;
30+
if (target) result.push(path.join(cwd, target));
31+
const up = path.resolve(cwd, '..');
32+
if (up === cwd) return (multiple && result.length > 0 ? result : undefined) as FindUpResult<Multiple>; // it'll fail anyway
33+
return findUp(names, up, multiple, result);
34+
}

0 commit comments

Comments
 (0)