drizzle-auto 1.1.4 → 1.1.6
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 +138 -120
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -5,177 +5,195 @@ const { spawn } = require("child_process");
|
|
|
5
5
|
const path = require("path");
|
|
6
6
|
const fs = require("fs");
|
|
7
7
|
|
|
8
|
-
/*
|
|
9
|
-
🎨
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
8
|
+
/* =============================================================
|
|
9
|
+
🎨 NEON-PULSE UI CORE (ChatGPT-Like Aesthetics)
|
|
10
|
+
============================================================= */
|
|
11
|
+
const T = {
|
|
12
|
+
reset: "\x1b[0m",
|
|
13
|
+
bold: "\x1b[1m",
|
|
14
|
+
italic: "\x1b[3m",
|
|
15
|
+
underline: "\x1b[4m",
|
|
16
|
+
cyan: "\x1b[38;5;51m",
|
|
17
|
+
pink: "\x1b[38;5;201m",
|
|
18
|
+
lime: "\x1b[38;5;118m",
|
|
19
|
+
yellow: "\x1b[38;5;226m",
|
|
20
|
+
red: "\x1b[38;5;196m",
|
|
21
|
+
gray: "\x1b[38;5;244m",
|
|
22
|
+
bg_dark: "\x1b[48;5;234m"
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const rainbow = (text) => {
|
|
26
|
+
const colors = [196, 208, 226, 118, 51, 201];
|
|
27
|
+
return text.split('').map((char, i) => `\x1b[38;5;${colors[i % colors.length]}m${char}`).join('') + T.reset;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/* =============================================================
|
|
31
|
+
💾 AUTO SCRIPT INJECTOR (tea)
|
|
32
|
+
============================================================= */
|
|
33
|
+
const ROOT = process.cwd();
|
|
34
|
+
const PKG = path.join(ROOT, "package.json");
|
|
35
|
+
|
|
36
|
+
function injectTea() {
|
|
37
|
+
if (!fs.existsSync(PKG)) return;
|
|
38
|
+
try {
|
|
39
|
+
const pkg = JSON.parse(fs.readFileSync(PKG, "utf8"));
|
|
40
|
+
pkg.scripts ||= {};
|
|
41
|
+
if (!pkg.scripts.tea) {
|
|
42
|
+
pkg.scripts.tea = "drizzle-auto";
|
|
43
|
+
fs.writeFileSync(PKG, JSON.stringify(pkg, null, 2));
|
|
44
|
+
console.log(`${T.cyan}☕ Script injected → ${T.bold}npm run tea${T.reset}`);
|
|
45
|
+
} else {
|
|
46
|
+
console.log(`${T.gray}☕ Tea script already exists${T.reset}`);
|
|
47
|
+
}
|
|
48
|
+
} catch (e) {
|
|
49
|
+
console.log(`${T.red}⚠ Failed to inject tea script:${T.reset} ${e.message}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Run injection immediately
|
|
54
|
+
injectTea();
|
|
55
|
+
|
|
56
|
+
/* =============================================================
|
|
57
|
+
⏳ HIGH-FIDELITY SPINNER & LOADING
|
|
58
|
+
============================================================= */
|
|
59
|
+
const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
60
|
+
let spinIdx = 0;
|
|
61
|
+
let spinInterval;
|
|
62
|
+
|
|
63
|
+
function startLoading(msg) {
|
|
64
|
+
stopLoading();
|
|
65
|
+
spinInterval = setInterval(() => {
|
|
66
|
+
process.stdout.write(`\r${T.cyan}${frames[spinIdx++ % frames.length]}${T.reset} ${T.bold}${msg}${T.reset} `);
|
|
31
67
|
}, 80);
|
|
32
68
|
}
|
|
33
69
|
|
|
34
|
-
function
|
|
35
|
-
if (
|
|
36
|
-
clearInterval(
|
|
37
|
-
|
|
38
|
-
process.stdout.write("\r\x1b[K");
|
|
70
|
+
function stopLoading() {
|
|
71
|
+
if (spinInterval) {
|
|
72
|
+
clearInterval(spinInterval);
|
|
73
|
+
spinInterval = null;
|
|
74
|
+
process.stdout.write("\r\x1b[K"); // Clear current line
|
|
39
75
|
}
|
|
40
76
|
}
|
|
41
77
|
|
|
42
|
-
/*
|
|
43
|
-
🧠
|
|
44
|
-
|
|
78
|
+
/* =============================================================
|
|
79
|
+
🧠 LOGIC & CRASH PROTECTION
|
|
80
|
+
============================================================= */
|
|
45
81
|
let isRunning = false;
|
|
46
|
-
let
|
|
82
|
+
let hasError = false;
|
|
47
83
|
|
|
48
|
-
//
|
|
49
|
-
function
|
|
84
|
+
// Dynamic File Justification
|
|
85
|
+
function justifyStructure() {
|
|
50
86
|
const root = process.cwd();
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const config = ["ts", "js", "mjs", "mts"]
|
|
54
|
-
.map(ext => `drizzle.config.${ext}`)
|
|
87
|
+
const config = ["ts", "js", "mjs", "mts", "cjs"]
|
|
88
|
+
.map(e => `drizzle.config.${e}`)
|
|
55
89
|
.find(f => fs.existsSync(path.join(root, f)));
|
|
56
|
-
|
|
57
|
-
if (!config) return { ok: false, msg: "drizzle.config
|
|
58
|
-
|
|
59
|
-
// চেক ২: স্কিমা ফাইল জাস্টিফিকেশন (কনফিগ থেকে ডাইনামিকালি পাথ রিড করা)
|
|
90
|
+
|
|
91
|
+
if (!config) return { ok: false, msg: "Missing drizzle.config.*" };
|
|
92
|
+
|
|
60
93
|
try {
|
|
61
94
|
const content = fs.readFileSync(path.join(root, config), "utf8");
|
|
62
95
|
const schemaMatch = content.match(/schema:\s*["'](.+?)["']/);
|
|
63
96
|
if (schemaMatch && schemaMatch[1]) {
|
|
64
|
-
|
|
65
|
-
|
|
97
|
+
if (!fs.existsSync(path.resolve(root, schemaMatch[1]))) {
|
|
98
|
+
return { ok: false, msg: `Schema not found: ${schemaMatch[1]}` };
|
|
99
|
+
}
|
|
66
100
|
}
|
|
67
|
-
} catch (e) {
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return { ok: true };
|
|
101
|
+
} catch (e) { return { ok: false, msg: "Config parse error" }; }
|
|
102
|
+
|
|
103
|
+
return { ok: true, config };
|
|
72
104
|
}
|
|
73
105
|
|
|
74
|
-
//
|
|
75
|
-
function
|
|
106
|
+
// Secure Step Execution
|
|
107
|
+
function runStep(args, label) {
|
|
76
108
|
return new Promise((resolve) => {
|
|
77
|
-
|
|
78
|
-
|
|
109
|
+
startLoading(`${T.pink}${label}${T.reset}`);
|
|
110
|
+
let localErr = false;
|
|
79
111
|
|
|
80
|
-
const child = spawn("npx", args, { shell: true });
|
|
112
|
+
const child = spawn("npx", args, { shell: true, stdio: ["inherit", "pipe", "pipe"] });
|
|
81
113
|
|
|
82
114
|
child.stdout.on("data", (data) => {
|
|
83
115
|
const out = data.toString();
|
|
84
|
-
// Spam filter for cloud/server-side DB pulling logs
|
|
85
116
|
if (!out.includes('Pulling schema')) {
|
|
86
|
-
|
|
87
|
-
process.stdout.write(`${
|
|
117
|
+
stopLoading();
|
|
118
|
+
process.stdout.write(`${T.gray}${out}${T.reset}`);
|
|
88
119
|
}
|
|
89
|
-
if (/error|failed|ENOTFOUND
|
|
120
|
+
if (/error|failed|ENOTFOUND/i.test(out)) localErr = true;
|
|
90
121
|
});
|
|
91
122
|
|
|
92
123
|
child.stderr.on("data", (data) => {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
hasError = true;
|
|
124
|
+
stopLoading();
|
|
125
|
+
process.stderr.write(`${T.red}${T.bold}✖ ${data}${T.reset}`);
|
|
126
|
+
localErr = true;
|
|
97
127
|
});
|
|
98
128
|
|
|
99
129
|
child.on("close", (code) => {
|
|
100
|
-
|
|
101
|
-
resolve(code === 0 && !
|
|
130
|
+
stopLoading();
|
|
131
|
+
resolve(code === 0 && !localErr);
|
|
102
132
|
});
|
|
103
133
|
});
|
|
104
134
|
}
|
|
105
135
|
|
|
106
|
-
/*
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
async function
|
|
136
|
+
/* =============================================================
|
|
137
|
+
🔁 THE ENGINE WORKFLOW
|
|
138
|
+
============================================================= */
|
|
139
|
+
async function triggerEngine(event) {
|
|
110
140
|
if (isRunning) return;
|
|
111
141
|
isRunning = true;
|
|
112
142
|
|
|
113
|
-
if (!
|
|
114
|
-
console.log(
|
|
115
|
-
console.log(`${
|
|
143
|
+
if (!hasError) console.clear();
|
|
144
|
+
console.log(`\n${T.bg_dark} ${rainbow(" DRIZZLE-AUTO v2026 ")} ${T.reset}`);
|
|
145
|
+
console.log(`${T.pink}●${T.reset} ${T.bold}Event:${T.reset} ${T.cyan}${event}${T.reset}\n`);
|
|
116
146
|
|
|
117
|
-
//
|
|
118
|
-
const audit =
|
|
147
|
+
// Step 2: Infrastructure Audit
|
|
148
|
+
const audit = justifyStructure();
|
|
119
149
|
if (!audit.ok) {
|
|
120
|
-
console.log(
|
|
121
|
-
|
|
122
|
-
isRunning = false;
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// STEP 3: Confirm no bug in code (Integrity Check)
|
|
127
|
-
const step3 = await executeCommand(["drizzle-kit", "check"], "Step 3: Bug Check");
|
|
128
|
-
if (!step3) {
|
|
129
|
-
console.log(`\n\x1b[31m🛑 STEP 3 FAILED: Bugs or Drifts detected. Halting Pipeline.${RESET}`);
|
|
130
|
-
hasActiveError = true;
|
|
131
|
-
isRunning = false;
|
|
132
|
-
return;
|
|
150
|
+
console.log(`${T.red}${T.bold}🛑 CRITICAL FAILURE:${T.reset} ${audit.msg}`);
|
|
151
|
+
hasError = true; isRunning = false; return;
|
|
133
152
|
}
|
|
134
153
|
|
|
135
|
-
//
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
hasActiveError = true;
|
|
149
|
-
isRunning = false;
|
|
150
|
-
return;
|
|
154
|
+
// Step 3-5: Execution Chain
|
|
155
|
+
const steps = [
|
|
156
|
+
{ name: "Confirming Integrity", args: ["drizzle-kit", "check"] },
|
|
157
|
+
{ name: "Generating Migrations", args: ["drizzle-kit", "generate"] },
|
|
158
|
+
{ name: "Pushing to Database", args: ["drizzle-kit", "push"] }
|
|
159
|
+
];
|
|
160
|
+
|
|
161
|
+
for (const step of steps) {
|
|
162
|
+
const success = await runStep(step.args, step.name);
|
|
163
|
+
if (!success) {
|
|
164
|
+
console.log(`\n${T.red}${T.bold}✖ PIPELINE CRASHED AT [${step.name.toUpperCase()}]${T.reset}`);
|
|
165
|
+
hasError = true; isRunning = false; return;
|
|
166
|
+
}
|
|
151
167
|
}
|
|
152
168
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
console.log(
|
|
156
|
-
|
|
157
|
-
setTimeout(() => {
|
|
158
|
-
isRunning = false;
|
|
159
|
-
console.log(`\n${DIM}🛰️ System justified. Watching for next change...${RESET}`);
|
|
160
|
-
}, 2000);
|
|
169
|
+
hasError = false;
|
|
170
|
+
console.log(`\n${T.lime}${T.bold}✔ SYSTEM JUSTIFIED & SYNCED${T.reset}`);
|
|
171
|
+
console.log(`${T.gray}Waiting for next server-side change...${T.reset}\n`);
|
|
172
|
+
isRunning = false;
|
|
161
173
|
}
|
|
162
174
|
|
|
163
|
-
/*
|
|
164
|
-
👀
|
|
165
|
-
|
|
175
|
+
/* =============================================================
|
|
176
|
+
👀 UNIVERSAL WATCHER & CRASH SHIELD
|
|
177
|
+
============================================================= */
|
|
166
178
|
chokidar.watch(".", {
|
|
167
|
-
ignored: [/node_modules/, /\.git/, /\.next/, /dist
|
|
179
|
+
ignored: [/node_modules/, /\.git/, /\.next/, /dist/],
|
|
168
180
|
ignoreInitial: true,
|
|
169
181
|
usePolling: true,
|
|
170
182
|
interval: 300
|
|
171
|
-
}).on("all", (e, f) =>
|
|
183
|
+
}).on("all", (e, f) => triggerEngine(`${e.toUpperCase()} -> ${path.basename(f)}`));
|
|
172
184
|
|
|
173
|
-
//
|
|
174
|
-
|
|
185
|
+
// Initial Ignition
|
|
186
|
+
triggerEngine("Initial Audit");
|
|
175
187
|
|
|
176
|
-
//
|
|
188
|
+
// Global Crash Protection
|
|
177
189
|
process.on("uncaughtException", (err) => {
|
|
178
|
-
|
|
179
|
-
console.log(`\n
|
|
190
|
+
stopLoading();
|
|
191
|
+
console.log(`\n${T.red}${T.bold}🛡️ PROTECTIVE SHIELD:${T.reset} ${err.message}`);
|
|
180
192
|
isRunning = false;
|
|
181
193
|
});
|
|
194
|
+
|
|
195
|
+
process.on("SIGINT", () => {
|
|
196
|
+
stopLoading();
|
|
197
|
+
console.log(`\n${T.yellow}Shutting down Drizzle-Auto...${T.reset}`);
|
|
198
|
+
process.exit();
|
|
199
|
+
});
|