drizzle-auto 1.1.11 → 1.1.12
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 +141 -99
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -6,35 +6,43 @@ const path = require("path");
|
|
|
6
6
|
const fs = require("fs");
|
|
7
7
|
|
|
8
8
|
/* =============================================================
|
|
9
|
-
🎨
|
|
9
|
+
🎨 NEON-PULSE UI CORE
|
|
10
10
|
============================================================= */
|
|
11
11
|
const T = {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
+
magenta: "\x1b[38;5;201m",
|
|
23
|
+
bg_dark: "\x1b[48;5;234m"
|
|
20
24
|
};
|
|
21
25
|
|
|
26
|
+
/* =============================================================
|
|
27
|
+
⏳ SPINNER & LOADING
|
|
28
|
+
============================================================= */
|
|
22
29
|
const frames = ["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];
|
|
23
|
-
let spinIdx = 0
|
|
30
|
+
let spinIdx = 0;
|
|
31
|
+
let spinInterval;
|
|
24
32
|
|
|
25
33
|
function startLoading(msg) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
34
|
+
stopLoading();
|
|
35
|
+
spinInterval = setInterval(() => {
|
|
36
|
+
process.stdout.write(\r${T.cyan}${frames[spinIdx++ % frames.length]}${T.reset} ${T.bold}${msg}${T.reset} );
|
|
37
|
+
}, 80);
|
|
30
38
|
}
|
|
31
39
|
|
|
32
40
|
function stopLoading() {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
if (spinInterval) {
|
|
42
|
+
clearInterval(spinInterval);
|
|
43
|
+
spinInterval = null;
|
|
44
|
+
process.stdout.write("\r\x1b[K"); // Clear line
|
|
45
|
+
}
|
|
38
46
|
}
|
|
39
47
|
|
|
40
48
|
/* =============================================================
|
|
@@ -42,117 +50,151 @@ function stopLoading() {
|
|
|
42
50
|
============================================================= */
|
|
43
51
|
const PKG = path.join(process.cwd(), "package.json");
|
|
44
52
|
function injectScript() {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
if (!fs.existsSync(PKG)) return;
|
|
54
|
+
const pkg = JSON.parse(fs.readFileSync(PKG, "utf8"));
|
|
55
|
+
pkg.scripts ||= {};
|
|
56
|
+
if (!pkg.scripts.tea) {
|
|
57
|
+
pkg.scripts.tea = "drizzle-auto";
|
|
58
|
+
fs.writeFileSync(PKG, JSON.stringify(pkg, null, 2));
|
|
59
|
+
console.log(${T.lime}☕ Script added → npm run tea${T.reset});
|
|
60
|
+
}
|
|
53
61
|
}
|
|
54
62
|
injectScript();
|
|
55
63
|
|
|
56
64
|
/* =============================================================
|
|
57
|
-
🔍 DRIZZLE DETECTOR
|
|
65
|
+
🔍 ALL FILES DRIZZLE DETECTOR
|
|
58
66
|
============================================================= */
|
|
59
67
|
function findDrizzleConfig(root) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
const exts = ["js","mjs","ts","mts","cjs"];
|
|
69
|
+
const files = [];
|
|
70
|
+
|
|
71
|
+
function walk(dir) {
|
|
72
|
+
fs.readdirSync(dir, { withFileTypes: true }).forEach(file => {
|
|
73
|
+
const full = path.join(dir, file.name);
|
|
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
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
walk(root);
|
|
83
|
+
return files;
|
|
71
84
|
}
|
|
72
85
|
|
|
73
86
|
function justifyStructure() {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
87
|
+
const root = process.cwd();
|
|
88
|
+
const configs = findDrizzleConfig(root);
|
|
89
|
+
if (configs.length === 0) return { ok: false, msg: "Missing drizzle.config.*" };
|
|
90
|
+
|
|
91
|
+
for (const configPath of configs) {
|
|
92
|
+
try {
|
|
93
|
+
const content = fs.readFileSync(configPath, "utf8");
|
|
94
|
+
const schemaMatch = content.match(/schema:\s*"'["']/);
|
|
95
|
+
if (schemaMatch && schemaMatch[1]) {
|
|
96
|
+
const schemaFull = path.resolve(path.dirname(configPath), schemaMatch[1]);
|
|
97
|
+
if (!fs.existsSync(schemaFull)) {
|
|
98
|
+
return { ok: false, msg: Schema not found: ${schemaMatch[1]} in ${configPath} };
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
} catch (e) {
|
|
102
|
+
return { ok: false, msg: Config parse error in ${configPath} };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return { ok: true, config: configs };
|
|
77
107
|
}
|
|
78
108
|
|
|
79
109
|
/* =============================================================
|
|
80
110
|
⚙️ SAFE STEP RUNNER
|
|
81
111
|
============================================================= */
|
|
82
112
|
function runStep(args, label) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
113
|
+
return new Promise((resolve) => {
|
|
114
|
+
startLoading(${T.pink}${label}${T.reset});
|
|
115
|
+
let localErr = false;
|
|
116
|
+
|
|
117
|
+
const child = spawn("npx", args, { shell: true, stdio: ["inherit", "pipe", "pipe"] });
|
|
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
|
+
});
|
|
138
|
+
|
|
139
|
+
});
|
|
102
140
|
}
|
|
103
141
|
|
|
104
142
|
/* =============================================================
|
|
105
143
|
🔁 ENGINE WORKFLOW
|
|
106
144
|
============================================================= */
|
|
107
145
|
let isRunning = false;
|
|
146
|
+
let hasError = false;
|
|
108
147
|
|
|
109
|
-
async function triggerEngine() {
|
|
110
|
-
|
|
111
|
-
|
|
148
|
+
async function triggerEngine(event) {
|
|
149
|
+
if (isRunning) return;
|
|
150
|
+
isRunning = true;
|
|
112
151
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const steps = [
|
|
120
|
-
{ name: "Checking Integrity", args: ["drizzle-kit", "check"] },
|
|
121
|
-
{ name: "Generating Schema", args: ["drizzle-kit", "generate"] },
|
|
122
|
-
{ name: "Pushing to Database", args: ["drizzle-kit", "push"] }
|
|
123
|
-
];
|
|
152
|
+
const audit = justifyStructure();
|
|
153
|
+
if (!audit.ok) {
|
|
154
|
+
console.log(${T.red}${T.bold}🛑 CRITICAL FAILURE:${T.reset} ${audit.msg});
|
|
155
|
+
hasError = true; isRunning = false; return;
|
|
156
|
+
}
|
|
124
157
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
158
|
+
const steps = [
|
|
159
|
+
{ name: "Confirming Integrity", args: ["drizzle-kit", "check"] },
|
|
160
|
+
{ name: "Generating Migrations", args: ["drizzle-kit", "generate"] },
|
|
161
|
+
{ name: "Pushing to Database", args: ["drizzle-kit", "push"] }
|
|
162
|
+
];
|
|
163
|
+
|
|
164
|
+
for (const step of steps) {
|
|
165
|
+
const success = await runStep(step.args, step.name);
|
|
166
|
+
if (!success) {
|
|
167
|
+
console.log(\n${T.red}${T.bold}✖ PIPELINE CRASHED AT [${step.name.toUpperCase()}]${T.reset});
|
|
168
|
+
hasError = true; isRunning = false; return;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
132
171
|
|
|
133
|
-
|
|
134
|
-
|
|
172
|
+
hasError = false;
|
|
173
|
+
console.log(\n${T.lime}${T.bold}✔ SYSTEM JUSTIFIED & SYNCED${T.reset});
|
|
174
|
+
console.log(${T.gray}Waiting for next server-side change...${T.reset}\n);
|
|
175
|
+
isRunning = false;
|
|
135
176
|
}
|
|
136
177
|
|
|
137
178
|
/* =============================================================
|
|
138
|
-
👀 WATCHER
|
|
179
|
+
👀 WATCHER & GLOBAL CRASH PROTECTION
|
|
139
180
|
============================================================= */
|
|
140
181
|
chokidar.watch(".", {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}).on("all", (e, f) => {
|
|
146
|
-
|
|
147
|
-
|
|
182
|
+
ignored: [/node_modules/, /.git/, /.next/, /dist/],
|
|
183
|
+
ignoreInitial: true,
|
|
184
|
+
usePolling: true,
|
|
185
|
+
interval: 300
|
|
186
|
+
}).on("all", (e, f) => triggerEngine(${e.toUpperCase()} -> ${path.basename(f)}));
|
|
187
|
+
|
|
188
|
+
triggerEngine("Initial Audit");
|
|
189
|
+
|
|
190
|
+
process.on("uncaughtException", (err) => {
|
|
191
|
+
stopLoading();
|
|
192
|
+
console.log(\n${T.red}${T.bold}🛡️ PROTECTIVE SHIELD:${T.reset} ${err.message});
|
|
193
|
+
isRunning = false;
|
|
148
194
|
});
|
|
149
195
|
|
|
150
|
-
console.clear();
|
|
151
|
-
console.log(`${T.cyan}${T.bold}⚡ NEON-BLUE WATCHER ACTIVE [DRIZZLE]${T.reset}\n`);
|
|
152
|
-
triggerEngine();
|
|
153
|
-
|
|
154
196
|
process.on("SIGINT", () => {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
197
|
+
stopLoading();
|
|
198
|
+
console.log(\n${T.yellow}Shutting down Drizzle-Auto...${T.reset});
|
|
199
|
+
process.exit();
|
|
158
200
|
});
|