drizzle-auto 1.1.16 → 1.1.17
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 +87 -111
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* 🌟 Drizzle-Auto v2 - Server Style / Multi-Package Manager
|
|
5
|
+
* 🔹 Watches your project and auto-runs drizzle-kit steps
|
|
6
|
+
* 🔹 Works with npm, yarn, pnpm, bun, npx
|
|
7
|
+
* 🔹 Fully server-style logging
|
|
8
|
+
* 🔹 Neon-pulse colored UI with emojis
|
|
9
|
+
*/
|
|
10
|
+
|
|
3
11
|
const chokidar = require("chokidar");
|
|
4
12
|
const { spawn } = require("child_process");
|
|
5
13
|
const path = require("path");
|
|
6
14
|
const fs = require("fs");
|
|
7
15
|
|
|
8
16
|
/* =============================================================
|
|
9
|
-
🎨 NEON-PULSE UI
|
|
17
|
+
🎨 NEON-PULSE UI COLORS
|
|
10
18
|
============================================================= */
|
|
11
19
|
const T = {
|
|
12
20
|
reset: "\x1b[0m",
|
|
@@ -24,175 +32,143 @@ const T = {
|
|
|
24
32
|
};
|
|
25
33
|
|
|
26
34
|
/* =============================================================
|
|
27
|
-
⏳ SPINNER
|
|
35
|
+
⏳ SPINNER
|
|
28
36
|
============================================================= */
|
|
29
37
|
const frames = ["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];
|
|
30
|
-
let spinIdx = 0;
|
|
31
|
-
let spinInterval;
|
|
38
|
+
let spinIdx = 0, spinInterval;
|
|
32
39
|
|
|
33
|
-
function startLoading(msg)
|
|
40
|
+
function startLoading(msg){
|
|
34
41
|
stopLoading();
|
|
35
|
-
spinInterval = setInterval(()
|
|
42
|
+
spinInterval = setInterval(()=>{
|
|
36
43
|
process.stdout.write(`\r${T.cyan}${frames[spinIdx++ % frames.length]}${T.reset} ${T.bold}${msg}${T.reset} `);
|
|
37
44
|
}, 80);
|
|
38
45
|
}
|
|
39
46
|
|
|
40
|
-
function stopLoading()
|
|
41
|
-
if
|
|
47
|
+
function stopLoading(){
|
|
48
|
+
if(spinInterval){
|
|
42
49
|
clearInterval(spinInterval);
|
|
43
|
-
spinInterval
|
|
44
|
-
process.stdout.write("\r\x1b[K");
|
|
50
|
+
spinInterval=null;
|
|
51
|
+
process.stdout.write("\r\x1b[K");
|
|
45
52
|
}
|
|
46
53
|
}
|
|
47
54
|
|
|
48
55
|
/* =============================================================
|
|
49
56
|
🧩 AUTO SCRIPT INJECTOR
|
|
50
57
|
============================================================= */
|
|
51
|
-
const PKG = path.join(process.cwd(),
|
|
52
|
-
function injectScript()
|
|
53
|
-
if
|
|
54
|
-
const pkg = JSON.parse(fs.readFileSync(PKG,
|
|
58
|
+
const PKG = path.join(process.cwd(),"package.json");
|
|
59
|
+
function injectScript(){
|
|
60
|
+
if(!fs.existsSync(PKG)) return;
|
|
61
|
+
const pkg = JSON.parse(fs.readFileSync(PKG,"utf8"));
|
|
55
62
|
pkg.scripts ||= {};
|
|
56
|
-
if
|
|
57
|
-
pkg.scripts.
|
|
58
|
-
fs.writeFileSync(PKG, JSON.stringify(pkg,
|
|
59
|
-
console.log(`${T.lime}☕ Script added → npm run
|
|
63
|
+
if(!pkg.scripts.drizzle){
|
|
64
|
+
pkg.scripts.drizzle = "drizzle-auto";
|
|
65
|
+
fs.writeFileSync(PKG, JSON.stringify(pkg,null,2));
|
|
66
|
+
console.log(`${T.lime}☕ Script added → npm/yarn/pnpm run drizzle${T.reset}`);
|
|
60
67
|
}
|
|
61
68
|
}
|
|
62
69
|
injectScript();
|
|
63
70
|
|
|
64
71
|
/* =============================================================
|
|
65
|
-
🔍
|
|
72
|
+
🔍 FIND DRIZZLE CONFIGS
|
|
66
73
|
============================================================= */
|
|
67
|
-
function findDrizzleConfig(root)
|
|
68
|
-
const exts
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (file.isDirectory() && !/node_modules|\.git|\.next|dist/.test(file.name)) {
|
|
75
|
-
walk(full);
|
|
76
|
-
} else if (file.isFile() && exts.some(ext => file.name === `drizzle.config.${ext}`)) {
|
|
77
|
-
files.push(full);
|
|
78
|
-
}
|
|
74
|
+
function findDrizzleConfig(root){
|
|
75
|
+
const exts=["js","ts","cjs","mjs","mts"], files=[];
|
|
76
|
+
function walk(dir){
|
|
77
|
+
fs.readdirSync(dir,{withFileTypes:true}).forEach(file=>{
|
|
78
|
+
const full = path.join(dir,file.name);
|
|
79
|
+
if(file.isDirectory() && !/node_modules|\.git|\.next|dist/.test(file.name)) walk(full);
|
|
80
|
+
else if(file.isFile() && exts.some(ext=>file.name===`drizzle.config.${ext}`)) files.push(full);
|
|
79
81
|
});
|
|
80
82
|
}
|
|
81
|
-
|
|
82
83
|
walk(root);
|
|
83
84
|
return files;
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
87
|
+
/* =============================================================
|
|
88
|
+
🔹 VALIDATE SCHEMA
|
|
89
|
+
============================================================= */
|
|
90
|
+
function validateSchema(){
|
|
91
|
+
const root=process.cwd();
|
|
92
|
+
const configs=findDrizzleConfig(root);
|
|
93
|
+
if(configs.length===0) return {ok:false,msg:"Missing drizzle.config.*"};
|
|
94
|
+
|
|
95
|
+
for(const cfg of configs){
|
|
96
|
+
try{
|
|
97
|
+
const content = fs.readFileSync(cfg,"utf8");
|
|
98
|
+
const match = content.match(/schema:\s*["'](.+?)["']/);
|
|
99
|
+
if(match && match[1]){
|
|
100
|
+
const schemaFull = path.resolve(path.dirname(cfg), match[1]);
|
|
101
|
+
if(!fs.existsSync(schemaFull)) return {ok:false,msg:`Schema not found: ${match[1]} in ${cfg}`};
|
|
100
102
|
}
|
|
101
|
-
}
|
|
102
|
-
return { ok: false, msg: `Config parse error in ${configPath}` };
|
|
103
|
-
}
|
|
103
|
+
}catch(e){ return {ok:false,msg:`Config parse error in ${cfg}`}; }
|
|
104
104
|
}
|
|
105
|
-
|
|
106
|
-
return { ok: true, config: configs };
|
|
105
|
+
return {ok:true,config:configs};
|
|
107
106
|
}
|
|
108
107
|
|
|
109
108
|
/* =============================================================
|
|
110
|
-
⚙️
|
|
109
|
+
⚙️ SERVER-STYLE RUNNER (WORKS WITH ANY PM)
|
|
111
110
|
============================================================= */
|
|
112
|
-
function
|
|
113
|
-
return new Promise(
|
|
111
|
+
function runCommandServerStyle(cmd,label){
|
|
112
|
+
return new Promise(resolve=>{
|
|
114
113
|
startLoading(`${T.pink}${label}${T.reset}`);
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
child.stdout.on("data", (data) => {
|
|
120
|
-
const out = data.toString();
|
|
121
|
-
if (!out.includes('Pulling schema')) {
|
|
122
|
-
stopLoading();
|
|
123
|
-
process.stdout.write(`${T.gray}${out}${T.reset}`);
|
|
124
|
-
}
|
|
125
|
-
if (/error|failed|ENOTFOUND/i.test(out)) localErr = true;
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
child.stderr.on("data", (data) => {
|
|
129
|
-
stopLoading();
|
|
130
|
-
process.stderr.write(`${T.red}${T.bold}✖ ${data}${T.reset}`);
|
|
131
|
-
localErr = true;
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
child.on("close", (code) => {
|
|
135
|
-
stopLoading();
|
|
136
|
-
resolve(code === 0 && !localErr);
|
|
137
|
-
});
|
|
114
|
+
const child = spawn(cmd,{shell:true,stdio:"inherit"}); // Server-style
|
|
115
|
+
child.on("close",code=>{ stopLoading(); resolve(code===0); });
|
|
116
|
+
child.on("error",err=>{ stopLoading(); console.log(`${T.red}✖ ${label} Error: ${err.message}${T.reset}`); resolve(false); });
|
|
138
117
|
});
|
|
139
118
|
}
|
|
140
119
|
|
|
141
120
|
/* =============================================================
|
|
142
121
|
🔁 ENGINE WORKFLOW
|
|
143
122
|
============================================================= */
|
|
144
|
-
let
|
|
145
|
-
|
|
123
|
+
let running=false;
|
|
124
|
+
async function triggerEngine(event){
|
|
125
|
+
if(running) return;
|
|
126
|
+
running=true;
|
|
146
127
|
|
|
147
|
-
|
|
148
|
-
if (
|
|
149
|
-
isRunning = true;
|
|
150
|
-
|
|
151
|
-
const audit = justifyStructure();
|
|
152
|
-
if (!audit.ok) {
|
|
153
|
-
console.log(`${T.red}${T.bold}👾 CRITICAL FAILURE:${T.reset} ${audit.msg}`);
|
|
154
|
-
hasError = true; isRunning = false; return;
|
|
155
|
-
}
|
|
128
|
+
const audit = validateSchema();
|
|
129
|
+
if(!audit.ok){ console.log(`${T.red}${T.bold}👾 CRITICAL FAILURE:${T.reset} ${audit.msg}`); running=false; return; }
|
|
156
130
|
|
|
157
131
|
const steps = [
|
|
158
|
-
{
|
|
159
|
-
{
|
|
160
|
-
{
|
|
132
|
+
{name:"Integrity Check", cmd:"drizzle-kit check"},
|
|
133
|
+
{name:"Generate Migration", cmd:"drizzle-kit generate"},
|
|
134
|
+
{name:"Push Database", cmd:"drizzle-kit push"}
|
|
161
135
|
];
|
|
162
136
|
|
|
163
|
-
for
|
|
164
|
-
const success = await
|
|
165
|
-
if
|
|
166
|
-
console.log(`\n${T.red}${T.bold}👾
|
|
167
|
-
|
|
137
|
+
for(const step of steps){
|
|
138
|
+
const success = await runCommandServerStyle(step.cmd,step.name);
|
|
139
|
+
if(!success){
|
|
140
|
+
console.log(`\n${T.red}${T.bold}👾 FAILED AT [${step.name.toUpperCase()}]${T.reset}`);
|
|
141
|
+
running=false; return;
|
|
168
142
|
}
|
|
169
143
|
}
|
|
170
144
|
|
|
171
|
-
|
|
172
|
-
console.log(
|
|
173
|
-
|
|
174
|
-
isRunning = false;
|
|
145
|
+
console.log(`\n${T.lime}${T.bold}🎉 All steps successful!${T.reset}`);
|
|
146
|
+
console.log(`${T.gray}Waiting for changes...${T.reset}\n`);
|
|
147
|
+
running=false;
|
|
175
148
|
}
|
|
176
149
|
|
|
177
150
|
/* =============================================================
|
|
178
|
-
👀 WATCHER
|
|
151
|
+
👀 WATCHER
|
|
179
152
|
============================================================= */
|
|
180
|
-
chokidar.watch(".",
|
|
181
|
-
ignored:
|
|
182
|
-
ignoreInitial:
|
|
183
|
-
usePolling:
|
|
184
|
-
interval:
|
|
185
|
-
}).on("all",
|
|
153
|
+
chokidar.watch(".",{
|
|
154
|
+
ignored:[/node_modules/,/\.git/,/\.next/,/dist/],
|
|
155
|
+
ignoreInitial:true,
|
|
156
|
+
usePolling:true,
|
|
157
|
+
interval:300
|
|
158
|
+
}).on("all",(e,f)=>triggerEngine(`${e.toUpperCase()} -> ${path.basename(f)}`));
|
|
186
159
|
|
|
187
160
|
triggerEngine("Initial Audit");
|
|
188
161
|
|
|
189
|
-
|
|
162
|
+
/* =============================================================
|
|
163
|
+
🚨 GLOBAL ERROR HANDLING
|
|
164
|
+
============================================================= */
|
|
165
|
+
process.on("uncaughtException",err=>{
|
|
190
166
|
stopLoading();
|
|
191
|
-
console.log(`\n${T.red}${T.bold}🛡️
|
|
192
|
-
|
|
167
|
+
console.log(`\n${T.red}${T.bold}🛡️ ERROR:${T.reset} ${err.message}`);
|
|
168
|
+
running=false;
|
|
193
169
|
});
|
|
194
170
|
|
|
195
|
-
process.on("SIGINT",
|
|
171
|
+
process.on("SIGINT",()=>{
|
|
196
172
|
stopLoading();
|
|
197
173
|
console.log(`\n${T.yellow}Shutting down Drizzle-Auto...${T.reset}`);
|
|
198
174
|
process.exit();
|