drizzle-auto 1.1.2 → 1.1.4

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.
Files changed (2) hide show
  1. package/index.js +146 -127
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,162 +1,181 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const fs = require("fs");
4
- const path = require("path");
5
3
  const chokidar = require("chokidar");
6
4
  const { spawn } = require("child_process");
5
+ const path = require("path");
6
+ const fs = require("fs");
7
7
 
8
- /* =========================
9
- 🎨 COLORS (CLEAN + PRO)
10
- ========================= */
11
- const C = {
12
- reset: "\x1b[0m",
13
- dim: "\x1b[2m",
14
- cyan: "\x1b[36m",
15
- green: "\x1b[32m",
16
- yellow: "\x1b[33m",
17
- red: "\x1b[31m",
18
- magenta: "\x1b[35m",
19
- bold: "\x1b[1m",
20
- };
21
-
22
- /* =========================
23
- 🧭 PROJECT ROOT
24
- ========================= */
25
- const ROOT = process.cwd();
26
- const PKG = path.join(ROOT, "package.json");
27
-
28
- /* =========================
29
- 🧩 SCRIPT INJECTOR (REAL FIX)
30
- ========================= */
31
- function injectTeaScript() {
32
- if (!fs.existsSync(PKG)) return;
33
-
34
- const pkg = JSON.parse(fs.readFileSync(PKG, "utf8"));
35
- pkg.scripts ||= {};
36
-
37
- if (!pkg.scripts.tea) {
38
- pkg.scripts.tea = "drizzle-auto";
39
- fs.writeFileSync(PKG, JSON.stringify(pkg, null, 2));
40
- console.log(
41
- `${C.green}☕ Added script:${C.reset} ${C.bold}npm run tea${C.reset}`
42
- );
43
- }
8
+ /* =======================
9
+ 🎨 NeonPulse UI Core
10
+ ======================= */
11
+ const PALETTE = ["\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 = () => PALETTE[colorIndex++ % PALETTE.length];
18
+ const rainbow = (text) => text.split("").map((c) => `${nextColor()}${c}`).join("") + RESET;
19
+
20
+ /* =======================
21
+ ⏳ Dynamic 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);
44
32
  }
45
33
 
46
- /* =========================
47
- 🔍 FIND DRIZZLE CONFIG (ANYWHERE)
48
- ========================= */
49
- function findDrizzleConfig() {
50
- const exts = ["js", "mjs", "cjs", "ts", "mts"];
51
- let found = null;
52
-
53
- function walk(dir) {
54
- if (found) return;
55
- for (const file of fs.readdirSync(dir, { withFileTypes: true })) {
56
- if (file.name === "node_modules" || file.name.startsWith(".")) continue;
57
- const full = path.join(dir, file.name);
58
-
59
- if (file.isDirectory()) walk(full);
60
- else {
61
- for (const e of exts) {
62
- if (file.name === `drizzle.config.${e}`) {
63
- found = full;
64
- return;
65
- }
66
- }
67
- }
68
- }
34
+ function stopSpinner() {
35
+ if (spinnerInterval) {
36
+ clearInterval(spinnerInterval);
37
+ spinnerInterval = null;
38
+ process.stdout.write("\r\x1b[K");
69
39
  }
70
-
71
- walk(ROOT);
72
- return found;
73
40
  }
74
41
 
75
- /* =========================
76
- 🧪 VALIDATE SCHEMA EXISTS
77
- ========================= */
78
- function validateConfig(configPath) {
42
+ /* =======================
43
+ 🧠 5-Step Logic Engine
44
+ ======================= */
45
+ let isRunning = false;
46
+ let hasActiveError = false;
47
+
48
+ // [STEP 2]: Justify All Infrastructure Files (Dynamic Format Support)
49
+ function justifyFiles() {
50
+ const root = process.cwd();
51
+
52
+ // চেক ১: কনফিগ ফাইল (js, mjs, ts, mts)
53
+ const config = ["ts", "js", "mjs", "mts"]
54
+ .map(ext => `drizzle.config.${ext}`)
55
+ .find(f => fs.existsSync(path.join(root, f)));
56
+
57
+ if (!config) return { ok: false, msg: "drizzle.config.(ts/js/mjs/mts) not found in project." };
58
+
59
+ // চেক ২: স্কিমা ফাইল জাস্টিফিকেশন (কনফিগ থেকে ডাইনামিকালি পাথ রিড করা)
79
60
  try {
80
- const txt = fs.readFileSync(configPath, "utf8");
81
- const m = txt.match(/schema:\s*["'](.+?)["']/);
82
- if (!m) return true;
83
-
84
- const schemaPath = path.resolve(path.dirname(configPath), m[1]);
85
- return fs.existsSync(schemaPath);
86
- } catch {
87
- return false;
61
+ const content = fs.readFileSync(path.join(root, config), "utf8");
62
+ const schemaMatch = content.match(/schema:\s*["'](.+?)["']/);
63
+ if (schemaMatch && schemaMatch[1]) {
64
+ const schemaPath = path.join(root, schemaMatch[1]);
65
+ if (!fs.existsSync(schemaPath)) return { ok: false, msg: `Schema file missing at: ${schemaMatch[1]}` };
66
+ }
67
+ } catch (e) {
68
+ return { ok: false, msg: "Failed to read or parse config file." };
88
69
  }
70
+
71
+ return { ok: true };
89
72
  }
90
73
 
91
- /* =========================
92
- ⚙️ SAFE RUNNER (NO SERVER KILL)
93
- ========================= */
94
- function run(cmd, args) {
74
+ // [STEP 3, 4, 5]: Command Executor with Strict Error Halt
75
+ function executeCommand(args, stepName) {
95
76
  return new Promise((resolve) => {
96
- const p = spawn(cmd, args, {
97
- stdio: "inherit",
98
- shell: false,
99
- });
77
+ let hasError = false;
78
+ startSpinner(`[${stepName}] In Progress...`);
100
79
 
101
- p.on("close", (code) => resolve(code === 0));
102
- });
103
- }
80
+ const child = spawn("npx", args, { shell: true });
104
81
 
105
- /* =========================
106
- 🔁 PIPELINE (SERVER SAFE)
107
- ========================= */
108
- let busy = false;
82
+ child.stdout.on("data", (data) => {
83
+ const out = data.toString();
84
+ // Spam filter for cloud/server-side DB pulling logs
85
+ if (!out.includes('Pulling schema')) {
86
+ stopSpinner();
87
+ process.stdout.write(`${DIM}${out}${RESET}`);
88
+ }
89
+ if (/error|failed|ENOTFOUND|ECONNREFUSED/i.test(out)) hasError = true;
90
+ });
109
91
 
110
- async function pipeline(trigger) {
111
- if (busy) return;
112
- busy = true;
92
+ child.stderr.on("data", (data) => {
93
+ const err = data.toString();
94
+ stopSpinner();
95
+ process.stderr.write(`\x1b[31m${err}${RESET}`);
96
+ hasError = true;
97
+ });
113
98
 
114
- console.log(
115
- `\n${C.cyan}⚡ Trigger →${C.reset} ${C.bold}${trigger}${C.reset}`
116
- );
99
+ child.on("close", (code) => {
100
+ stopSpinner();
101
+ resolve(code === 0 && !hasError);
102
+ });
103
+ });
104
+ }
117
105
 
118
- const config = findDrizzleConfig();
119
- if (!config) {
120
- console.log(`${C.yellow}⚠ No drizzle.config found${C.reset}`);
121
- busy = false;
106
+ /* =======================
107
+ 🔄 The Sequential Workflow
108
+ ======================= */
109
+ async function startWorkflow(trigger) {
110
+ if (isRunning) return;
111
+ isRunning = true;
112
+
113
+ if (!hasActiveError) console.clear();
114
+ console.log(BOLD + rainbow("🚀 DRIZZLE-AUTO // UNIVERSAL SERVER-SIDE ENGINE"));
115
+ console.log(`${nextColor()}⚡ Trigger → ${trigger}${RESET}\n`);
116
+
117
+ // STEP 2: Justify Files (Infrastructure Check)
118
+ const audit = justifyFiles();
119
+ if (!audit.ok) {
120
+ console.log(`\n\x1b[31m🛑 STEP 2 FAILED: ${audit.msg}${RESET}`);
121
+ hasActiveError = true;
122
+ isRunning = false;
122
123
  return;
123
124
  }
124
125
 
125
- if (!validateConfig(config)) {
126
- console.log(`${C.red}❌ Schema path invalid${C.reset}`);
127
- busy = false;
126
+ // STEP 3: Confirm no bug in code (Integrity Check)
127
+ const step3 = await executeCommand(["drizzle-kit", "check"], "Step 3: Bug Check");
128
+ if (!step3) {
129
+ console.log(`\n\x1b[31m🛑 STEP 3 FAILED: Bugs or Drifts detected. Halting Pipeline.${RESET}`);
130
+ hasActiveError = true;
131
+ isRunning = false;
128
132
  return;
129
133
  }
130
134
 
131
- console.log(`${C.magenta}▶ drizzle-kit generate${C.reset}`);
132
- const genOK = await run("npx", ["drizzle-kit", "generate"]);
133
- if (!genOK) {
134
- console.log(`${C.red}🛑 Generate failed watcher alive${C.reset}`);
135
- busy = false;
135
+ // STEP 4: Run Drizzle Generate
136
+ const step4 = await executeCommand(["drizzle-kit", "generate"], "Step 4: Generate");
137
+ if (!step4) {
138
+ console.log(`\n\x1b[31m🛑 STEP 4 FAILED: Migration generation failed.${RESET}`);
139
+ hasActiveError = true;
140
+ isRunning = false;
136
141
  return;
137
142
  }
138
143
 
139
- console.log(`${C.magenta}▶ drizzle-kit push${C.reset}`);
140
- const pushOK = await run("npx", ["drizzle-kit", "push"]);
141
- if (!pushOK) {
142
- console.log(`${C.red}🛑 Push failed watcher alive${C.reset}`);
143
- busy = false;
144
+ // STEP 5: Push Changes
145
+ const step5 = await executeCommand(["drizzle-kit", "push"], "Step 5: Push");
146
+ if (!step5) {
147
+ console.log(`\n\x1b[31m🛑 STEP 5 FAILED: DB Push failed. Check connection.${RESET}`);
148
+ hasActiveError = true;
149
+ isRunning = false;
144
150
  return;
145
151
  }
146
152
 
147
- console.log(`${C.green}✨ Drizzle fully synced${C.reset}`);
148
- busy = false;
153
+ // ALL STEPS SUCCESS
154
+ hasActiveError = false;
155
+ console.log(`\n\x1b[32m${BOLD}✨ SUCCESS: 5/5 Steps Completed. All systems justified!${RESET}`);
156
+
157
+ setTimeout(() => {
158
+ isRunning = false;
159
+ console.log(`\n${DIM}🛰️ System justified. Watching for next change...${RESET}`);
160
+ }, 2000);
149
161
  }
150
162
 
151
- /* =========================
152
- 👀 WATCH EVERYTHING
153
- ========================= */
154
- injectTeaScript();
155
- pipeline("Initial");
156
-
157
- chokidar.watch(ROOT, {
158
- ignored: [/node_modules/, /\.git/, /\.next/, /dist/],
163
+ /* =======================
164
+ 👀 Universal Watcher
165
+ ======================= */
166
+ chokidar.watch(".", {
167
+ ignored: [/node_modules/, /\.git/, /\.next/, /dist/, /drizzle/],
159
168
  ignoreInitial: true,
160
- }).on("all", (_, file) => {
161
- pipeline(path.relative(ROOT, file));
162
- });
169
+ usePolling: true,
170
+ interval: 300
171
+ }).on("all", (e, f) => startWorkflow(`${e.toUpperCase()} → ${path.basename(f)}`));
172
+
173
+ // Init Call
174
+ startWorkflow("Initial System Audit");
175
+
176
+ // Safety Net
177
+ process.on("uncaughtException", (err) => {
178
+ stopSpinner();
179
+ console.log(`\n\x1b[31m🛡️ Shield Error: ${err.message}${RESET}`);
180
+ isRunning = false;
181
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drizzle-auto",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "",
5
5
  "license": "ISC",
6
6
  "author": "pavel ahmmed hridoy",