drizzle-auto 1.1.12 → 1.1.14
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 +136 -137
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -6,195 +6,194 @@ const path = require("path");
|
|
|
6
6
|
const fs = require("fs");
|
|
7
7
|
|
|
8
8
|
/* =============================================================
|
|
9
|
-
🎨 NEON-PULSE UI CORE
|
|
9
|
+
🎨 NEON-PULSE UI CORE
|
|
10
10
|
============================================================= */
|
|
11
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
|
-
magenta: "\x1b[38;5;201m",
|
|
23
|
-
bg_dark: "\x1b[48;5;234m"
|
|
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"
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
/* =============================================================
|
|
27
|
-
⏳ SPINNER & LOADING
|
|
27
|
+
⏳ SPINNER & LOADING
|
|
28
28
|
============================================================= */
|
|
29
29
|
const frames = ["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];
|
|
30
30
|
let spinIdx = 0;
|
|
31
31
|
let spinInterval;
|
|
32
32
|
|
|
33
33
|
function startLoading(msg) {
|
|
34
|
-
stopLoading();
|
|
35
|
-
spinInterval = setInterval(() => {
|
|
36
|
-
process.stdout.write(
|
|
37
|
-
}, 80);
|
|
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);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
function stopLoading() {
|
|
41
|
-
if (spinInterval) {
|
|
42
|
-
clearInterval(spinInterval);
|
|
43
|
-
spinInterval = null;
|
|
44
|
-
process.stdout.write("\r\x1b[K"); // Clear line
|
|
45
|
-
}
|
|
41
|
+
if (spinInterval) {
|
|
42
|
+
clearInterval(spinInterval);
|
|
43
|
+
spinInterval = null;
|
|
44
|
+
process.stdout.write("\r\x1b[K"); // Clear line
|
|
45
|
+
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/* =============================================================
|
|
49
|
-
🧩 AUTO SCRIPT INJECTOR
|
|
49
|
+
🧩 AUTO SCRIPT INJECTOR
|
|
50
50
|
============================================================= */
|
|
51
51
|
const PKG = path.join(process.cwd(), "package.json");
|
|
52
52
|
function injectScript() {
|
|
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(
|
|
60
|
-
}
|
|
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
|
+
}
|
|
61
61
|
}
|
|
62
62
|
injectScript();
|
|
63
63
|
|
|
64
64
|
/* =============================================================
|
|
65
|
-
🔍 ALL FILES DRIZZLE DETECTOR
|
|
65
|
+
🔍 ALL FILES DRIZZLE DETECTOR
|
|
66
66
|
============================================================= */
|
|
67
67
|
function findDrizzleConfig(root) {
|
|
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
|
-
}
|
|
68
|
+
const exts = ["js","mjs","ts","mts","cjs"];
|
|
69
|
+
const files = [];
|
|
81
70
|
|
|
82
|
-
walk(
|
|
83
|
-
|
|
84
|
-
|
|
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
|
+
}
|
|
85
81
|
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
}
|
|
82
|
+
walk(root);
|
|
83
|
+
return files;
|
|
104
84
|
}
|
|
105
85
|
|
|
106
|
-
|
|
86
|
+
function justifyStructure() {
|
|
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 };
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
/* =============================================================
|
|
110
|
-
⚙️ SAFE STEP RUNNER
|
|
110
|
+
⚙️ SAFE STEP RUNNER
|
|
111
111
|
============================================================= */
|
|
112
112
|
function runStep(args, label) {
|
|
113
|
-
return new Promise((resolve) => {
|
|
114
|
-
startLoading(
|
|
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
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
child.stderr.on("data", (data) => {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
child.on("close", (code) => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
});
|
|
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
|
+
});
|
|
140
139
|
}
|
|
141
140
|
|
|
142
141
|
/* =============================================================
|
|
143
|
-
🔁 ENGINE WORKFLOW
|
|
142
|
+
🔁 ENGINE WORKFLOW
|
|
144
143
|
============================================================= */
|
|
145
144
|
let isRunning = false;
|
|
146
145
|
let hasError = false;
|
|
147
146
|
|
|
148
147
|
async function triggerEngine(event) {
|
|
149
|
-
if (isRunning) return;
|
|
150
|
-
isRunning = true;
|
|
151
|
-
|
|
152
|
-
const audit = justifyStructure();
|
|
153
|
-
if (!audit.ok) {
|
|
154
|
-
console.log(
|
|
155
|
-
hasError = true; isRunning = false; return;
|
|
156
|
-
}
|
|
157
|
-
|
|
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(
|
|
168
|
-
hasError = true; isRunning = false; return;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
hasError = false;
|
|
173
|
-
console.log(
|
|
174
|
-
console.log(
|
|
175
|
-
isRunning = false;
|
|
148
|
+
if (isRunning) return;
|
|
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
|
+
}
|
|
156
|
+
|
|
157
|
+
const steps = [
|
|
158
|
+
{ name: "Confirming Integrity", args: ["drizzle-kit", "check"] },
|
|
159
|
+
{ name: "Generating Migrations", args: ["drizzle-kit", "generate"] },
|
|
160
|
+
{ name: "Pushing to Database", args: ["drizzle-kit", "push"] }
|
|
161
|
+
];
|
|
162
|
+
|
|
163
|
+
for (const step of steps) {
|
|
164
|
+
const success = await runStep(step.args, step.name);
|
|
165
|
+
if (!success) {
|
|
166
|
+
console.log(`\n${T.red}${T.bold}✖ PIPELINE CRASHED AT [${step.name.toUpperCase()}]${T.reset}`);
|
|
167
|
+
hasError = true; isRunning = false; return;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
hasError = false;
|
|
172
|
+
console.log(`\n${T.lime}${T.bold}✔ SYSTEM JUSTIFIED & SYNCED${T.reset}`);
|
|
173
|
+
console.log(`${T.gray}Waiting for next server-side change...${T.reset}\n`);
|
|
174
|
+
isRunning = false;
|
|
176
175
|
}
|
|
177
176
|
|
|
178
177
|
/* =============================================================
|
|
179
|
-
👀 WATCHER & GLOBAL CRASH PROTECTION
|
|
178
|
+
👀 WATCHER & GLOBAL CRASH PROTECTION
|
|
180
179
|
============================================================= */
|
|
181
180
|
chokidar.watch(".", {
|
|
182
|
-
ignored: [/node_modules/,
|
|
183
|
-
ignoreInitial: true,
|
|
184
|
-
usePolling: true,
|
|
185
|
-
interval: 300
|
|
186
|
-
}).on("all", (e, f) => triggerEngine(
|
|
181
|
+
ignored: [/node_modules/, /\.git/, /\.next/, /dist/],
|
|
182
|
+
ignoreInitial: true,
|
|
183
|
+
usePolling: true,
|
|
184
|
+
interval: 300
|
|
185
|
+
}).on("all", (e, f) => triggerEngine(`${e.toUpperCase()} -> ${path.basename(f)}`));
|
|
187
186
|
|
|
188
187
|
triggerEngine("Initial Audit");
|
|
189
188
|
|
|
190
189
|
process.on("uncaughtException", (err) => {
|
|
191
|
-
stopLoading();
|
|
192
|
-
console.log(
|
|
193
|
-
isRunning = false;
|
|
190
|
+
stopLoading();
|
|
191
|
+
console.log(`\n${T.red}${T.bold}🛡️ PROTECTIVE SHIELD:${T.reset} ${err.message}`);
|
|
192
|
+
isRunning = false;
|
|
194
193
|
});
|
|
195
194
|
|
|
196
195
|
process.on("SIGINT", () => {
|
|
197
|
-
stopLoading();
|
|
198
|
-
console.log(
|
|
199
|
-
process.exit();
|
|
200
|
-
});
|
|
196
|
+
stopLoading();
|
|
197
|
+
console.log(`\n${T.yellow}Shutting down Drizzle-Auto...${T.reset}`);
|
|
198
|
+
process.exit();
|
|
199
|
+
});
|