drizzle-auto 1.1.29 → 1.1.30
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/index.js +47 -50
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* 🍵 Drizzle-Auto v2.
|
|
5
|
-
* 🔹
|
|
4
|
+
* 🍵 Drizzle-Auto v2.2 - Strict Validation Edition
|
|
5
|
+
* 🔹 Checks Config -> Checks Schema -> Runs Drizzle
|
|
6
6
|
* 🔹 Strictly catches WebSocket/Neon ENOTFOUND errors
|
|
7
7
|
* 🔹 Stops immediately on any failure
|
|
8
8
|
*/
|
|
@@ -16,13 +16,8 @@ try { require("ts-node").register({ transpileOnly: true }); } catch (e) {}
|
|
|
16
16
|
|
|
17
17
|
// ---------------------- COLORS & UI ----------------------
|
|
18
18
|
const T = {
|
|
19
|
-
reset: "\x1b[0m",
|
|
20
|
-
|
|
21
|
-
cyan: "\x1b[38;5;51m",
|
|
22
|
-
lime: "\x1b[38;5;118m",
|
|
23
|
-
yellow: "\x1b[38;5;226m",
|
|
24
|
-
red: "\x1b[38;5;196m",
|
|
25
|
-
gray: "\x1b[38;5;244m",
|
|
19
|
+
reset: "\x1b[0m", bold: "\x1b[1m", cyan: "\x1b[38;5;51m",
|
|
20
|
+
lime: "\x1b[38;5;118m", yellow: "\x1b[38;5;226m", red: "\x1b[38;5;196m", gray: "\x1b[38;5;244m",
|
|
26
21
|
};
|
|
27
22
|
|
|
28
23
|
const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
@@ -31,40 +26,49 @@ let spinIdx = 0, spinInterval;
|
|
|
31
26
|
function startLoading(msg) {
|
|
32
27
|
stopLoading();
|
|
33
28
|
spinInterval = setInterval(() => {
|
|
34
|
-
// FIXED: Corrected backticks for template literals
|
|
35
29
|
process.stdout.write(`\r${T.cyan}${frames[spinIdx++ % frames.length]}${T.reset} ${T.bold}${msg}${T.reset} `);
|
|
36
30
|
}, 80);
|
|
37
31
|
}
|
|
38
32
|
|
|
39
33
|
function stopLoading() {
|
|
40
|
-
if (spinInterval) {
|
|
41
|
-
|
|
42
|
-
spinInterval = null;
|
|
43
|
-
process.stdout.write("\r\x1b[K");
|
|
44
|
-
}
|
|
34
|
+
if (spinInterval) { clearInterval(spinInterval); spinInterval = null; }
|
|
35
|
+
process.stdout.write("\r\x1b[K");
|
|
45
36
|
}
|
|
46
37
|
|
|
47
|
-
// ----------------------
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
38
|
+
// ---------------------- VALIDATION LOGIC ----------------------
|
|
39
|
+
function validateProject() {
|
|
40
|
+
const root = process.cwd();
|
|
41
|
+
const configFiles = ["drizzle.config.ts", "drizzle.config.js", "drizzle.config.mjs", "drizzle.config.cjs"];
|
|
42
|
+
const configPath = configFiles.map(f => path.join(root, f)).find(f => fs.existsSync(f));
|
|
43
|
+
|
|
44
|
+
if (!configPath) {
|
|
45
|
+
return { ok: false, msg: "drizzle.config.[ts|js] not found in root." };
|
|
46
|
+
}
|
|
47
|
+
|
|
51
48
|
try {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
49
|
+
// Basic regex check for schema path to avoid complex module loading issues
|
|
50
|
+
const configContent = fs.readFileSync(configPath, "utf8");
|
|
51
|
+
const schemaMatch = configContent.match(/schema:\s*["'](.+?)["']/);
|
|
52
|
+
|
|
53
|
+
if (!schemaMatch) {
|
|
54
|
+
return { ok: false, msg: `Could not find 'schema' path inside ${path.basename(configPath)}` };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const schemaPath = path.resolve(root, schemaMatch[1]);
|
|
58
|
+
if (!fs.existsSync(schemaPath)) {
|
|
59
|
+
return { ok: false, msg: `Schema file defined in config does not exist: ${schemaMatch[1]}` };
|
|
58
60
|
}
|
|
59
|
-
|
|
61
|
+
|
|
62
|
+
return { ok: true, config: configPath, schema: schemaPath };
|
|
63
|
+
} catch (e) {
|
|
64
|
+
return { ok: false, msg: `Error reading config: ${e.message}` };
|
|
65
|
+
}
|
|
60
66
|
}
|
|
61
67
|
|
|
62
68
|
// ---------------------- COMMAND RUNNER (STRICT) ----------------------
|
|
63
69
|
function runCommand(cmd, label) {
|
|
64
70
|
return new Promise((resolve, reject) => {
|
|
65
71
|
startLoading(label);
|
|
66
|
-
|
|
67
|
-
// Use pipe for stderr to catch Neon driver WebSocket errors
|
|
68
72
|
const child = spawn(cmd, { shell: true, stdio: ["inherit", "inherit", "pipe"] });
|
|
69
73
|
let errorOutput = "";
|
|
70
74
|
|
|
@@ -76,12 +80,9 @@ function runCommand(cmd, label) {
|
|
|
76
80
|
|
|
77
81
|
child.on("close", (code) => {
|
|
78
82
|
stopLoading();
|
|
79
|
-
|
|
80
|
-
// Detection for WebSocket/Neon ENOTFOUND or standard failures
|
|
81
83
|
const hasDriverError = /ErrorEvent|ENOTFOUND|failed to connect|syscall: 'getaddrinfo'/i.test(errorOutput);
|
|
82
|
-
|
|
83
84
|
if (code !== 0 || hasDriverError) {
|
|
84
|
-
reject(new Error(`${label} failed
|
|
85
|
+
reject(new Error(`${label} failed.`));
|
|
85
86
|
} else {
|
|
86
87
|
resolve();
|
|
87
88
|
}
|
|
@@ -102,6 +103,16 @@ async function triggerEngine() {
|
|
|
102
103
|
if (isRunning) return;
|
|
103
104
|
isRunning = true;
|
|
104
105
|
|
|
106
|
+
// 1. Check Config and Schema first
|
|
107
|
+
const check = validateProject();
|
|
108
|
+
if (!check.ok) {
|
|
109
|
+
console.log(`\n${T.red}${T.bold}📁 CONFIG ERROR:${T.reset} ${check.msg}`);
|
|
110
|
+
isBroken = true;
|
|
111
|
+
isRunning = false;
|
|
112
|
+
if (process.argv.includes('--postinstall')) process.exit(1);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
105
116
|
try {
|
|
106
117
|
const steps = [
|
|
107
118
|
{ name: "Integrity Check", cmd: "npx drizzle-kit check" },
|
|
@@ -118,32 +129,25 @@ async function triggerEngine() {
|
|
|
118
129
|
} catch (err) {
|
|
119
130
|
isBroken = true;
|
|
120
131
|
console.log(`\n${T.red}${T.bold}🚨 CRITICAL STOP:${T.reset} ${err.message}`);
|
|
121
|
-
console.log(`${T.yellow}Execution paused. Fix the
|
|
122
|
-
|
|
123
|
-
if (process.argv.includes('--postinstall')) {
|
|
124
|
-
process.exit(1);
|
|
125
|
-
}
|
|
132
|
+
console.log(`${T.yellow}Execution paused. Fix the code/connection and save to retry.${T.reset}\n`);
|
|
133
|
+
if (process.argv.includes('--postinstall')) process.exit(1);
|
|
126
134
|
} finally {
|
|
127
135
|
isRunning = false;
|
|
128
136
|
}
|
|
129
137
|
}
|
|
130
138
|
|
|
131
139
|
// ---------------------- MAIN / WATCHER ----------------------
|
|
132
|
-
injectScript();
|
|
133
|
-
|
|
134
140
|
const skipWatcher = process.argv.includes('--postinstall');
|
|
135
141
|
|
|
136
142
|
if (skipWatcher) {
|
|
137
143
|
triggerEngine();
|
|
138
144
|
} else {
|
|
139
145
|
triggerEngine();
|
|
140
|
-
|
|
141
146
|
try {
|
|
142
147
|
const chokidar = require("chokidar");
|
|
143
148
|
let debounceTimer;
|
|
144
|
-
|
|
145
149
|
const watcher = chokidar.watch(".", {
|
|
146
|
-
ignored: [/node_modules/, /\.git/, /\.next/, /dist
|
|
150
|
+
ignored: [/node_modules/, /\.git/, /\.next/, /dist/],
|
|
147
151
|
ignoreInitial: true,
|
|
148
152
|
usePolling: true,
|
|
149
153
|
interval: 300
|
|
@@ -156,20 +160,13 @@ if (skipWatcher) {
|
|
|
156
160
|
triggerEngine();
|
|
157
161
|
}, 500);
|
|
158
162
|
});
|
|
159
|
-
|
|
160
163
|
console.log(`${T.gray}👀 Watching for schema changes...${T.reset}`);
|
|
161
164
|
} catch (e) {
|
|
162
165
|
console.log(`${T.yellow}⚠ Chokidar not found. Watch mode disabled.${T.reset}`);
|
|
163
166
|
}
|
|
164
167
|
}
|
|
165
168
|
|
|
166
|
-
// ---------------------- GLOBAL ERROR CATCH ----------------------
|
|
167
|
-
process.on("uncaughtException", (err) => {
|
|
168
|
-
console.log(`\n${T.red}${T.bold}🛡️ UNCAUGHT ERROR:${T.reset} ${err.message}`);
|
|
169
|
-
process.exit(1);
|
|
170
|
-
});
|
|
171
|
-
|
|
172
169
|
process.on("SIGINT", () => {
|
|
173
|
-
console.log(`\n${T.yellow}Shutting down
|
|
170
|
+
console.log(`\n${T.yellow}Shutting down...${T.reset}`);
|
|
174
171
|
process.exit(0);
|
|
175
172
|
});
|