drizzle-auto 1.1.12 → 1.1.13
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 +79 -160
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -6,195 +6,114 @@ const path = require("path");
|
|
|
6
6
|
const fs = require("fs");
|
|
7
7
|
|
|
8
8
|
/* =============================================================
|
|
9
|
-
🎨
|
|
10
|
-
============================================================= */
|
|
9
|
+
🎨 UI CORE (Universal ANSI)
|
|
10
|
+
============================================================= */
|
|
11
11
|
const T = {
|
|
12
|
-
reset: "\x1b[0m",
|
|
13
|
-
bold: "\x1b[1m",
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
+
cyan: "\x1b[38;5;51m",
|
|
15
|
+
pink: "\x1b[38;5;201m",
|
|
16
|
+
lime: "\x1b[38;5;118m",
|
|
17
|
+
yellow: "\x1b[38;5;226m",
|
|
18
|
+
red: "\x1b[38;5;196m",
|
|
19
|
+
gray: "\x1b[38;5;244m"
|
|
24
20
|
};
|
|
25
21
|
|
|
26
22
|
/* =============================================================
|
|
27
|
-
⏳ SPINNER
|
|
28
|
-
============================================================= */
|
|
23
|
+
⏳ SPINNER
|
|
24
|
+
============================================================= */
|
|
29
25
|
const frames = ["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];
|
|
30
26
|
let spinIdx = 0;
|
|
31
27
|
let spinInterval;
|
|
32
28
|
|
|
33
29
|
function startLoading(msg) {
|
|
34
|
-
stopLoading();
|
|
35
|
-
spinInterval = setInterval(() => {
|
|
36
|
-
process.stdout.write(
|
|
37
|
-
}, 80);
|
|
30
|
+
stopLoading();
|
|
31
|
+
spinInterval = setInterval(() => {
|
|
32
|
+
process.stdout.write(`\r${T.cyan}${frames[spinIdx++ % frames.length]}${T.reset} ${T.bold}${msg}${T.reset} `);
|
|
33
|
+
}, 80);
|
|
38
34
|
}
|
|
39
35
|
|
|
40
36
|
function stopLoading() {
|
|
41
|
-
if (spinInterval) {
|
|
42
|
-
clearInterval(spinInterval);
|
|
43
|
-
spinInterval = null;
|
|
44
|
-
process.stdout.write("\r\x1b[K");
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/* =============================================================
|
|
49
|
-
🧩 AUTO SCRIPT INJECTOR
|
|
50
|
-
============================================================= */
|
|
51
|
-
const PKG = path.join(process.cwd(), "package.json");
|
|
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(${T.lime}☕ Script added → npm run tea${T.reset});
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
injectScript();
|
|
63
|
-
|
|
64
|
-
/* =============================================================
|
|
65
|
-
🔍 ALL FILES DRIZZLE DETECTOR
|
|
66
|
-
============================================================= */
|
|
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
|
-
}
|
|
81
|
-
|
|
82
|
-
walk(root);
|
|
83
|
-
return files;
|
|
84
|
-
}
|
|
85
|
-
|
|
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 };
|
|
37
|
+
if (spinInterval) {
|
|
38
|
+
clearInterval(spinInterval);
|
|
39
|
+
spinInterval = null;
|
|
40
|
+
process.stdout.write("\r\x1b[K");
|
|
41
|
+
}
|
|
107
42
|
}
|
|
108
43
|
|
|
109
44
|
/* =============================================================
|
|
110
|
-
⚙️ SAFE STEP RUNNER
|
|
111
|
-
============================================================= */
|
|
45
|
+
⚙️ SAFE STEP RUNNER
|
|
46
|
+
============================================================= */
|
|
112
47
|
function runStep(args, label) {
|
|
113
|
-
return new Promise((resolve) => {
|
|
114
|
-
startLoading(
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
child.on("close", (code) => {
|
|
135
|
-
stopLoading();
|
|
136
|
-
resolve(code === 0 && !localErr);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
});
|
|
48
|
+
return new Promise((resolve) => {
|
|
49
|
+
startLoading(`${T.pink}${label}${T.reset}`);
|
|
50
|
+
|
|
51
|
+
const child = spawn("npx", args, {
|
|
52
|
+
shell: true,
|
|
53
|
+
stdio: ["inherit", "pipe", "pipe"]
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
child.stdout.on("data", (data) => {
|
|
57
|
+
const out = data.toString();
|
|
58
|
+
if (!out.includes('Pulling')) {
|
|
59
|
+
stopLoading();
|
|
60
|
+
process.stdout.write(`${T.gray}${out}${T.reset}`);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
child.on("close", (code) => {
|
|
65
|
+
stopLoading();
|
|
66
|
+
resolve(code === 0);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
140
69
|
}
|
|
141
70
|
|
|
142
71
|
/* =============================================================
|
|
143
|
-
🔁 ENGINE WORKFLOW
|
|
144
|
-
============================================================= */
|
|
72
|
+
🔁 ENGINE WORKFLOW
|
|
73
|
+
============================================================= */
|
|
145
74
|
let isRunning = false;
|
|
146
|
-
let hasError = false;
|
|
147
75
|
|
|
148
|
-
async function triggerEngine(
|
|
149
|
-
if (isRunning) return;
|
|
150
|
-
isRunning = true;
|
|
76
|
+
async function triggerEngine() {
|
|
77
|
+
if (isRunning) return;
|
|
78
|
+
isRunning = true;
|
|
151
79
|
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
80
|
+
const steps = [
|
|
81
|
+
{ name: "Checking Integrity", args: ["drizzle-kit", "check"] },
|
|
82
|
+
{ name: "Generating Migrations", args: ["drizzle-kit", "generate"] },
|
|
83
|
+
{ name: "Pushing to Database", args: ["drizzle-kit", "push"] }
|
|
84
|
+
];
|
|
157
85
|
|
|
158
|
-
const steps
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
{
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|
-
}
|
|
86
|
+
for (const step of steps) {
|
|
87
|
+
const success = await runStep(step.args, step.name);
|
|
88
|
+
if (!success) {
|
|
89
|
+
console.log(`\n${T.red}${T.bold}✖ PIPELINE HALTED AT [${step.name.toUpperCase()}]${T.reset}`);
|
|
90
|
+
isRunning = false;
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
171
94
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
console.log(${T.gray}Waiting for next server-side change...${T.reset}\n);
|
|
175
|
-
isRunning = false;
|
|
95
|
+
console.log(`\n${T.lime}${T.bold}✔ DATABASE SYNCED${T.reset}`);
|
|
96
|
+
isRunning = false;
|
|
176
97
|
}
|
|
177
98
|
|
|
178
99
|
/* =============================================================
|
|
179
|
-
👀 WATCHER
|
|
180
|
-
============================================================= */
|
|
100
|
+
👀 WATCHER
|
|
101
|
+
============================================================= */
|
|
181
102
|
chokidar.watch(".", {
|
|
182
|
-
ignored: [/node_modules/,
|
|
183
|
-
ignoreInitial: true,
|
|
184
|
-
usePolling: true,
|
|
185
|
-
interval:
|
|
186
|
-
}).on("all", (
|
|
187
|
-
|
|
188
|
-
triggerEngine(
|
|
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;
|
|
103
|
+
ignored: [/node_modules/, /\.git/, /\.next/, /dist/],
|
|
104
|
+
ignoreInitial: true,
|
|
105
|
+
usePolling: true,
|
|
106
|
+
interval: 500
|
|
107
|
+
}).on("all", (event, file) => {
|
|
108
|
+
if (file.includes("schema") || file.includes("drizzle.config")) {
|
|
109
|
+
triggerEngine();
|
|
110
|
+
}
|
|
194
111
|
});
|
|
195
112
|
|
|
113
|
+
// Initial run
|
|
114
|
+
triggerEngine();
|
|
115
|
+
|
|
196
116
|
process.on("SIGINT", () => {
|
|
197
|
-
stopLoading();
|
|
198
|
-
|
|
199
|
-
process.exit();
|
|
117
|
+
stopLoading();
|
|
118
|
+
process.exit();
|
|
200
119
|
});
|