drizzle-auto 1.1.4 → 1.1.5

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 +141 -154
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -5,177 +5,164 @@ 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
-
8
+ /* =============================================================
9
+ 1. UI & COLOR CONFIGURATION (NeonPulse Style)
10
+ ============================================================= */
11
+ const C = {
12
+ reset: "\x1b[0m",
13
+ bold: "\x1b[1m",
14
+ red: "\x1b[31m",
15
+ green: "\x1b[32m",
16
+ yellow: "\x1b[33m",
17
+ blue: "\x1b[34m",
18
+ magenta: "\x1b[35m",
19
+ cyan: "\x1b[36m",
20
+ dim: "\x1b[90m"
21
+ };
22
+
23
+ const PALETTE = [C.red, C.green, C.yellow, C.blue, C.magenta, C.cyan];
16
24
  let colorIndex = 0;
17
25
  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);
32
- }
33
26
 
34
- function stopSpinner() {
35
- if (spinnerInterval) {
36
- clearInterval(spinnerInterval);
37
- spinnerInterval = null;
38
- process.stdout.write("\r\x1b[K");
39
- }
27
+ /* =============================================================
28
+ 2. AUTOMATIC PACKAGE.JSON INJECTION (The "tea" Script)
29
+ ============================================================= */
30
+ function injectTeaScript() {
31
+ const pkgPath = path.join(process.cwd(), "package.json");
32
+ if (fs.existsSync(pkgPath)) {
33
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
34
+ if (!pkg.scripts) pkg.scripts = {};
35
+ if (!pkg.scripts.tea) {
36
+ pkg.scripts.tea = "drizzle-auto";
37
+ fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
38
+ console.log(`${C.green}✔ Added "tea": "drizzle-auto" to package.json${C.reset}`);
39
+ }
40
+ }
40
41
  }
41
42
 
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
- // চেক ২: স্কিমা ফাইল জাস্টিফিকেশন (কনফিগ থেকে ডাইনামিকালি পাথ রিড করা)
60
- try {
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]}` };
43
+ /* =============================================================
44
+ 3. DEEP INFRASTRUCTURE JUSTIFICATION (Recursive Search)
45
+ ============================================================= */
46
+ function findConfig(dir = process.cwd()) {
47
+ const files = fs.readdirSync(dir);
48
+ for (const file of files) {
49
+ const fullPath = path.join(dir, file);
50
+ if (IGNORED_REGEX.test(fullPath)) continue;
51
+
52
+ if (fs.statSync(fullPath).isDirectory()) {
53
+ const found = findConfig(fullPath);
54
+ if (found) return found;
55
+ } else if (/^drizzle\.config\.(js|mjs|cjs|ts|mts)$/.test(file)) {
56
+ return fullPath;
57
+ }
66
58
  }
67
- } catch (e) {
68
- return { ok: false, msg: "Failed to read or parse config file." };
69
- }
70
-
71
- return { ok: true };
59
+ return null;
72
60
  }
73
61
 
74
- // [STEP 3, 4, 5]: Command Executor with Strict Error Halt
75
- function executeCommand(args, stepName) {
76
- return new Promise((resolve) => {
77
- let hasError = false;
78
- startSpinner(`[${stepName}] In Progress...`);
79
-
80
- const child = spawn("npx", args, { shell: true });
81
-
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
- });
91
-
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
- });
62
+ function justifyInfrastructure() {
63
+ const configPath = findConfig();
64
+ if (!configPath) return { ok: false, msg: "Missing drizzle.config.*" };
65
+
66
+ try {
67
+ const content = fs.readFileSync(configPath, "utf8");
68
+ const schemaMatch = content.match(/schema:\s*["'](.+?)["']/);
69
+ if (schemaMatch && schemaMatch[1]) {
70
+ const schemaPath = path.resolve(path.dirname(configPath), schemaMatch[1]);
71
+ if (!fs.existsSync(schemaPath)) return { ok: false, msg: `Schema missing at ${schemaMatch[1]}` };
72
+ }
73
+ } catch (e) {
74
+ return { ok: false, msg: "Config unreadable" };
75
+ }
76
+ return { ok: true, path: configPath };
77
+ }
98
78
 
99
- child.on("close", (code) => {
100
- stopSpinner();
101
- resolve(code === 0 && !hasError);
79
+ /* =============================================================
80
+ 4. SAFE COMMAND EXECUTION (Step-by-Step Chain)
81
+ ============================================================= */
82
+ function execute(args, name) {
83
+ return new Promise((resolve) => {
84
+ let hasError = false;
85
+ console.log(`${C.cyan}⏳ ${name}...${C.reset}`);
86
+
87
+ const child = spawn("npx", args, { shell: true, stdio: ["inherit", "pipe", "pipe"] });
88
+
89
+ child.stdout.on("data", (data) => {
90
+ const out = data.toString();
91
+ // Filter noise from Cloud DB pullers
92
+ if (!out.includes('Pulling schema')) process.stdout.write(`${C.dim}${out}${C.reset}`);
93
+ if (/error|failed|ENOTFOUND|ECONNREFUSED/i.test(out)) hasError = true;
94
+ });
95
+
96
+ child.stderr.on("data", (data) => {
97
+ process.stderr.write(`${C.red}${data}${C.reset}`);
98
+ hasError = true;
99
+ });
100
+
101
+ child.on("close", (code) => resolve(code === 0 && !hasError));
102
102
  });
103
- });
104
103
  }
105
104
 
106
- /* =======================
107
- 🔄 The Sequential Workflow
108
- ======================= */
105
+ /* =============================================================
106
+ 5. DYNAMIC WORKFLOW MANAGER
107
+ ============================================================= */
108
+ let isRunning = false;
109
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;
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;
133
- }
134
-
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;
151
- }
152
-
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(() => {
110
+ if (isRunning) return;
111
+ isRunning = true;
112
+
113
+ console.log(`\n${nextColor()}⚡ Triggered: ${trigger}${C.reset}`);
114
+
115
+ // Step 2: Justify Files
116
+ const infra = justifyInfrastructure();
117
+ if (!infra.ok) {
118
+ console.log(`${C.red}🛑 Infrastructure Failure: ${infra.msg}${C.reset}`);
119
+ isRunning = false;
120
+ return;
121
+ }
122
+
123
+ // Step 3 & 4: Sequence (Generate -> Push)
124
+ const steps = [
125
+ { name: "Generating Schema", args: ["drizzle-kit", "generate"] },
126
+ { name: "Pushing to Database", args: ["drizzle-kit", "push"] }
127
+ ];
128
+
129
+ for (const step of steps) {
130
+ const ok = await execute(step.args, step.name);
131
+ if (!ok) {
132
+ console.log(`${C.red}${C.bold}✖ Pipeline Halted. Check logs above.${C.reset}`);
133
+ isRunning = false;
134
+ return;
135
+ }
136
+ }
137
+
138
+ console.log(`${C.green}${C.bold}✨ Success: All steps completed.${C.reset}`);
158
139
  isRunning = false;
159
- console.log(`\n${DIM}🛰️ System justified. Watching for next change...${RESET}`);
160
- }, 2000);
161
140
  }
162
141
 
163
- /* =======================
164
- 👀 Universal Watcher
165
- ======================= */
166
- chokidar.watch(".", {
167
- ignored: [/node_modules/, /\.git/, /\.next/, /dist/, /drizzle/],
168
- ignoreInitial: true,
169
- usePolling: true,
170
- interval: 300
171
- }).on("all", (e, f) => startWorkflow(`${e.toUpperCase()} → ${path.basename(f)}`));
172
-
173
- // Init Call
142
+ /* =============================================================
143
+ 6. UNIVERSAL WATCHER & INITIALIZATION
144
+ ============================================================= */
145
+ const IGNORED_REGEX = /(node_modules|\.git|\.next|dist)/;
146
+
147
+ injectTeaScript();
148
+
149
+ const watcher = chokidar.watch(".", {
150
+ ignored: IGNORED_REGEX,
151
+ persistent: true,
152
+ ignoreInitial: true,
153
+ usePolling: true,
154
+ interval: 300
155
+ });
156
+
157
+ watcher.on("all", (event, file) => {
158
+ startWorkflow(`${event.toUpperCase()} -> ${path.basename(file)}`);
159
+ });
160
+
161
+ // Initial startup audit
174
162
  startWorkflow("Initial System Audit");
175
163
 
176
- // Safety Net
164
+ // Crash Protection
177
165
  process.on("uncaughtException", (err) => {
178
- stopSpinner();
179
- console.log(`\n\x1b[31m🛡️ Shield Error: ${err.message}${RESET}`);
180
- isRunning = false;
166
+ console.log(`${C.red}🛡️ Shield: ${err.message}${C.reset}`);
167
+ isRunning = false;
181
168
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drizzle-auto",
3
- "version": "1.1.4",
3
+ "version": "1.1.5",
4
4
  "description": "",
5
5
  "license": "ISC",
6
6
  "author": "pavel ahmmed hridoy",