drizzle-auto 1.1.5 → 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 +159 -128
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -6,163 +6,194 @@ const path = require("path");
|
|
|
6
6
|
const fs = require("fs");
|
|
7
7
|
|
|
8
8
|
/* =============================================================
|
|
9
|
-
|
|
9
|
+
🎨 NEON-PULSE UI CORE (ChatGPT-Like Aesthetics)
|
|
10
10
|
============================================================= */
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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"
|
|
21
23
|
};
|
|
22
24
|
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
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
|
+
};
|
|
26
29
|
|
|
27
30
|
/* =============================================================
|
|
28
|
-
|
|
31
|
+
💾 AUTO SCRIPT INJECTOR (tea)
|
|
29
32
|
============================================================= */
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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}`);
|
|
40
47
|
}
|
|
48
|
+
} catch (e) {
|
|
49
|
+
console.log(`${T.red}⚠ Failed to inject tea script:${T.reset} ${e.message}`);
|
|
50
|
+
}
|
|
41
51
|
}
|
|
42
52
|
|
|
53
|
+
// Run injection immediately
|
|
54
|
+
injectTea();
|
|
55
|
+
|
|
43
56
|
/* =============================================================
|
|
44
|
-
|
|
57
|
+
⏳ HIGH-FIDELITY SPINNER & LOADING
|
|
45
58
|
============================================================= */
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
} else if (/^drizzle\.config\.(js|mjs|cjs|ts|mts)$/.test(file)) {
|
|
56
|
-
return fullPath;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return null;
|
|
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} `);
|
|
67
|
+
}, 80);
|
|
60
68
|
}
|
|
61
69
|
|
|
62
|
-
function
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const schemaMatch = content.match(/schema:\s*["'](.+?)["']/);
|
|
69
|
-
if (schemaMatch && schemaMatch[1]) {
|
|
70
|
-
const schemaPath = path.resolve(path.dirname(configPath), schemaMatch[1]);
|
|
71
|
-
if (!fs.existsSync(schemaPath)) return { ok: false, msg: `Schema missing at ${schemaMatch[1]}` };
|
|
72
|
-
}
|
|
73
|
-
} catch (e) {
|
|
74
|
-
return { ok: false, msg: "Config unreadable" };
|
|
75
|
-
}
|
|
76
|
-
return { ok: true, path: configPath };
|
|
70
|
+
function stopLoading() {
|
|
71
|
+
if (spinInterval) {
|
|
72
|
+
clearInterval(spinInterval);
|
|
73
|
+
spinInterval = null;
|
|
74
|
+
process.stdout.write("\r\x1b[K"); // Clear current line
|
|
75
|
+
}
|
|
77
76
|
}
|
|
78
77
|
|
|
79
78
|
/* =============================================================
|
|
80
|
-
|
|
79
|
+
🧠 LOGIC & CRASH PROTECTION
|
|
81
80
|
============================================================= */
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
81
|
+
let isRunning = false;
|
|
82
|
+
let hasError = false;
|
|
83
|
+
|
|
84
|
+
// Dynamic File Justification
|
|
85
|
+
function justifyStructure() {
|
|
86
|
+
const root = process.cwd();
|
|
87
|
+
const config = ["ts", "js", "mjs", "mts", "cjs"]
|
|
88
|
+
.map(e => `drizzle.config.${e}`)
|
|
89
|
+
.find(f => fs.existsSync(path.join(root, f)));
|
|
90
|
+
|
|
91
|
+
if (!config) return { ok: false, msg: "Missing drizzle.config.*" };
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
const content = fs.readFileSync(path.join(root, config), "utf8");
|
|
95
|
+
const schemaMatch = content.match(/schema:\s*["'](.+?)["']/);
|
|
96
|
+
if (schemaMatch && schemaMatch[1]) {
|
|
97
|
+
if (!fs.existsSync(path.resolve(root, schemaMatch[1]))) {
|
|
98
|
+
return { ok: false, msg: `Schema not found: ${schemaMatch[1]}` };
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
} catch (e) { return { ok: false, msg: "Config parse error" }; }
|
|
102
|
+
|
|
103
|
+
return { ok: true, config };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Secure Step Execution
|
|
107
|
+
function runStep(args, label) {
|
|
108
|
+
return new Promise((resolve) => {
|
|
109
|
+
startLoading(`${T.pink}${label}${T.reset}`);
|
|
110
|
+
let localErr = false;
|
|
111
|
+
|
|
112
|
+
const child = spawn("npx", args, { shell: true, stdio: ["inherit", "pipe", "pipe"] });
|
|
113
|
+
|
|
114
|
+
child.stdout.on("data", (data) => {
|
|
115
|
+
const out = data.toString();
|
|
116
|
+
if (!out.includes('Pulling schema')) {
|
|
117
|
+
stopLoading();
|
|
118
|
+
process.stdout.write(`${T.gray}${out}${T.reset}`);
|
|
119
|
+
}
|
|
120
|
+
if (/error|failed|ENOTFOUND/i.test(out)) localErr = true;
|
|
102
121
|
});
|
|
122
|
+
|
|
123
|
+
child.stderr.on("data", (data) => {
|
|
124
|
+
stopLoading();
|
|
125
|
+
process.stderr.write(`${T.red}${T.bold}✖ ${data}${T.reset}`);
|
|
126
|
+
localErr = true;
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
child.on("close", (code) => {
|
|
130
|
+
stopLoading();
|
|
131
|
+
resolve(code === 0 && !localErr);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
103
134
|
}
|
|
104
135
|
|
|
105
136
|
/* =============================================================
|
|
106
|
-
|
|
137
|
+
🔁 THE ENGINE WORKFLOW
|
|
107
138
|
============================================================= */
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
139
|
+
async function triggerEngine(event) {
|
|
140
|
+
if (isRunning) return;
|
|
141
|
+
isRunning = true;
|
|
142
|
+
|
|
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`);
|
|
146
|
+
|
|
147
|
+
// Step 2: Infrastructure Audit
|
|
148
|
+
const audit = justifyStructure();
|
|
149
|
+
if (!audit.ok) {
|
|
150
|
+
console.log(`${T.red}${T.bold}🛑 CRITICAL FAILURE:${T.reset} ${audit.msg}`);
|
|
151
|
+
hasError = true; isRunning = false; return;
|
|
152
|
+
}
|
|
153
|
+
|
|
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;
|
|
121
166
|
}
|
|
167
|
+
}
|
|
122
168
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
];
|
|
128
|
-
|
|
129
|
-
for (const step of steps) {
|
|
130
|
-
const ok = await execute(step.args, step.name);
|
|
131
|
-
if (!ok) {
|
|
132
|
-
console.log(`${C.red}${C.bold}✖ Pipeline Halted. Check logs above.${C.reset}`);
|
|
133
|
-
isRunning = false;
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
console.log(`${C.green}${C.bold}✨ Success: All steps completed.${C.reset}`);
|
|
139
|
-
isRunning = false;
|
|
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;
|
|
140
173
|
}
|
|
141
174
|
|
|
142
175
|
/* =============================================================
|
|
143
|
-
|
|
176
|
+
👀 UNIVERSAL WATCHER & CRASH SHIELD
|
|
144
177
|
============================================================= */
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
178
|
+
chokidar.watch(".", {
|
|
179
|
+
ignored: [/node_modules/, /\.git/, /\.next/, /dist/],
|
|
180
|
+
ignoreInitial: true,
|
|
181
|
+
usePolling: true,
|
|
182
|
+
interval: 300
|
|
183
|
+
}).on("all", (e, f) => triggerEngine(`${e.toUpperCase()} -> ${path.basename(f)}`));
|
|
148
184
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
persistent: true,
|
|
152
|
-
ignoreInitial: true,
|
|
153
|
-
usePolling: true,
|
|
154
|
-
interval: 300
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
watcher.on("all", (event, file) => {
|
|
158
|
-
startWorkflow(`${event.toUpperCase()} -> ${path.basename(file)}`);
|
|
159
|
-
});
|
|
185
|
+
// Initial Ignition
|
|
186
|
+
triggerEngine("Initial Audit");
|
|
160
187
|
|
|
161
|
-
//
|
|
162
|
-
startWorkflow("Initial System Audit");
|
|
163
|
-
|
|
164
|
-
// Crash Protection
|
|
188
|
+
// Global Crash Protection
|
|
165
189
|
process.on("uncaughtException", (err) => {
|
|
166
|
-
|
|
167
|
-
|
|
190
|
+
stopLoading();
|
|
191
|
+
console.log(`\n${T.red}${T.bold}🛡️ PROTECTIVE SHIELD:${T.reset} ${err.message}`);
|
|
192
|
+
isRunning = false;
|
|
168
193
|
});
|
|
194
|
+
|
|
195
|
+
process.on("SIGINT", () => {
|
|
196
|
+
stopLoading();
|
|
197
|
+
console.log(`\n${T.yellow}Shutting down Drizzle-Auto...${T.reset}`);
|
|
198
|
+
process.exit();
|
|
199
|
+
});
|