drizzle-auto 1.1.4 → 1.1.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.
Files changed (2) hide show
  1. package/index.js +138 -120
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -5,177 +5,195 @@ const { spawn } = require("child_process");
5
5
  const path = require("path");
6
6
  const fs = require("fs");
7
7
 
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}`);
8
+ /* =============================================================
9
+ 🎨 NEON-PULSE UI CORE (ChatGPT-Like Aesthetics)
10
+ ============================================================= */
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
+ bg_dark: "\x1b[48;5;234m"
23
+ };
24
+
25
+ const rainbow = (text) => {
26
+ const colors = [196, 208, 226, 118, 51, 201];
27
+ return text.split('').map((char, i) => `\x1b[38;5;${colors[i % colors.length]}m${char}`).join('') + T.reset;
28
+ };
29
+
30
+ /* =============================================================
31
+ 💾 AUTO SCRIPT INJECTOR (tea)
32
+ ============================================================= */
33
+ const ROOT = process.cwd();
34
+ const PKG = path.join(ROOT, "package.json");
35
+
36
+ function injectTea() {
37
+ if (!fs.existsSync(PKG)) return;
38
+ try {
39
+ const pkg = JSON.parse(fs.readFileSync(PKG, "utf8"));
40
+ pkg.scripts ||= {};
41
+ if (!pkg.scripts.tea) {
42
+ pkg.scripts.tea = "drizzle-auto";
43
+ fs.writeFileSync(PKG, JSON.stringify(pkg, null, 2));
44
+ console.log(`${T.cyan}☕ Script injected → ${T.bold}npm run tea${T.reset}`);
45
+ } else {
46
+ console.log(`${T.gray}☕ Tea script already exists${T.reset}`);
47
+ }
48
+ } catch (e) {
49
+ console.log(`${T.red}⚠ Failed to inject tea script:${T.reset} ${e.message}`);
50
+ }
51
+ }
52
+
53
+ // Run injection immediately
54
+ injectTea();
55
+
56
+ /* =============================================================
57
+ ⏳ HIGH-FIDELITY SPINNER & LOADING
58
+ ============================================================= */
59
+ const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
60
+ let spinIdx = 0;
61
+ let spinInterval;
62
+
63
+ function startLoading(msg) {
64
+ stopLoading();
65
+ spinInterval = setInterval(() => {
66
+ process.stdout.write(`\r${T.cyan}${frames[spinIdx++ % frames.length]}${T.reset} ${T.bold}${msg}${T.reset} `);
31
67
  }, 80);
32
68
  }
33
69
 
34
- function stopSpinner() {
35
- if (spinnerInterval) {
36
- clearInterval(spinnerInterval);
37
- spinnerInterval = null;
38
- process.stdout.write("\r\x1b[K");
70
+ function stopLoading() {
71
+ if (spinInterval) {
72
+ clearInterval(spinInterval);
73
+ spinInterval = null;
74
+ process.stdout.write("\r\x1b[K"); // Clear current line
39
75
  }
40
76
  }
41
77
 
42
- /* =======================
43
- 🧠 5-Step Logic Engine
44
- ======================= */
78
+ /* =============================================================
79
+ 🧠 LOGIC & CRASH PROTECTION
80
+ ============================================================= */
45
81
  let isRunning = false;
46
- let hasActiveError = false;
82
+ let hasError = false;
47
83
 
48
- // [STEP 2]: Justify All Infrastructure Files (Dynamic Format Support)
49
- function justifyFiles() {
84
+ // Dynamic File Justification
85
+ function justifyStructure() {
50
86
  const root = process.cwd();
51
-
52
- // চেক ১: কনফিগ ফাইল (js, mjs, ts, mts)
53
- const config = ["ts", "js", "mjs", "mts"]
54
- .map(ext => `drizzle.config.${ext}`)
87
+ const config = ["ts", "js", "mjs", "mts", "cjs"]
88
+ .map(e => `drizzle.config.${e}`)
55
89
  .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
- // চেক ২: স্কিমা ফাইল জাস্টিফিকেশন (কনফিগ থেকে ডাইনামিকালি পাথ রিড করা)
90
+
91
+ if (!config) return { ok: false, msg: "Missing drizzle.config.*" };
92
+
60
93
  try {
61
94
  const content = fs.readFileSync(path.join(root, config), "utf8");
62
95
  const schemaMatch = content.match(/schema:\s*["'](.+?)["']/);
63
96
  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]}` };
97
+ if (!fs.existsSync(path.resolve(root, schemaMatch[1]))) {
98
+ return { ok: false, msg: `Schema not found: ${schemaMatch[1]}` };
99
+ }
66
100
  }
67
- } catch (e) {
68
- return { ok: false, msg: "Failed to read or parse config file." };
69
- }
70
-
71
- return { ok: true };
101
+ } catch (e) { return { ok: false, msg: "Config parse error" }; }
102
+
103
+ return { ok: true, config };
72
104
  }
73
105
 
