relq 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/cli/commands/add.cjs +403 -27
- package/dist/cjs/cli/commands/branch.cjs +13 -23
- package/dist/cjs/cli/commands/checkout.cjs +16 -29
- package/dist/cjs/cli/commands/cherry-pick.cjs +3 -4
- package/dist/cjs/cli/commands/commit.cjs +21 -29
- package/dist/cjs/cli/commands/diff.cjs +28 -32
- package/dist/cjs/cli/commands/export.cjs +7 -7
- package/dist/cjs/cli/commands/fetch.cjs +15 -21
- package/dist/cjs/cli/commands/generate.cjs +28 -54
- package/dist/cjs/cli/commands/history.cjs +19 -40
- package/dist/cjs/cli/commands/import.cjs +34 -41
- package/dist/cjs/cli/commands/init.cjs +69 -59
- package/dist/cjs/cli/commands/introspect.cjs +4 -8
- package/dist/cjs/cli/commands/log.cjs +26 -32
- package/dist/cjs/cli/commands/merge.cjs +24 -41
- package/dist/cjs/cli/commands/migrate.cjs +12 -25
- package/dist/cjs/cli/commands/pull.cjs +216 -106
- package/dist/cjs/cli/commands/push.cjs +35 -75
- package/dist/cjs/cli/commands/remote.cjs +2 -1
- package/dist/cjs/cli/commands/reset.cjs +22 -43
- package/dist/cjs/cli/commands/resolve.cjs +12 -14
- package/dist/cjs/cli/commands/rollback.cjs +16 -38
- package/dist/cjs/cli/commands/stash.cjs +5 -7
- package/dist/cjs/cli/commands/status.cjs +5 -10
- package/dist/cjs/cli/commands/sync.cjs +30 -50
- package/dist/cjs/cli/commands/tag.cjs +3 -4
- package/dist/cjs/cli/index.cjs +72 -9
- package/dist/cjs/cli/utils/change-tracker.cjs +107 -3
- package/dist/cjs/cli/utils/cli-utils.cjs +217 -0
- package/dist/cjs/cli/utils/config-loader.cjs +34 -8
- package/dist/cjs/cli/utils/fast-introspect.cjs +109 -3
- package/dist/cjs/cli/utils/git-utils.cjs +42 -161
- package/dist/cjs/cli/utils/pool-manager.cjs +156 -0
- package/dist/cjs/cli/utils/project-root.cjs +56 -5
- package/dist/cjs/cli/utils/relqignore.cjs +1 -0
- package/dist/cjs/cli/utils/repo-manager.cjs +47 -0
- package/dist/cjs/cli/utils/schema-comparator.cjs +301 -11
- package/dist/cjs/cli/utils/schema-diff.cjs +202 -1
- package/dist/cjs/cli/utils/schema-hash.cjs +2 -1
- package/dist/cjs/cli/utils/schema-introspect.cjs +7 -3
- package/dist/cjs/cli/utils/snapshot-manager.cjs +1 -0
- package/dist/cjs/cli/utils/spinner.cjs +14 -106
- package/dist/cjs/cli/utils/sql-generator.cjs +10 -2
- package/dist/cjs/cli/utils/type-generator.cjs +28 -16
- package/dist/config.d.ts +16 -6
- package/dist/esm/cli/commands/add.js +372 -29
- package/dist/esm/cli/commands/branch.js +14 -24
- package/dist/esm/cli/commands/checkout.js +16 -29
- package/dist/esm/cli/commands/cherry-pick.js +3 -4
- package/dist/esm/cli/commands/commit.js +22 -30
- package/dist/esm/cli/commands/diff.js +6 -10
- package/dist/esm/cli/commands/export.js +8 -8
- package/dist/esm/cli/commands/fetch.js +14 -20
- package/dist/esm/cli/commands/generate.js +28 -54
- package/dist/esm/cli/commands/history.js +11 -32
- package/dist/esm/cli/commands/import.js +35 -42
- package/dist/esm/cli/commands/init.js +65 -55
- package/dist/esm/cli/commands/introspect.js +4 -8
- package/dist/esm/cli/commands/log.js +6 -12
- package/dist/esm/cli/commands/merge.js +20 -37
- package/dist/esm/cli/commands/migrate.js +12 -25
- package/dist/esm/cli/commands/pull.js +204 -94
- package/dist/esm/cli/commands/push.js +21 -61
- package/dist/esm/cli/commands/remote.js +2 -1
- package/dist/esm/cli/commands/reset.js +16 -37
- package/dist/esm/cli/commands/resolve.js +13 -15
- package/dist/esm/cli/commands/rollback.js +16 -38
- package/dist/esm/cli/commands/stash.js +6 -8
- package/dist/esm/cli/commands/status.js +6 -11
- package/dist/esm/cli/commands/sync.js +30 -50
- package/dist/esm/cli/commands/tag.js +3 -4
- package/dist/esm/cli/index.js +72 -9
- package/dist/esm/cli/utils/change-tracker.js +107 -3
- package/dist/esm/cli/utils/cli-utils.js +169 -0
- package/dist/esm/cli/utils/config-loader.js +34 -8
- package/dist/esm/cli/utils/fast-introspect.js +109 -3
- package/dist/esm/cli/utils/git-utils.js +2 -124
- package/dist/esm/cli/utils/pool-manager.js +114 -0
- package/dist/esm/cli/utils/project-root.js +55 -5
- package/dist/esm/cli/utils/relqignore.js +1 -0
- package/dist/esm/cli/utils/repo-manager.js +42 -0
- package/dist/esm/cli/utils/schema-comparator.js +301 -11
- package/dist/esm/cli/utils/schema-diff.js +202 -1
- package/dist/esm/cli/utils/schema-hash.js +2 -1
- package/dist/esm/cli/utils/schema-introspect.js +7 -3
- package/dist/esm/cli/utils/snapshot-manager.js +1 -0
- package/dist/esm/cli/utils/spinner.js +1 -101
- package/dist/esm/cli/utils/sql-generator.js +10 -2
- package/dist/esm/cli/utils/type-generator.js +28 -16
- package/dist/index.d.ts +25 -8
- package/dist/schema-builder.d.ts +18 -7
- package/package.json +1 -1
|
@@ -39,8 +39,7 @@ const path = __importStar(require("path"));
|
|
|
39
39
|
const spinner_1 = require("../utils/spinner.cjs");
|
|
40
40
|
const repo_manager_1 = require("../utils/repo-manager.cjs");
|
|
41
41
|
async function cherryPickCommand(context) {
|
|
42
|
-
const { config, args, flags } = context;
|
|
43
|
-
const projectRoot = process.cwd();
|
|
42
|
+
const { config, args, flags, projectRoot } = context;
|
|
44
43
|
console.log('');
|
|
45
44
|
if (!(0, repo_manager_1.isInitialized)(projectRoot)) {
|
|
46
45
|
console.log(`${spinner_1.colors.red('fatal:')} not a relq repository`);
|
|
@@ -51,10 +50,10 @@ async function cherryPickCommand(context) {
|
|
|
51
50
|
if (abort) {
|
|
52
51
|
if (fs.existsSync(cherryPickStatePath)) {
|
|
53
52
|
fs.unlinkSync(cherryPickStatePath);
|
|
54
|
-
console.log(
|
|
53
|
+
console.log('Cherry-pick aborted');
|
|
55
54
|
}
|
|
56
55
|
else {
|
|
57
|
-
console.log(
|
|
56
|
+
console.log('No cherry-pick in progress.');
|
|
58
57
|
}
|
|
59
58
|
console.log('');
|
|
60
59
|
return;
|
|
@@ -35,33 +35,29 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.commitCommand = commitCommand;
|
|
37
37
|
const crypto = __importStar(require("crypto"));
|
|
38
|
-
const
|
|
38
|
+
const cli_utils_1 = require("../utils/cli-utils.cjs");
|
|
39
39
|
const repo_manager_1 = require("../utils/repo-manager.cjs");
|
|
40
|
+
const config_1 = require("../../config/config.cjs");
|
|
40
41
|
const change_tracker_1 = require("../utils/change-tracker.cjs");
|
|
41
42
|
const fs = __importStar(require("fs"));
|
|
42
43
|
const path = __importStar(require("path"));
|
|
43
44
|
async function commitCommand(context) {
|
|
44
|
-
const { config, flags, args } = context;
|
|
45
|
-
const projectRoot = process.cwd();
|
|
45
|
+
const { config, flags, args, projectRoot } = context;
|
|
46
46
|
const author = config?.author || 'Developer <dev@example.com>';
|
|
47
47
|
console.log('');
|
|
48
48
|
if (!(0, repo_manager_1.isInitialized)(projectRoot)) {
|
|
49
|
-
|
|
50
|
-
console.log('');
|
|
51
|
-
console.log(`${spinner_1.colors.muted('Run')} ${spinner_1.colors.cyan('relq init')} ${spinner_1.colors.muted('first.')}`);
|
|
52
|
-
return;
|
|
49
|
+
(0, cli_utils_1.fatal)('not a relq repository (or any parent directories): .relq', "run 'relq init' to initialize");
|
|
53
50
|
}
|
|
54
51
|
const staged = (0, repo_manager_1.getStagedChanges)(projectRoot);
|
|
55
52
|
if (staged.length === 0) {
|
|
56
|
-
console.log(
|
|
57
|
-
console.log('');
|
|
53
|
+
console.log('nothing to commit, working tree clean');
|
|
58
54
|
const unstaged = (0, repo_manager_1.getUnstagedChanges)(projectRoot);
|
|
59
55
|
if (unstaged.length > 0) {
|
|
60
|
-
console.log(`${
|
|
61
|
-
|
|
56
|
+
console.log(`${unstaged.length} unstaged change(s).`);
|
|
57
|
+
(0, cli_utils_1.hint)("run 'relq add .' to stage all changes");
|
|
62
58
|
}
|
|
63
59
|
else {
|
|
64
|
-
|
|
60
|
+
(0, cli_utils_1.hint)("run 'relq add <table>' to stage changes");
|
|
65
61
|
}
|
|
66
62
|
return;
|
|
67
63
|
}
|
|
@@ -71,10 +67,7 @@ async function commitCommand(context) {
|
|
|
71
67
|
message = args.join(' ');
|
|
72
68
|
}
|
|
73
69
|
else {
|
|
74
|
-
|
|
75
|
-
console.log('');
|
|
76
|
-
console.log(`${spinner_1.colors.muted('Usage:')} relq commit -m "message"`);
|
|
77
|
-
return;
|
|
70
|
+
(0, cli_utils_1.fatal)('commit message required', "usage: relq commit -m '<message>'");
|
|
78
71
|
}
|
|
79
72
|
}
|
|
80
73
|
const sortedChanges = (0, change_tracker_1.sortChangesByDependency)(staged);
|
|
@@ -113,7 +106,7 @@ async function commitCommand(context) {
|
|
|
113
106
|
fs.writeFileSync(path.join(commitsDir, `${hash}.json`), JSON.stringify(commit, null, 2), 'utf-8');
|
|
114
107
|
fs.writeFileSync(path.join(projectRoot, '.relq', 'HEAD'), hash, 'utf-8');
|
|
115
108
|
const workingPath = path.join(projectRoot, '.relq', 'working.json');
|
|
116
|
-
const unstaged = (0, repo_manager_1.getUnstagedChanges)(projectRoot);
|
|
109
|
+
const unstaged = (0, repo_manager_1.getUnstagedChanges)(projectRoot).filter(c => c.objectType !== 'SCHEMA_FILE');
|
|
117
110
|
if (unstaged.length > 0) {
|
|
118
111
|
fs.writeFileSync(workingPath, JSON.stringify({
|
|
119
112
|
timestamp: new Date().toISOString(),
|
|
@@ -126,20 +119,19 @@ async function commitCommand(context) {
|
|
|
126
119
|
fs.unlinkSync(workingPath);
|
|
127
120
|
}
|
|
128
121
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
if (drops > 0) {
|
|
138
|
-
console.log(` ${spinner_1.colors.red(`${drops} dropped`)}`);
|
|
122
|
+
const commitConfig = await (0, config_1.loadConfig)();
|
|
123
|
+
const schemaPathRaw = typeof commitConfig.schema === 'string' ? commitConfig.schema : './db/schema.ts';
|
|
124
|
+
const schemaFilePath = path.resolve(projectRoot, schemaPathRaw);
|
|
125
|
+
if (fs.existsSync(schemaFilePath)) {
|
|
126
|
+
const currentContent = fs.readFileSync(schemaFilePath, 'utf-8');
|
|
127
|
+
const currentHash = (0, repo_manager_1.hashFileContent)(currentContent);
|
|
128
|
+
(0, repo_manager_1.saveFileHash)(currentHash, projectRoot);
|
|
139
129
|
}
|
|
130
|
+
console.log(`[${(0, repo_manager_1.shortHash)(hash)}] ${message}`);
|
|
131
|
+
console.log(` ${creates} create(s), ${alters} alter(s), ${drops} drop(s)`);
|
|
140
132
|
console.log('');
|
|
141
|
-
|
|
142
|
-
|
|
133
|
+
(0, cli_utils_1.hint)("run 'relq push' to apply changes to database");
|
|
134
|
+
(0, cli_utils_1.hint)("run 'relq export' to export as SQL file");
|
|
143
135
|
console.log('');
|
|
144
136
|
}
|
|
145
137
|
exports.default = commitCommand;
|
|
@@ -4,17 +4,14 @@ exports.diffCommand = diffCommand;
|
|
|
4
4
|
const config_loader_1 = require("../utils/config-loader.cjs");
|
|
5
5
|
const fast_introspect_1 = require("../utils/fast-introspect.cjs");
|
|
6
6
|
const env_loader_1 = require("../utils/env-loader.cjs");
|
|
7
|
-
const
|
|
7
|
+
const cli_utils_1 = require("../utils/cli-utils.cjs");
|
|
8
8
|
const repo_manager_1 = require("../utils/repo-manager.cjs");
|
|
9
9
|
const change_tracker_1 = require("../utils/change-tracker.cjs");
|
|
10
10
|
async function diffCommand(context) {
|
|
11
|
-
const { config, args, flags } = context;
|
|
12
|
-
const projectRoot = process.cwd();
|
|
11
|
+
const { config, args, flags, projectRoot } = context;
|
|
13
12
|
console.log('');
|
|
14
13
|
if (!(0, repo_manager_1.isInitialized)(projectRoot)) {
|
|
15
|
-
|
|
16
|
-
console.log(`${spinner_1.colors.muted('Run')} ${spinner_1.colors.cyan('relq init')} ${spinner_1.colors.muted('to initialize.')}`);
|
|
17
|
-
return;
|
|
14
|
+
(0, cli_utils_1.fatal)('not a relq repository (or any parent directories): .relq', `Run ${cli_utils_1.colors.cyan('relq init')} to initialize.`);
|
|
18
15
|
}
|
|
19
16
|
const showSQL = flags['sql'] === true;
|
|
20
17
|
const staged = flags['staged'] === true;
|
|
@@ -25,10 +22,9 @@ async function diffCommand(context) {
|
|
|
25
22
|
}
|
|
26
23
|
if (target === 'remote/live' || target === 'remote' || target === 'live' || target === 'origin') {
|
|
27
24
|
if (!config) {
|
|
28
|
-
|
|
29
|
-
process.exit(1);
|
|
25
|
+
(0, cli_utils_1.fatal)('No configuration found', `Run ${cli_utils_1.colors.cyan('relq init')} to create one.`);
|
|
30
26
|
}
|
|
31
|
-
(0, config_loader_1.requireValidConfig)(config);
|
|
27
|
+
await (0, config_loader_1.requireValidConfig)(config, { calledFrom: 'diff' });
|
|
32
28
|
await showOriginDiff(config, projectRoot, showSQL);
|
|
33
29
|
return;
|
|
34
30
|
}
|
|
@@ -36,20 +32,20 @@ async function diffCommand(context) {
|
|
|
36
32
|
}
|
|
37
33
|
function getSymbol(change) {
|
|
38
34
|
if (change.type === 'CREATE')
|
|
39
|
-
return
|
|
35
|
+
return cli_utils_1.colors.green('+');
|
|
40
36
|
if (change.type === 'DROP')
|
|
41
|
-
return
|
|
42
|
-
return
|
|
37
|
+
return cli_utils_1.colors.red('-');
|
|
38
|
+
return cli_utils_1.colors.yellow('~');
|
|
43
39
|
}
|
|
44
40
|
async function showUnstagedDiff(projectRoot, showSQL) {
|
|
45
41
|
const unstaged = (0, repo_manager_1.getUnstagedChanges)(projectRoot);
|
|
46
42
|
if (unstaged.length === 0) {
|
|
47
|
-
console.log(`${
|
|
48
|
-
console.log(`${
|
|
43
|
+
console.log(`${cli_utils_1.colors.green('No unstaged changes.')}`);
|
|
44
|
+
console.log(`${cli_utils_1.colors.muted('Use')} ${cli_utils_1.colors.cyan('relq diff remote/live')} ${cli_utils_1.colors.muted('to compare with remote.')}`);
|
|
49
45
|
console.log('');
|
|
50
46
|
return;
|
|
51
47
|
}
|
|
52
|
-
console.log(`${
|
|
48
|
+
console.log(`${cli_utils_1.colors.bold('Unstaged changes:')}`);
|
|
53
49
|
console.log('');
|
|
54
50
|
const sorted = (0, change_tracker_1.sortChangesByDependency)(unstaged);
|
|
55
51
|
for (const change of sorted) {
|
|
@@ -57,26 +53,26 @@ async function showUnstagedDiff(projectRoot, showSQL) {
|
|
|
57
53
|
}
|
|
58
54
|
if (showSQL) {
|
|
59
55
|
console.log('');
|
|
60
|
-
console.log(`${
|
|
56
|
+
console.log(`${cli_utils_1.colors.bold('SQL:')}`);
|
|
61
57
|
for (const change of sorted) {
|
|
62
58
|
const sql = (0, change_tracker_1.generateChangeSQL)(change);
|
|
63
59
|
if (sql)
|
|
64
|
-
console.log(`${
|
|
60
|
+
console.log(`${cli_utils_1.colors.cyan(sql)}`);
|
|
65
61
|
}
|
|
66
62
|
}
|
|
67
63
|
console.log('');
|
|
68
|
-
console.log(`${
|
|
64
|
+
console.log(`${cli_utils_1.colors.muted('Use')} ${cli_utils_1.colors.cyan('relq add .')} ${cli_utils_1.colors.muted('to stage all.')}`);
|
|
69
65
|
console.log('');
|
|
70
66
|
}
|
|
71
67
|
async function showStagedDiff(projectRoot, showSQL) {
|
|
72
68
|
const staged = (0, repo_manager_1.getStagedChanges)(projectRoot);
|
|
73
69
|
if (staged.length === 0) {
|
|
74
|
-
console.log(`${
|
|
75
|
-
console.log(`${
|
|
70
|
+
console.log(`${cli_utils_1.colors.green('No staged changes.')}`);
|
|
71
|
+
console.log(`${cli_utils_1.colors.muted('Use')} ${cli_utils_1.colors.cyan('relq add .')} ${cli_utils_1.colors.muted('to stage changes.')}`);
|
|
76
72
|
console.log('');
|
|
77
73
|
return;
|
|
78
74
|
}
|
|
79
|
-
console.log(`${
|
|
75
|
+
console.log(`${cli_utils_1.colors.bold('Staged changes:')}`);
|
|
80
76
|
console.log('');
|
|
81
77
|
const sorted = (0, change_tracker_1.sortChangesByDependency)(staged);
|
|
82
78
|
for (const change of sorted) {
|
|
@@ -84,24 +80,24 @@ async function showStagedDiff(projectRoot, showSQL) {
|
|
|
84
80
|
}
|
|
85
81
|
if (showSQL) {
|
|
86
82
|
console.log('');
|
|
87
|
-
console.log(`${
|
|
83
|
+
console.log(`${cli_utils_1.colors.bold('SQL:')}`);
|
|
88
84
|
for (const change of sorted) {
|
|
89
85
|
const sql = (0, change_tracker_1.generateChangeSQL)(change);
|
|
90
86
|
if (sql)
|
|
91
|
-
console.log(`${
|
|
87
|
+
console.log(`${cli_utils_1.colors.cyan(sql)}`);
|
|
92
88
|
}
|
|
93
89
|
}
|
|
94
90
|
console.log('');
|
|
95
|
-
console.log(`${
|
|
91
|
+
console.log(`${cli_utils_1.colors.muted('Use')} ${cli_utils_1.colors.cyan('relq commit -m "message"')} ${cli_utils_1.colors.muted('to commit.')}`);
|
|
96
92
|
console.log('');
|
|
97
93
|
}
|
|
98
94
|
async function showOriginDiff(config, projectRoot, showSQL) {
|
|
99
95
|
const connection = config.connection;
|
|
100
|
-
const spinner = (0,
|
|
96
|
+
const spinner = (0, cli_utils_1.createSpinner)();
|
|
101
97
|
const snapshot = (0, repo_manager_1.loadSnapshot)(projectRoot);
|
|
102
98
|
if (!snapshot) {
|
|
103
|
-
console.log(`${
|
|
104
|
-
console.log(`${
|
|
99
|
+
console.log(`${cli_utils_1.colors.yellow('No local snapshot.')}`);
|
|
100
|
+
console.log(`${cli_utils_1.colors.muted('Run')} ${cli_utils_1.colors.cyan('relq pull')} ${cli_utils_1.colors.muted('first.')}`);
|
|
105
101
|
console.log('');
|
|
106
102
|
return;
|
|
107
103
|
}
|
|
@@ -114,22 +110,22 @@ async function showOriginDiff(config, projectRoot, showSQL) {
|
|
|
114
110
|
const diffs = compareSchemas(snapshot, remoteDb);
|
|
115
111
|
if (diffs.length === 0) {
|
|
116
112
|
console.log('');
|
|
117
|
-
console.log(
|
|
113
|
+
console.log('Local and remote are in sync.');
|
|
118
114
|
console.log('');
|
|
119
115
|
return;
|
|
120
116
|
}
|
|
121
117
|
console.log('');
|
|
122
|
-
console.log(`${
|
|
118
|
+
console.log(`${cli_utils_1.colors.bold('Differences:')}`);
|
|
123
119
|
console.log('');
|
|
124
120
|
for (const d of diffs.slice(0, 20)) {
|
|
125
|
-
const sym = d.type === 'added' ?
|
|
121
|
+
const sym = d.type === 'added' ? cli_utils_1.colors.green('+') : d.type === 'removed' ? cli_utils_1.colors.red('-') : cli_utils_1.colors.yellow('~');
|
|
126
122
|
console.log(` ${sym} ${d.description}`);
|
|
127
123
|
}
|
|
128
124
|
if (diffs.length > 20) {
|
|
129
|
-
console.log(` ${
|
|
125
|
+
console.log(` ${cli_utils_1.colors.muted(`... and ${diffs.length - 20} more`)}`);
|
|
130
126
|
}
|
|
131
127
|
console.log('');
|
|
132
|
-
console.log(`${
|
|
128
|
+
console.log(`${cli_utils_1.colors.muted('Use')} ${cli_utils_1.colors.cyan('relq pull')} ${cli_utils_1.colors.muted('to sync local with remote.')}`);
|
|
133
129
|
console.log('');
|
|
134
130
|
}
|
|
135
131
|
function compareSchemas(local, remote) {
|
|
@@ -45,8 +45,7 @@ const relqignore_1 = require("../utils/relqignore.cjs");
|
|
|
45
45
|
const config_1 = require("../../config/config.cjs");
|
|
46
46
|
async function exportCommand(context) {
|
|
47
47
|
const spinner = (0, spinner_1.createSpinner)();
|
|
48
|
-
const { args, flags } = context;
|
|
49
|
-
const projectRoot = process.cwd();
|
|
48
|
+
const { args, flags, projectRoot } = context;
|
|
50
49
|
const changesOnly = Boolean(flags['changes']);
|
|
51
50
|
const stagedOnly = Boolean(flags['staged']);
|
|
52
51
|
const fromDb = Boolean(flags['db']);
|
|
@@ -111,7 +110,7 @@ async function exportFromSnapshot(projectRoot, absoluteOutputPath, options) {
|
|
|
111
110
|
console.log(` ${spinner_1.colors.green('•')} Triggers: ${filteredSnapshot.triggers.length}`);
|
|
112
111
|
}
|
|
113
112
|
if (ignoredCount > 0) {
|
|
114
|
-
console.log(` ${spinner_1.colors.muted(
|
|
113
|
+
console.log(` ${spinner_1.colors.muted(`${ignoredCount} object(s) filtered by .relqignore`)}`);
|
|
115
114
|
}
|
|
116
115
|
spinner.start('Generating SQL statements');
|
|
117
116
|
const sqlContent = generateFullSQL(schema, options);
|
|
@@ -123,7 +122,7 @@ async function exportFromSnapshot(projectRoot, absoluteOutputPath, options) {
|
|
|
123
122
|
fs.writeFileSync(absoluteOutputPath, sqlContent, 'utf-8');
|
|
124
123
|
spinner.succeed(`Written ${options.output} (${(sqlContent.length / 1024).toFixed(1)} KB)`);
|
|
125
124
|
console.log('');
|
|
126
|
-
console.log(
|
|
125
|
+
console.log('Export completed');
|
|
127
126
|
console.log(` Source: ${spinner_1.colors.muted('snapshot (local)')}`);
|
|
128
127
|
console.log(` Output: ${spinner_1.colors.muted(options.output || '')}`);
|
|
129
128
|
}
|
|
@@ -163,7 +162,7 @@ async function exportFromDatabase(context, absoluteOutputPath, options) {
|
|
|
163
162
|
fs.writeFileSync(absoluteOutputPath, sqlContent, 'utf-8');
|
|
164
163
|
spinner.succeed(`Written ${options.output} (${(sqlContent.length / 1024).toFixed(1)} KB)`);
|
|
165
164
|
console.log('');
|
|
166
|
-
console.log(
|
|
165
|
+
console.log('Export completed');
|
|
167
166
|
console.log(` Source: ${spinner_1.colors.muted('database (live)')}`);
|
|
168
167
|
console.log(` Output: ${spinner_1.colors.muted(options.output || '')}`);
|
|
169
168
|
}
|
|
@@ -249,6 +248,7 @@ function normalizedToDbSchema(normalized) {
|
|
|
249
248
|
cycle: s.cycle,
|
|
250
249
|
ownedBy: s.ownedBy || undefined,
|
|
251
250
|
})),
|
|
251
|
+
collations: [],
|
|
252
252
|
extensions: normalized.extensions.map(e => e.name),
|
|
253
253
|
functions: (normalized.functions || []).map(f => ({
|
|
254
254
|
name: f.name,
|
|
@@ -296,7 +296,7 @@ async function exportChanges(projectRoot, flags, args, stagedOnly) {
|
|
|
296
296
|
modeLabel = 'uncommitted';
|
|
297
297
|
}
|
|
298
298
|
if (changes.length === 0) {
|
|
299
|
-
|
|
299
|
+
(0, spinner_1.warning)(`No ${modeLabel} changes to export`);
|
|
300
300
|
console.log('');
|
|
301
301
|
if (stagedOnly) {
|
|
302
302
|
console.log(`${spinner_1.colors.muted('Run')} ${spinner_1.colors.cyan('relq add .')} ${spinner_1.colors.muted('to stage changes.')}`);
|
|
@@ -325,7 +325,7 @@ async function exportChanges(projectRoot, flags, args, stagedOnly) {
|
|
|
325
325
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
326
326
|
}
|
|
327
327
|
fs.writeFileSync(absoluteOutputPath, sqlContent, 'utf-8');
|
|
328
|
-
console.log(
|
|
328
|
+
console.log(`Exported ${changes.length} ${modeLabel} change(s) to ${outputPath}`);
|
|
329
329
|
console.log(`${spinner_1.colors.muted(`${(sqlContent.length / 1024).toFixed(1)} KB`)}`);
|
|
330
330
|
console.log('');
|
|
331
331
|
}
|
|
@@ -3,33 +3,28 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.fetchCommand = fetchCommand;
|
|
4
4
|
const config_loader_1 = require("../utils/config-loader.cjs");
|
|
5
5
|
const env_loader_1 = require("../utils/env-loader.cjs");
|
|
6
|
-
const
|
|
6
|
+
const cli_utils_1 = require("../utils/cli-utils.cjs");
|
|
7
7
|
const repo_manager_1 = require("../utils/repo-manager.cjs");
|
|
8
8
|
async function fetchCommand(context) {
|
|
9
9
|
const { config, flags } = context;
|
|
10
10
|
if (!config) {
|
|
11
|
-
|
|
12
|
-
process.exit(1);
|
|
11
|
+
(0, cli_utils_1.fatal)('No configuration found', `run ${cli_utils_1.colors.cyan('relq init')} to create a configuration file`);
|
|
13
12
|
}
|
|
14
|
-
(0, config_loader_1.requireValidConfig)(config);
|
|
13
|
+
await (0, config_loader_1.requireValidConfig)(config, { calledFrom: 'fetch' });
|
|
15
14
|
const connection = config.connection;
|
|
16
|
-
const projectRoot =
|
|
15
|
+
const { projectRoot } = context;
|
|
17
16
|
console.log('');
|
|
18
17
|
if (!(0, repo_manager_1.isInitialized)(projectRoot)) {
|
|
19
|
-
|
|
20
|
-
console.log('');
|
|
21
|
-
console.log(`${spinner_1.colors.muted('Run')} ${spinner_1.colors.cyan('relq init')} ${spinner_1.colors.muted('to initialize.')}`);
|
|
22
|
-
return;
|
|
18
|
+
(0, cli_utils_1.fatal)('not a relq repository (or any parent directories): .relq', "run 'relq init' to initialize");
|
|
23
19
|
}
|
|
24
|
-
const spinner = (0,
|
|
20
|
+
const spinner = (0, cli_utils_1.createSpinner)();
|
|
25
21
|
spinner.start(`Fetching from ${(0, env_loader_1.getConnectionDescription)(connection)}...`);
|
|
26
22
|
try {
|
|
27
23
|
await (0, repo_manager_1.ensureRemoteTable)(connection);
|
|
28
24
|
const remoteCommits = await (0, repo_manager_1.fetchRemoteCommits)(connection, 100);
|
|
29
25
|
if (remoteCommits.length === 0) {
|
|
30
26
|
spinner.succeed('No remote commits found');
|
|
31
|
-
|
|
32
|
-
console.log(`${spinner_1.colors.muted('Run')} ${spinner_1.colors.cyan('relq push')} ${spinner_1.colors.muted('to push your commits.')}`);
|
|
27
|
+
(0, cli_utils_1.hint)("run 'relq push' to push your commits");
|
|
33
28
|
return;
|
|
34
29
|
}
|
|
35
30
|
let newCommits = 0;
|
|
@@ -50,25 +45,24 @@ async function fetchCommand(context) {
|
|
|
50
45
|
const ahead = [...localCommits].filter(h => !remoteHashes.has(h)).length;
|
|
51
46
|
console.log('');
|
|
52
47
|
if (behind > 0 && ahead > 0) {
|
|
53
|
-
console.log(`Your branch and 'origin/main' have diverged
|
|
54
|
-
console.log(`
|
|
48
|
+
console.log(`Your branch and 'origin/main' have diverged,`);
|
|
49
|
+
console.log(`and have ${ahead} and ${behind} different commits each, respectively.`);
|
|
55
50
|
}
|
|
56
51
|
else if (behind > 0) {
|
|
57
|
-
console.log(`Your branch is ${
|
|
58
|
-
|
|
52
|
+
console.log(`Your branch is behind 'origin/main' by ${behind} commit(s).`);
|
|
53
|
+
(0, cli_utils_1.hint)("run 'relq pull' to update your local branch");
|
|
59
54
|
}
|
|
60
55
|
else if (ahead > 0) {
|
|
61
|
-
console.log(`Your branch is ${
|
|
62
|
-
|
|
56
|
+
console.log(`Your branch is ahead of 'origin/main' by ${ahead} commit(s).`);
|
|
57
|
+
(0, cli_utils_1.hint)("run 'relq push' to publish your local commits");
|
|
63
58
|
}
|
|
64
59
|
else {
|
|
65
|
-
console.log(
|
|
60
|
+
console.log("Your branch is up to date with 'origin/main'.");
|
|
66
61
|
}
|
|
67
62
|
}
|
|
68
63
|
catch (error) {
|
|
69
64
|
spinner.fail('Fetch failed');
|
|
70
|
-
|
|
71
|
-
process.exit(1);
|
|
65
|
+
(0, cli_utils_1.fatal)('Fetch failed', error instanceof Error ? error.message : String(error));
|
|
72
66
|
}
|
|
73
67
|
console.log('');
|
|
74
68
|
}
|
|
@@ -44,32 +44,7 @@ const schema_diff_1 = require("../utils/schema-diff.cjs");
|
|
|
44
44
|
const schema_hash_1 = require("../utils/schema-hash.cjs");
|
|
45
45
|
const migration_generator_1 = require("../utils/migration-generator.cjs");
|
|
46
46
|
const env_loader_1 = require("../utils/env-loader.cjs");
|
|
47
|
-
const
|
|
48
|
-
reset: '\x1b[0m',
|
|
49
|
-
bold: '\x1b[1m',
|
|
50
|
-
dim: '\x1b[2m',
|
|
51
|
-
red: '\x1b[31m',
|
|
52
|
-
green: '\x1b[32m',
|
|
53
|
-
yellow: '\x1b[33m',
|
|
54
|
-
cyan: '\x1b[36m',
|
|
55
|
-
};
|
|
56
|
-
function askConfirm(question, defaultYes = false) {
|
|
57
|
-
const rl = readline.createInterface({
|
|
58
|
-
input: process.stdin,
|
|
59
|
-
output: process.stdout,
|
|
60
|
-
});
|
|
61
|
-
const suffix = defaultYes ? '[Y/n]' : '[y/N]';
|
|
62
|
-
return new Promise((resolve) => {
|
|
63
|
-
rl.question(`${question} ${suffix}: `, (answer) => {
|
|
64
|
-
rl.close();
|
|
65
|
-
const a = answer.trim().toLowerCase();
|
|
66
|
-
if (!a)
|
|
67
|
-
resolve(defaultYes);
|
|
68
|
-
else
|
|
69
|
-
resolve(a === 'y' || a === 'yes');
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
}
|
|
47
|
+
const cli_utils_1 = require("../utils/cli-utils.cjs");
|
|
73
48
|
function askInput(question) {
|
|
74
49
|
const rl = readline.createInterface({
|
|
75
50
|
input: process.stdin,
|
|
@@ -85,10 +60,10 @@ function askInput(question) {
|
|
|
85
60
|
async function generateCommand(context) {
|
|
86
61
|
const { config, args, flags } = context;
|
|
87
62
|
if (!config) {
|
|
88
|
-
|
|
89
|
-
|
|
63
|
+
(0, cli_utils_1.fatal)('No configuration found', `run ${cli_utils_1.colors.cyan('relq init')} to create a configuration file`);
|
|
64
|
+
return;
|
|
90
65
|
}
|
|
91
|
-
(0, config_loader_1.requireValidConfig)(config);
|
|
66
|
+
await (0, config_loader_1.requireValidConfig)(config, { calledFrom: 'generate' });
|
|
92
67
|
const connection = config.connection;
|
|
93
68
|
const migrationsDir = config.migrations?.directory || './migrations';
|
|
94
69
|
const snapshotPath = config.sync?.snapshot || '.relq/snapshot.json';
|
|
@@ -111,10 +86,10 @@ async function generateCommand(context) {
|
|
|
111
86
|
migrationName = message.replace(/\s+/g, '_').toLowerCase();
|
|
112
87
|
}
|
|
113
88
|
if (!migrationName && !isEmpty) {
|
|
114
|
-
migrationName = await askInput(
|
|
89
|
+
migrationName = await askInput('Migration name: ');
|
|
115
90
|
if (!migrationName) {
|
|
116
|
-
|
|
117
|
-
|
|
91
|
+
(0, cli_utils_1.fatal)('Migration name is required');
|
|
92
|
+
return;
|
|
118
93
|
}
|
|
119
94
|
}
|
|
120
95
|
if (isEmpty) {
|
|
@@ -122,48 +97,48 @@ async function generateCommand(context) {
|
|
|
122
97
|
await createEmptyMigration(migrationsDir, migrationName, format, dryRun);
|
|
123
98
|
return;
|
|
124
99
|
}
|
|
125
|
-
console.log(
|
|
100
|
+
console.log('Generating migration...');
|
|
126
101
|
console.log(` Connection: ${(0, env_loader_1.getConnectionDescription)(connection)}`);
|
|
127
102
|
console.log('');
|
|
128
103
|
try {
|
|
129
104
|
const dbSchema = await (0, schema_introspect_1.introspectDatabase)(connection);
|
|
130
105
|
const snapshot = (0, snapshot_manager_1.loadSnapshot)(snapshotPath);
|
|
131
106
|
if (!snapshot) {
|
|
132
|
-
|
|
133
|
-
console.log(
|
|
107
|
+
(0, cli_utils_1.warning)('No snapshot found.');
|
|
108
|
+
console.log('Run "relq pull" first to create initial snapshot.');
|
|
134
109
|
return;
|
|
135
110
|
}
|
|
136
111
|
const localSchema = (0, snapshot_manager_1.snapshotToDatabaseSchema)(snapshot);
|
|
137
112
|
const diff = (0, schema_diff_1.diffSchemas)((0, schema_hash_1.normalizeSchema)(localSchema), (0, schema_hash_1.normalizeSchema)(dbSchema));
|
|
138
113
|
const filteredDiff = (0, schema_diff_1.filterDiff)(diff, ignorePatterns);
|
|
139
114
|
if (!filteredDiff.hasChanges) {
|
|
140
|
-
console.log(
|
|
115
|
+
console.log('No changes to generate.');
|
|
141
116
|
return;
|
|
142
117
|
}
|
|
143
118
|
const s = filteredDiff.summary;
|
|
144
|
-
console.log(
|
|
119
|
+
console.log('Changes to include:');
|
|
145
120
|
if (s.tablesAdded > 0)
|
|
146
|
-
console.log(`
|
|
121
|
+
console.log(` + ${s.tablesAdded} table(s)`);
|
|
147
122
|
if (s.tablesRemoved > 0)
|
|
148
|
-
console.log(`
|
|
123
|
+
console.log(` - ${s.tablesRemoved} table(s)`);
|
|
149
124
|
if (s.tablesModified > 0)
|
|
150
|
-
console.log(`
|
|
125
|
+
console.log(` ~ ${s.tablesModified} table(s) modified`);
|
|
151
126
|
if (s.columnsAdded > 0)
|
|
152
|
-
console.log(`
|
|
127
|
+
console.log(` + ${s.columnsAdded} column(s)`);
|
|
153
128
|
if (s.columnsRemoved > 0)
|
|
154
|
-
console.log(`
|
|
129
|
+
console.log(` - ${s.columnsRemoved} column(s)`);
|
|
155
130
|
if (s.columnsModified > 0)
|
|
156
|
-
console.log(`
|
|
131
|
+
console.log(` ~ ${s.columnsModified} column(s)`);
|
|
157
132
|
console.log('');
|
|
158
133
|
if ((0, schema_diff_1.hasDestructiveChanges)(filteredDiff)) {
|
|
159
134
|
const tables = (0, schema_diff_1.getDestructiveTables)(filteredDiff);
|
|
160
|
-
|
|
135
|
+
(0, cli_utils_1.warning)('Destructive changes:');
|
|
161
136
|
for (const t of tables) {
|
|
162
|
-
console.log(`
|
|
137
|
+
console.log(` - ${t}`);
|
|
163
138
|
}
|
|
164
139
|
console.log('');
|
|
165
140
|
if (!autoStage) {
|
|
166
|
-
const proceed = await
|
|
141
|
+
const proceed = await (0, cli_utils_1.confirm)('Include destructive changes?', false);
|
|
167
142
|
if (!proceed) {
|
|
168
143
|
console.log('Cancelled.');
|
|
169
144
|
return;
|
|
@@ -185,7 +160,7 @@ async function generateCommand(context) {
|
|
|
185
160
|
}
|
|
186
161
|
const filePath = path.join(migrationsDir, fileName);
|
|
187
162
|
if (dryRun) {
|
|
188
|
-
console.log(
|
|
163
|
+
console.log(`[dry-run] Would create: ${filePath}`);
|
|
189
164
|
console.log('');
|
|
190
165
|
console.log('--- Generated SQL ---');
|
|
191
166
|
console.log(migrationFile.content);
|
|
@@ -196,16 +171,15 @@ async function generateCommand(context) {
|
|
|
196
171
|
fs.mkdirSync(migrationsDir, { recursive: true });
|
|
197
172
|
}
|
|
198
173
|
fs.writeFileSync(filePath, migrationFile.content, 'utf-8');
|
|
199
|
-
console.log(
|
|
174
|
+
console.log(`Created: ${filePath}`);
|
|
200
175
|
(0, snapshot_manager_1.saveSnapshot)(dbSchema, snapshotPath, connection.database);
|
|
201
|
-
console.log(
|
|
176
|
+
console.log('Updated snapshot.');
|
|
202
177
|
}
|
|
203
178
|
console.log('');
|
|
204
|
-
console.log(
|
|
179
|
+
console.log('Run "relq push" to apply this migration.');
|
|
205
180
|
}
|
|
206
181
|
catch (error) {
|
|
207
|
-
|
|
208
|
-
process.exit(1);
|
|
182
|
+
(0, cli_utils_1.fatal)('Generation failed', error instanceof Error ? error.message : String(error));
|
|
209
183
|
}
|
|
210
184
|
}
|
|
211
185
|
async function createEmptyMigration(migrationsDir, name, format, dryRun) {
|
|
@@ -230,13 +204,13 @@ async function createEmptyMigration(migrationsDir, name, format, dryRun) {
|
|
|
230
204
|
|
|
231
205
|
`;
|
|
232
206
|
if (dryRun) {
|
|
233
|
-
console.log(
|
|
207
|
+
console.log(`[dry-run] Would create: ${filePath}`);
|
|
234
208
|
}
|
|
235
209
|
else {
|
|
236
210
|
if (!fs.existsSync(migrationsDir)) {
|
|
237
211
|
fs.mkdirSync(migrationsDir, { recursive: true });
|
|
238
212
|
}
|
|
239
213
|
fs.writeFileSync(filePath, content, 'utf-8');
|
|
240
|
-
console.log(
|
|
214
|
+
console.log(`Created empty migration: ${filePath}`);
|
|
241
215
|
}
|
|
242
216
|
}
|