drizzle-auto 1.0.3 → 1.0.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 +66 -144
- package/package.json +17 -3
package/index.js
CHANGED
|
@@ -1,166 +1,88 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const chokidar = require("chokidar");
|
|
4
|
-
const { spawn } = require("child_process");
|
|
5
|
-
const path = require("path");
|
|
6
3
|
const fs = require("fs");
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
/* =======================
|
|
22
|
-
⏳ Neon Spinner
|
|
23
|
-
======================= */
|
|
24
|
-
const spinnerFrames = ["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];
|
|
25
|
-
let spinIndex = 0;
|
|
26
|
-
let spinnerInterval;
|
|
27
|
-
|
|
28
|
-
function startSpinner(text) {
|
|
29
|
-
stopSpinner();
|
|
30
|
-
spinnerInterval = setInterval(() => {
|
|
31
|
-
process.stdout.write(
|
|
32
|
-
`\r${nextColor()}${spinnerFrames[spinIndex++ % spinnerFrames.length]} ${text}${RESET}`
|
|
33
|
-
);
|
|
34
|
-
}, 80);
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const chokidar = require("chokidar");
|
|
6
|
+
const spawn = require("cross-spawn");
|
|
7
|
+
|
|
8
|
+
/* =========================
|
|
9
|
+
🧠 Detect project root
|
|
10
|
+
========================= */
|
|
11
|
+
function getProjectRoot() {
|
|
12
|
+
const init = process.env.INIT_CWD;
|
|
13
|
+
if (init && fs.existsSync(path.join(init, "package.json"))) return init;
|
|
14
|
+
let cwd = process.cwd();
|
|
15
|
+
if (cwd.includes("node_modules")) cwd = cwd.split(`node_modules${path.sep}`)[0];
|
|
16
|
+
return cwd;
|
|
35
17
|
}
|
|
36
18
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
19
|
+
const projectRoot = getProjectRoot();
|
|
20
|
+
const pkgPath = path.join(projectRoot, "package.json");
|
|
21
|
+
|
|
22
|
+
/* =========================
|
|
23
|
+
✍️ Inject "tea" script
|
|
24
|
+
========================= */
|
|
25
|
+
function injectTeaScript() {
|
|
26
|
+
if (!fs.existsSync(pkgPath)) return;
|
|
27
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
28
|
+
pkg.scripts ||= {};
|
|
29
|
+
if (!pkg.scripts.tea) {
|
|
30
|
+
pkg.scripts.tea = "drizzle-auto";
|
|
31
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
32
|
+
console.log("⚡ Script injected → npm run tea");
|
|
42
33
|
}
|
|
43
34
|
}
|
|
44
35
|
|
|
45
|
-
/*
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
results.push({ name: "Drizzle Config", ok: !!configName });
|
|
63
|
-
|
|
64
|
-
if (configName) {
|
|
65
|
-
try {
|
|
66
|
-
const cfg = fs.readFileSync(path.join(root, configName), "utf8");
|
|
67
|
-
const match = cfg.match(/schema:\s*["'](.+?)["']/);
|
|
68
|
-
if (match) {
|
|
69
|
-
results.push({
|
|
70
|
-
name: `Schema (${match[1]})`,
|
|
71
|
-
ok: fs.existsSync(path.join(root, match[1]))
|
|
72
|
-
});
|
|
73
|
-
} else {
|
|
74
|
-
results.push({ name: "Schema Path", ok: false });
|
|
75
|
-
}
|
|
76
|
-
} catch {
|
|
77
|
-
results.push({ name: "Config Read", ok: false });
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
results.push({ name: ".env", ok: fs.existsSync(path.join(root, ".env")) });
|
|
82
|
-
results.push({ name: "node_modules", ok: fs.existsSync(path.join(root, "node_modules")) });
|
|
83
|
-
|
|
84
|
-
const missing = results.filter(r => !r.ok).map(r => r.name);
|
|
85
|
-
return { ok: missing.length === 0, missing };
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/* =======================
|
|
89
|
-
⚙️ Runner
|
|
90
|
-
======================= */
|
|
91
|
-
function run(cmd) {
|
|
92
|
-
return new Promise((resolve) => {
|
|
93
|
-
let failed = false;
|
|
94
|
-
startSpinner(`npx ${cmd.join(" ")}`);
|
|
95
|
-
|
|
96
|
-
const p = spawn("npx", cmd, { shell: true });
|
|
97
|
-
|
|
98
|
-
p.stdout.on("data", d => {
|
|
99
|
-
stopSpinner();
|
|
100
|
-
process.stdout.write(DIM + d.toString() + RESET);
|
|
101
|
-
if (/error|failed/i.test(d)) failed = true;
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
p.stderr.on("data", d => {
|
|
105
|
-
stopSpinner();
|
|
106
|
-
process.stderr.write("\x1b[31m" + d + RESET);
|
|
107
|
-
failed = true;
|
|
108
|
-
});
|
|
36
|
+
/* =========================
|
|
37
|
+
🚀 Run Drizzle pipeline
|
|
38
|
+
========================= */
|
|
39
|
+
let running = false;
|
|
40
|
+
|
|
41
|
+
function runPipeline() {
|
|
42
|
+
if (running) return;
|
|
43
|
+
running = true;
|
|
44
|
+
console.clear();
|
|
45
|
+
console.log("🚀 Drizzle Pipeline starting...");
|
|
46
|
+
|
|
47
|
+
const p = spawn("npx", ["drizzle-kit", "check", "generate", "push"], {
|
|
48
|
+
stdio: "inherit",
|
|
49
|
+
shell: true,
|
|
50
|
+
cwd: projectRoot,
|
|
51
|
+
});
|
|
109
52
|
|
|
110
|
-
|
|
53
|
+
p.on("close", (code) => {
|
|
54
|
+
running = false;
|
|
55
|
+
if (code === 0) console.log("✅ Drizzle synced!");
|
|
56
|
+
else console.log("❌ Drizzle pipeline failed. Fix errors & save files.");
|
|
111
57
|
});
|
|
112
58
|
}
|
|
113
59
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const audit = auditInfra();
|
|
122
|
-
if (!audit.ok) {
|
|
123
|
-
console.log("\n\x1b[31m❌ Infra not ready\x1b[0m");
|
|
124
|
-
audit.missing.forEach(m => console.log(DIM + "• " + m + RESET));
|
|
125
|
-
hasActiveError = true;
|
|
126
|
-
isRunning = false;
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
for (const step of [
|
|
131
|
-
["drizzle-kit", "check"],
|
|
132
|
-
["drizzle-kit", "generate"],
|
|
133
|
-
["drizzle-kit", "push"],
|
|
134
|
-
]) {
|
|
135
|
-
if (!(await run(step))) {
|
|
136
|
-
console.log("\n\x1b[31m💀 Pipeline crashed\x1b[0m");
|
|
137
|
-
hasActiveError = true;
|
|
138
|
-
isRunning = false;
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
hasActiveError = false;
|
|
144
|
-
console.log("\n\x1b[32m✨ Drizzle synced\x1b[0m");
|
|
145
|
-
setTimeout(() => (isRunning = false), 1200);
|
|
60
|
+
/* =========================
|
|
61
|
+
👀 Postinstall / Auto inject
|
|
62
|
+
========================= */
|
|
63
|
+
if (process.argv.includes("--postinstall")) {
|
|
64
|
+
injectTeaScript();
|
|
65
|
+
runPipeline(); // first run after install
|
|
66
|
+
process.exit(0);
|
|
146
67
|
}
|
|
147
68
|
|
|
148
|
-
/*
|
|
69
|
+
/* =========================
|
|
149
70
|
👀 Watcher
|
|
150
|
-
|
|
71
|
+
========================= */
|
|
72
|
+
injectTeaScript();
|
|
73
|
+
runPipeline(); // first run immediately when running npx drizzle-auto
|
|
74
|
+
|
|
151
75
|
chokidar
|
|
152
|
-
.watch(
|
|
153
|
-
ignored:
|
|
76
|
+
.watch(projectRoot, {
|
|
77
|
+
ignored: /node_modules|\.git|\.next/,
|
|
154
78
|
ignoreInitial: true,
|
|
155
|
-
usePolling: true,
|
|
156
|
-
interval: 300,
|
|
157
79
|
})
|
|
158
|
-
.on("all", (
|
|
159
|
-
|
|
160
|
-
|
|
80
|
+
.on("all", (event, filePath) => {
|
|
81
|
+
console.log(`⚡ File changed → ${filePath}`);
|
|
82
|
+
runPipeline();
|
|
83
|
+
});
|
|
161
84
|
|
|
162
85
|
process.on("uncaughtException", (err) => {
|
|
163
|
-
stopSpinner();
|
|
164
86
|
console.log("\x1b[31m🔥 Crash:\x1b[0m", err.message);
|
|
165
|
-
|
|
87
|
+
running = false;
|
|
166
88
|
});
|
package/package.json
CHANGED
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "drizzle-auto",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
|
+
"description": "Auto Drizzle sync with tea script injection",
|
|
4
5
|
"main": "index.js",
|
|
5
6
|
"bin": {
|
|
6
7
|
"drizzle-auto": "index.js"
|
|
7
8
|
},
|
|
8
9
|
"scripts": {
|
|
9
|
-
"
|
|
10
|
+
"postinstall": "node index.js --postinstall"
|
|
10
11
|
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"drizzle",
|
|
17
|
+
"automation",
|
|
18
|
+
"nextjs",
|
|
19
|
+
"watcher",
|
|
20
|
+
"tea"
|
|
21
|
+
],
|
|
22
|
+
"author": "Pavel Ahmmed Hridoy",
|
|
23
|
+
"license": "MIT",
|
|
11
24
|
"dependencies": {
|
|
12
|
-
"chokidar": "^4.0.1"
|
|
25
|
+
"chokidar": "^4.0.1",
|
|
26
|
+
"cross-spawn": "^7.0.6"
|
|
13
27
|
}
|
|
14
28
|
}
|