74
- // [STEP 3, 4, 5]: Command Executor with Strict Error Halt
75
- function executeCommand(args, stepName) {
106
+ // Secure Step Execution
107
+ function runStep(args, label) {
76
108
  return new Promise((resolve) => {
77
- let hasError = false;
78
- startSpinner(`[${stepName}] In Progress...`);
109
+ startLoading(`${T.pink}${label}${T.reset}`);
110
+ let localErr = false;
79
111
 
80
- const child = spawn("npx", args, { shell: true });
112
+ const child = spawn("npx", args, { shell: true, stdio: ["inherit", "pipe", "pipe"] });
81
113
 
82
114
  child.stdout.on("data", (data) => {
83
115
  const out = data.toString();
84
- // Spam filter for cloud/server-side DB pulling logs
85
116
  if (!out.includes('Pulling schema')) {
86
- stopSpinner();
87
- process.stdout.write(`${DIM}${out}${RESET}`);
117
+ stopLoading();
118
+ process.stdout.write(`${T.gray}${out}${T.reset}`);
88
119
  }
89
- if (/error|failed|ENOTFOUND|ECONNREFUSED/i.test(out)) hasError = true;
120
+ if (/error|failed|ENOTFOUND/i.test(out)) localErr = true;
90
121
  });
91
122
 
92
123
  child.stderr.on("data", (data) => {
93
- const err = data.toString();
94
- stopSpinner();
95
- process.stderr.write(`\x1b[31m${err}${RESET}`);
96
- hasError = true;
124
+ stopLoading();
125
+ process.stderr.write(`${T.red}${T.bold}✖ ${data}${T.reset}`);
126
+ localErr = true;
97
127
  });
98
128
 
99
129
  child.on("close", (code) => {
100
- stopSpinner();
101
- resolve(code === 0 && !hasError);
130
+ stopLoading();
131
+ resolve(code === 0 && !localErr);
102
132
  });
103
133
  });
104
134
  }
105
135
 
106
- /* =======================
107
- 🔄 The Sequential Workflow
108
- ======================= */
109
- async function startWorkflow(trigger) {
136
+ /* =============================================================
137
+ 🔁 THE ENGINE WORKFLOW
138
+ ============================================================= */
139
+ async function triggerEngine(event) {
110
140
  if (isRunning) return;
111
141
  isRunning = true;
112
142
 
113
- if (!hasActiveError) console.clear();
114
- console.log(BOLD + rainbow("🚀 DRIZZLE-AUTO // UNIVERSAL SERVER-SIDE ENGINE"));
115
- console.log(`${nextColor()} Trigger ${trigger}${RESET}\n`);
143
+ if (!hasError) console.clear();
144
+ console.log(`\n${T.bg_dark} ${rainbow(" DRIZZLE-AUTO v2026 ")} ${T.reset}`);
145
+ console.log(`${T.pink}●${T.reset} ${T.bold}Event:${T.reset} ${T.cyan}${event}${T.reset}\n`);
116
146
 
117
- // STEP 2: Justify Files (Infrastructure Check)
118
- const audit = justifyFiles();
147
+ // Step 2: Infrastructure Audit
148
+ const audit = justifyStructure();
119
149
  if (!audit.ok) {
120
- console.log(`\n\x1b[31m🛑 STEP 2 FAILED: ${audit.msg}${RESET}`);
121
- hasActiveError = true;
122
- isRunning = false;
123
- return;
124
- }
125
-
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;
132
- return;
150
+ console.log(`${T.red}${T.bold}🛑 CRITICAL FAILURE:${T.reset} ${audit.msg}`);
151
+ hasError = true; isRunning = false; return;
133
152
  }
134
153
 
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;
141
- return;
142
- }
143
-
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;
150
- return;
154
+ // Step 3-5: Execution Chain
155
+ const steps = [
156
+ { name: "Confirming Integrity", args: ["drizzle-kit", "check"] },
157
+ { name: "Generating Migrations", args: ["drizzle-kit", "generate"] },
158
+ { name: "Pushing to Database", args: ["drizzle-kit", "push"] }
159
+ ];
160
+
161
+ for (const step of steps) {
162
+ const success = await runStep(step.args, step.name);
163
+ if (!success) {
164
+ console.log(`\n${T.red}${T.bold}✖ PIPELINE CRASHED AT [${step.name.toUpperCase()}]${T.reset}`);
165
+ hasError = true; isRunning = false; return;
166
+ }
151
167
  }
152
168
 
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);
169
+ hasError = false;
170
+ console.log(`\n${T.lime}${T.bold}✔ SYSTEM JUSTIFIED & SYNCED${T.reset}`);
171
+ console.log(`${T.gray}Waiting for next server-side change...${T.reset}\n`);
172
+ isRunning = false;
161
173
  }
162
174
 
163
- /* =======================
164
- 👀 Universal Watcher
165
- ======================= */
175
+ /* =============================================================
176
+ 👀 UNIVERSAL WATCHER & CRASH SHIELD
177
+ ============================================================= */
166
178
  chokidar.watch(".", {
167
- ignored: [/node_modules/, /\.git/, /\.next/, /dist/, /drizzle/],
179
+ ignored: [/node_modules/, /\.git/, /\.next/, /dist/],
168
180
  ignoreInitial: true,
169
181
  usePolling: true,
170
182
  interval: 300
171
- }).on("all", (e, f) => startWorkflow(`${e.toUpperCase()} ${path.basename(f)}`));
183
+ }).on("all", (e, f) => triggerEngine(`${e.toUpperCase()} -> ${path.basename(f)}`));
172
184
 
173
- // Init Call
174
- startWorkflow("Initial System Audit");
185
+ // Initial Ignition
186
+ triggerEngine("Initial Audit");
175
187
 
176
- // Safety Net
188
+ // Global Crash Protection
177
189
  process.on("uncaughtException", (err) => {
178
- stopSpinner();
179
- console.log(`\n\x1b[31m🛡️ Shield Error: ${err.message}${RESET}`);
190
+ stopLoading();
191
+ console.log(`\n${T.red}${T.bold}🛡️ PROTECTIVE SHIELD:${T.reset} ${err.message}`);
180
192
  isRunning = false;
181
193
  });
194
+
195
+ process.on("SIGINT", () => {
196
+ stopLoading();
197
+ console.log(`\n${T.yellow}Shutting down Drizzle-Auto...${T.reset}`);
198
+ process.exit();
199
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drizzle-auto",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "",
5
5
  "license": "ISC",
6
6
  "author": "pavel ahmmed hridoy",