drizzle-auto 1.1.3 → 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 +144 -131
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,155 +1,168 @@
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 (PRO ONLY)
10
- ========================= */
8
+ /* =============================================================
9
+ 1. UI & COLOR CONFIGURATION (NeonPulse Style)
10
+ ============================================================= */
11
11
  const C = {
12
- reset: "\x1b[0m",
13
- bold: "\x1b[1m",
14
- cyan: "\x1b[36m",
15
- green: "\x1b[32m",
16
- yellow: "\x1b[33m",
17
- red: "\x1b[31m",
18
- magenta: "\x1b[35m",
19
- dim: "\x1b[2m",
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"
20
21
  };
21
22
 
22
- /* =========================
23
- 🧭 ROOT
24
- ========================= */
25
- const ROOT = process.cwd();
26
- const PKG = path.join(ROOT, "package.json");
27
-
28
- /* =========================
29
- ADD tea SCRIPT
30
- ========================= */
31
- function injectTea() {
32
- if (!fs.existsSync(PKG)) return;
33
- const pkg = JSON.parse(fs.readFileSync(PKG, "utf8"));
34
- pkg.scripts ||= {};
35
-
36
- if (!pkg.scripts.tea) {
37
- pkg.scripts.tea = "drizzle-auto";
38
- fs.writeFileSync(PKG, JSON.stringify(pkg, null, 2));
39
- console.log(`${C.green}☕ Added:${C.reset} npm run tea`);
40
- }
23
+ const PALETTE = [C.red, C.green, C.yellow, C.blue, C.magenta, C.cyan];
24
+ let colorIndex = 0;
25
+ const nextColor = () => PALETTE[colorIndex++ % PALETTE.length];
26
+
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
+ }
41
41
  }
42
42
 
43
- /* =========================
44
- 🔍 FIND drizzle.config.*
45
- ========================= */
46
- function findConfig() {
47
- const exts = ["js", "mjs", "cjs", "ts", "mts"];
48
- let found = null;
49
-
50
- (function walk(dir) {
51
- if (found) return;
52
- for (const f of fs.readdirSync(dir, { withFileTypes: true })) {
53
- if (f.name === "node_modules" || f.name.startsWith(".")) continue;
54
- const p = path.join(dir, f.name);
55
- if (f.isDirectory()) walk(p);
56
- else {
57
- for (const e of exts) {
58
- if (f.name === `drizzle.config.${e}`) {
59
- found = p;
60
- return;
61
- }
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;
62
57
  }
63
- }
64
58
  }
65
- })(ROOT);
66
-
67
- return found;
59
+ return null;
68
60
  }
69
61
 
70
- /* =========================
71
- ⚙️ SAFE RUNNER (ERROR AWARE)
72
- ========================= */
73
- function run(cmd, args) {
74
- return new Promise((resolve) => {
75
- let stderr = "";
62
+ function justifyInfrastructure() {
63
+ const configPath = findConfig();
64
+ if (!configPath) return { ok: false, msg: "Missing drizzle.config.*" };
76
65
 
77
- const p = spawn(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
78
-
79
- p.stdout.on("data", d => process.stdout.write(d));
80
- p.stderr.on("data", d => {
81
- stderr += d.toString();
82
- process.stderr.write(d);
83
- });
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
+ }
84
78
 
85
- p.on("close", (code) => {
86
- resolve({ ok: code === 0, stderr });
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));
87
102
  });
88
- });
89
103
  }
90
104
 
91
- /* =========================
92
- 🔁 PIPELINE (NO LIES)
93
- ========================= */
94
- let busy = false;
95
-
96
- async function pipeline(trigger) {
97
- if (busy) return;
98
- busy = true;
99
-
100
- console.log(`\n${C.cyan}⚡ Trigger →${C.reset} ${trigger}`);
101
-
102
- const config = findConfig();
103
- if (!config) {
104
- console.log(`${C.yellow} No drizzle.config found${C.reset}`);
105
- busy = false;
106
- return;
107
- }
108
-
109
- console.log(`${C.magenta}▶ drizzle-kit generate${C.reset}`);
110
- const gen = await run("npx", ["drizzle-kit", "generate"]);
111
- if (!gen.ok) {
112
- console.log(`${C.red}🛑 Generate failed — watcher alive${C.reset}`);
113
- busy = false;
114
- return;
115
- }
116
-
117
- console.log(`${C.magenta}▶ drizzle-kit push${C.reset}`);
118
- const push = await run("npx", ["drizzle-kit", "push"]);
119
-
120
- if (!push.ok) {
121
- console.log(`\n${C.red}${C.bold}🚨 PUSH FAILED${C.reset}`);
122
-
123
- if (
124
- push.stderr.includes("ENOTFOUND") ||
125
- push.stderr.includes("websocket")
126
- ) {
127
- console.log(
128
- `${C.yellow}⚠ Neon / network issue detected${C.reset}\n` +
129
- `${C.dim}• Check internet\n` +
130
- `• Check DATABASE_URL\n` +
131
- `• Neon endpoint may be sleeping${C.reset}`
132
- );
105
+ /* =============================================================
106
+ 5. DYNAMIC WORKFLOW MANAGER
107
+ ============================================================= */
108
+ let isRunning = false;
109
+ async function startWorkflow(trigger) {
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;
133
121
  }
134
122
 
135
- console.log(`${C.dim}Watcher still running. Server NOT stopped.${C.reset}`);
136
- busy = false;
137
- return;
138
- }
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
+ }
139
137
 
140
- console.log(`${C.green}✨ Drizzle fully synced${C.reset}`);
141
- busy = false;
138
+ console.log(`${C.green}${C.bold}Success: All steps completed.${C.reset}`);
139
+ isRunning = false;
142
140
  }
143
141
 
144
- /* =========================
145
- 👀 WATCH EVERYTHING
146
- ========================= */
147
- injectTea();
148
- pipeline("Initial");
149
-
150
- chokidar.watch(ROOT, {
151
- ignored: [/node_modules/, /\.git/, /\.next/, /dist/],
152
- ignoreInitial: true,
153
- }).on("all", (_, file) => {
154
- pipeline(path.relative(ROOT, file));
155
- });
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
162
+ startWorkflow("Initial System Audit");
163
+
164
+ // Crash Protection
165
+ process.on("uncaughtException", (err) => {
166
+ console.log(`${C.red}🛡️ Shield: ${err.message}${C.reset}`);
167
+ isRunning = false;
168
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drizzle-auto",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "",
5
5
  "license": "ISC",
6
6
  "author": "pavel ahmmed hridoy",