drizzle-auto 1.0.7 โ 1.0.8
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 +144 -41
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -3,10 +3,44 @@
|
|
|
3
3
|
const fs = require("fs");
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const chokidar = require("chokidar");
|
|
6
|
-
const spawn = require("
|
|
6
|
+
const { spawn } = require("child_process");
|
|
7
7
|
|
|
8
8
|
/* =========================
|
|
9
|
-
|
|
9
|
+
๐จ Neon Colors
|
|
10
|
+
========================= */
|
|
11
|
+
const COLORS = ["\x1b[31m","\x1b[32m","\x1b[33m","\x1b[34m","\x1b[35m","\x1b[36m"];
|
|
12
|
+
const RESET = "\x1b[0m";
|
|
13
|
+
const BOLD = "\x1b[1m";
|
|
14
|
+
const DIM = "\x1b[90m";
|
|
15
|
+
|
|
16
|
+
let colorIndex = 0;
|
|
17
|
+
const nextColor = () => COLORS[colorIndex++ % COLORS.length];
|
|
18
|
+
const rainbow = (text) => text.split("").map(c => `${nextColor()}${c}`).join("") + RESET;
|
|
19
|
+
|
|
20
|
+
/* =========================
|
|
21
|
+
โณ Neon Spinner
|
|
22
|
+
========================= */
|
|
23
|
+
const spinnerFrames = ["โ ","โ ","โ น","โ ธ","โ ผ","โ ด","โ ฆ","โ ง","โ ","โ "];
|
|
24
|
+
let spinIndex = 0;
|
|
25
|
+
let spinnerInterval;
|
|
26
|
+
|
|
27
|
+
function startSpinner(text) {
|
|
28
|
+
stopSpinner();
|
|
29
|
+
spinnerInterval = setInterval(() => {
|
|
30
|
+
process.stdout.write(`\r${nextColor()}${spinnerFrames[spinIndex++ % spinnerFrames.length]} ${text}${RESET}`);
|
|
31
|
+
}, 80);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function stopSpinner() {
|
|
35
|
+
if (spinnerInterval) {
|
|
36
|
+
clearInterval(spinnerInterval);
|
|
37
|
+
spinnerInterval = null;
|
|
38
|
+
process.stdout.write("\r\x1b[K");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* =========================
|
|
43
|
+
๐งญ Project Root & Package.json
|
|
10
44
|
========================= */
|
|
11
45
|
function getProjectRoot() {
|
|
12
46
|
const init = process.env.INIT_CWD;
|
|
@@ -20,7 +54,7 @@ const projectRoot = getProjectRoot();
|
|
|
20
54
|
const pkgPath = path.join(projectRoot, "package.json");
|
|
21
55
|
|
|
22
56
|
/* =========================
|
|
23
|
-
โ๏ธ Inject "tea"
|
|
57
|
+
โ๏ธ Auto Inject Script "tea"
|
|
24
58
|
========================= */
|
|
25
59
|
function injectTeaScript() {
|
|
26
60
|
if (!fs.existsSync(pkgPath)) return;
|
|
@@ -29,59 +63,128 @@ function injectTeaScript() {
|
|
|
29
63
|
if (!pkg.scripts.tea) {
|
|
30
64
|
pkg.scripts.tea = "drizzle-auto";
|
|
31
65
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
32
|
-
console.log("โก
|
|
66
|
+
console.log("โก tea script injected โ npm run tea");
|
|
33
67
|
}
|
|
34
68
|
}
|
|
35
69
|
|
|
36
70
|
/* =========================
|
|
37
|
-
|
|
71
|
+
๐งช Infrastructure Audit
|
|
38
72
|
========================= */
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
73
|
+
function auditInfra() {
|
|
74
|
+
const results = [];
|
|
75
|
+
const configFile = ["ts","js","mjs","mts"].map(ext => `drizzle.config.${ext}`)
|
|
76
|
+
.find(f => fs.existsSync(path.join(projectRoot, f)));
|
|
77
|
+
results.push({ name: "Drizzle Config", ok: !!configFile });
|
|
78
|
+
|
|
79
|
+
if (configFile) {
|
|
80
|
+
try {
|
|
81
|
+
const content = fs.readFileSync(path.join(projectRoot, configFile), "utf-8");
|
|
82
|
+
const match = content.match(/schema:\s*["'](.+?)["']/);
|
|
83
|
+
if (match) {
|
|
84
|
+
const schemaPath = path.join(projectRoot, match[1]);
|
|
85
|
+
results.push({ name: `Schema (${match[1]})`, ok: fs.existsSync(schemaPath) });
|
|
86
|
+
} else {
|
|
87
|
+
results.push({ name: "Schema Path", ok: false });
|
|
88
|
+
}
|
|
89
|
+
} catch {
|
|
90
|
+
results.push({ name: "Config Read", ok: false });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
results.push({ name: ".env", ok: fs.existsSync(path.join(projectRoot, ".env")) });
|
|
95
|
+
results.push({ name: "node_modules", ok: fs.existsSync(path.join(projectRoot, "node_modules")) });
|
|
96
|
+
|
|
97
|
+
const missing = results.filter(r => !r.ok).map(r => r.name);
|
|
98
|
+
return { ok: missing.length === 0, missing };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* =========================
|
|
102
|
+
โ๏ธ Run NPX Command
|
|
103
|
+
========================= */
|
|
104
|
+
function runStep(cmd) {
|
|
105
|
+
return new Promise((resolve) => {
|
|
106
|
+
let failed = false;
|
|
107
|
+
startSpinner(`npx ${cmd.join(" ")}`);
|
|
108
|
+
const p = spawn("npx", cmd, { shell: true });
|
|
109
|
+
|
|
110
|
+
p.stdout.on("data", d => {
|
|
111
|
+
stopSpinner();
|
|
112
|
+
process.stdout.write(DIM + d.toString() + RESET);
|
|
113
|
+
if (/error|failed/i.test(d)) failed = true;
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
p.stderr.on("data", d => {
|
|
117
|
+
stopSpinner();
|
|
118
|
+
process.stderr.write("\x1b[31m" + d + RESET);
|
|
119
|
+
failed = true;
|
|
120
|
+
});
|
|
52
121
|
|
|
53
|
-
|
|
54
|
-
running = false;
|
|
55
|
-
if (code === 0) console.log("โ
Drizzle synced!");
|
|
56
|
-
else console.log("โ Drizzle pipeline failed. Fix errors & save files.");
|
|
122
|
+
p.on("close", code => resolve(code === 0 && !failed));
|
|
57
123
|
});
|
|
58
124
|
}
|
|
59
125
|
|
|
60
126
|
/* =========================
|
|
61
|
-
|
|
127
|
+
๐ Main Workflow
|
|
128
|
+
========================= */
|
|
129
|
+
let isRunning = false;
|
|
130
|
+
let hasError = false;
|
|
131
|
+
|
|
132
|
+
async function workflow(trigger) {
|
|
133
|
+
if (isRunning) return;
|
|
134
|
+
isRunning = true;
|
|
135
|
+
|
|
136
|
+
if (!hasError) console.clear();
|
|
137
|
+
console.log(`\n${nextColor()}โก ${trigger}${RESET}`);
|
|
138
|
+
|
|
139
|
+
const audit = auditInfra();
|
|
140
|
+
if (!audit.ok) {
|
|
141
|
+
console.log("\n\x1b[31mโ Infra not ready\x1b[0m");
|
|
142
|
+
audit.missing.forEach(m => console.log(DIM + "โข " + m + RESET));
|
|
143
|
+
hasError = true;
|
|
144
|
+
isRunning = false;
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const steps = [
|
|
149
|
+
["drizzle-kit", "check"],
|
|
150
|
+
["drizzle-kit", "generate"],
|
|
151
|
+
["drizzle-kit", "push"]
|
|
152
|
+
];
|
|
153
|
+
|
|
154
|
+
for (const s of steps) {
|
|
155
|
+
if (!(await runStep(s))) {
|
|
156
|
+
console.log("\n\x1b[31m๐ Pipeline crashed\x1b[0m");
|
|
157
|
+
hasError = true;
|
|
158
|
+
isRunning = false;
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
hasError = false;
|
|
164
|
+
console.log("\n\x1b[32mโจ Drizzle synced\x1b[0m");
|
|
165
|
+
setTimeout(() => (isRunning = false), 1200);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/* =========================
|
|
169
|
+
๐ Watcher
|
|
170
|
+
========================= */
|
|
171
|
+
chokidar.watch(projectRoot, {
|
|
172
|
+
ignored: [/node_modules/, /\.git/, /\.next/, /dist/],
|
|
173
|
+
ignoreInitial: true,
|
|
174
|
+
usePolling: true,
|
|
175
|
+
interval: 300
|
|
176
|
+
}).on("all", (e, f) => workflow(`${e.toUpperCase()} โ ${f ? path.basename(f) : ""}`));
|
|
177
|
+
|
|
178
|
+
/* =========================
|
|
179
|
+
๐ Postinstall Mode
|
|
62
180
|
========================= */
|
|
63
181
|
if (process.argv.includes("--postinstall") || process.env.npm_config_argv) {
|
|
64
182
|
injectTeaScript();
|
|
65
|
-
|
|
183
|
+
process.exit(0);
|
|
66
184
|
}
|
|
67
185
|
|
|
68
186
|
/* =========================
|
|
69
|
-
|
|
187
|
+
๐ Init
|
|
70
188
|
========================= */
|
|
71
189
|
injectTeaScript();
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
chokidar
|
|
75
|
-
.watch(projectRoot, {
|
|
76
|
-
ignored: /node_modules|\.git|\.next/,
|
|
77
|
-
ignoreInitial: true,
|
|
78
|
-
})
|
|
79
|
-
.on("all", (event, filePath) => {
|
|
80
|
-
console.log(`โก File changed โ ${filePath}`);
|
|
81
|
-
runPipeline();
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
process.on("uncaughtException", (err) => {
|
|
85
|
-
console.log("\x1b[31m๐ฅ Crash:\x1b[0m", err.message);
|
|
86
|
-
running = false;
|
|
87
|
-
});
|
|
190
|
+
workflow("Initial Audit");
|