Skip to content

Commit acbd2ae

Browse files
authored
Merge pull request #174 from zenstackhq/dev
merge dev to main (v3.0.0-alpha.25)
2 parents a607b46 + 1ac89c1 commit acbd2ae

File tree

40 files changed

+315
-165
lines changed

40 files changed

+315
-165
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ npm install -D @types/better-sqlite3
109109
For Postgres:
110110

111111
```bash
112-
npm install pg pg-connection-string
112+
npm install pg
113113
npm install -D @types/pg
114114
```
115115

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.24",
3+
"version": "3.0.0-alpha.25",
44
"description": "ZenStack",
55
"packageManager": "[email protected]",
66
"scripts": {

packages/cli/package.json

Lines changed: 2 additions & 2 deletions
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.24",
6+
"version": "3.0.0-alpha.25",
77
"type": "module",
88
"author": {
99
"name": "ZenStack Team"
@@ -22,7 +22,7 @@
2222
"zenstack": "bin/cli"
2323
},
2424
"scripts": {
25-
"build": "tsup-node",
25+
"build": "tsc --noEmit && tsup-node",
2626
"watch": "tsup-node --watch",
2727
"lint": "eslint src --ext ts",
2828
"test": "vitest run",

packages/cli/src/actions/migrate.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import fs from 'node:fs';
22
import path from 'node:path';
3+
import { CliError } from '../cli-error';
34
import { execPackage } from '../utils/exec-utils';
45
import { generateTempPrismaSchema, getSchemaFile } from './action-utils';
56

@@ -21,6 +22,11 @@ type DeployOptions = CommonOptions;
2122

2223
type StatusOptions = CommonOptions;
2324

25+
type ResolveOptions = CommonOptions & {
26+
applied?: string;
27+
rolledBack?: string;
28+
};
29+
2430
/**
2531
* CLI action for migration-related commands
2632
*/
@@ -46,6 +52,10 @@ export async function run(command: string, options: CommonOptions) {
4652
case 'status':
4753
await runStatus(prismaSchemaFile, options as StatusOptions);
4854
break;
55+
56+
case 'resolve':
57+
await runResolve(prismaSchemaFile, options as ResolveOptions);
58+
break;
4959
}
5060
} finally {
5161
if (fs.existsSync(prismaSchemaFile)) {
@@ -100,6 +110,25 @@ async function runStatus(prismaSchemaFile: string, _options: StatusOptions) {
100110
}
101111
}
102112

113+
async function runResolve(prismaSchemaFile: string, options: ResolveOptions) {
114+
if (!options.applied && !options.rolledBack) {
115+
throw new CliError('Either --applied or --rolled-back option must be provided');
116+
}
117+
118+
try {
119+
const cmd = [
120+
'prisma migrate resolve',
121+
` --schema "${prismaSchemaFile}"`,
122+
options.applied ? ` --applied ${options.applied}` : '',
123+
options.rolledBack ? ` --rolled-back ${options.rolledBack}` : '',
124+
].join('');
125+
126+
await execPackage(cmd);
127+
} catch (err) {
128+
handleSubProcessError(err);
129+
}
130+
}
131+
103132
function handleSubProcessError(err: unknown) {
104133
if (err instanceof Error && 'status' in err && typeof err.status === 'number') {
105134
process.exit(err.status);

packages/cli/src/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,18 @@ export function createProgram() {
9595
.command('status')
9696
.addOption(schemaOption)
9797
.addOption(migrationsOption)
98-
.description('check the status of your database migrations.')
98+
.description('Check the status of your database migrations.')
9999
.action((options) => migrateAction('status', options));
100100

101+
migrateCommand
102+
.command('resolve')
103+
.addOption(schemaOption)
104+
.addOption(migrationsOption)
105+
.addOption(new Option('--applied <migration>', 'record a specific migration as applied'))
106+
.addOption(new Option('--rolled-back <migration>', 'record a specific migration as rolled back'))
107+
.description('Resolve issues with database migrations in deployment databases')
108+
.action((options) => migrateAction('resolve', options));
109+
101110
const dbCommand = program.command('db').description('Manage your database schema during development.');
102111

103112
dbCommand

packages/cli/test/migrate.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,35 @@ describe('CLI migrate commands test', () => {
3838
runCli('migrate dev --name init', workDir);
3939
runCli('migrate status', workDir);
4040
});
41+
42+
it('supports migrate resolve', () => {
43+
const workDir = createProject(model);
44+
runCli('migrate dev --name init', workDir);
45+
46+
// find the migration record "timestamp_init"
47+
const migrationRecords = fs.readdirSync(path.join(workDir, 'zenstack/migrations'));
48+
const migration = migrationRecords.find((f) => f.endsWith('_init'));
49+
50+
// force a migration failure
51+
fs.writeFileSync(path.join(workDir, 'zenstack/migrations', migration!, 'migration.sql'), 'invalid content');
52+
53+
// redeploy the migration, which will fail
54+
fs.rmSync(path.join(workDir, 'zenstack/dev.db'), { force: true });
55+
try {
56+
runCli('migrate deploy', workDir);
57+
} catch {
58+
// noop
59+
}
60+
61+
// --rolled-back
62+
runCli(`migrate resolve --rolled-back ${migration}`, workDir);
63+
64+
// --applied
65+
runCli(`migrate resolve --applied ${migration}`, workDir);
66+
});
67+
68+
it('should throw error when neither applied nor rolled-back is provided', () => {
69+
const workDir = createProject(model);
70+
expect(() => runCli('migrate resolve', workDir)).toThrow();
71+
});
4172
});

packages/cli/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"extends": "@zenstackhq/typescript-config/base.json",
33
"compilerOptions": {
4-
"outDir": "dist"
4+
"baseUrl": "."
55
},
66
"include": ["src/**/*.ts"]
77
}

packages/common-helpers/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"name": "@zenstackhq/common-helpers",
3-
"version": "3.0.0-alpha.24",
3+
"version": "3.0.0-alpha.25",
44
"description": "ZenStack Common Helpers",
55
"type": "module",
66
"scripts": {
7-
"build": "tsup-node",
7+
"build": "tsc --noEmit && tsup-node",
88
"watch": "tsup-node --watch",
99
"lint": "eslint src --ext ts",
1010
"pack": "pnpm pack"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"extends": "@zenstackhq/typescript-config/base.json",
33
"compilerOptions": {
4-
"outDir": "dist"
4+
"baseUrl": "."
55
},
66
"include": ["src/**/*.ts"]
77
}

packages/create-zenstack/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"name": "create-zenstack",
3-
"version": "3.0.0-alpha.24",
3+
"version": "3.0.0-alpha.25",
44
"description": "Create a new ZenStack project",
55
"type": "module",
66
"scripts": {
7-
"build": "tsup-node",
7+
"build": "tsc --noEmit && tsup-node",
88
"lint": "eslint src --ext ts",
99
"pack": "pnpm pack"
1010
},

0 commit comments

Comments
 (0)