drizzle-auto 1.1.13 → 1.1.14

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 +158 -78
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -6,114 +6,194 @@ const path = require("path");
6
6
  const fs = require("fs");
7
7
 
8
8
  /* =============================================================
9
- 🎨 UI CORE (Universal ANSI)
10
- ============================================================= */
9
+ 🎨 NEON-PULSE UI CORE
10
+ ============================================================= */
11
11
  const T = {
12
- reset: "\x1b[0m",
13
- bold: "\x1b[1m",
14
- cyan: "\x1b[38;5;51m",
15
- pink: "\x1b[38;5;201m",
16
- lime: "\x1b[38;5;118m",
17
- yellow: "\x1b[38;5;226m",
18
- red: "\x1b[38;5;196m",
19
- gray: "\x1b[38;5;244m"
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
+ magenta: "\x1b[38;5;201m",
23
+ bg_dark: "\x1b[48;5;234m"
20
24
  };
21
25
 
22
26
  /* =============================================================
23
- ⏳ SPINNER
24
- ============================================================= */
27
+ ⏳ SPINNER & LOADING
28
+ ============================================================= */
25
29
  const frames = ["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];
26
30
  let spinIdx = 0;
27
31
  let spinInterval;
28
32
 
29
33
  function startLoading(msg) {
30
- stopLoading();
31
- spinInterval = setInterval(() => {
32
- process.stdout.write(`\r${T.cyan}${frames[spinIdx++ % frames.length]}${T.reset} ${T.bold}${msg}${T.reset} `);
33
- }, 80);
34
+ stopLoading();
35
+ spinInterval = setInterval(() => {
36
+ process.stdout.write(`\r${T.cyan}${frames[spinIdx++ % frames.length]}${T.reset} ${T.bold}${msg}${T.reset} `);
37
+ }, 80);
34
38
  }
35
39
 
36
40
  function stopLoading() {
37
- if (spinInterval) {
38
- clearInterval(spinInterval);
39
- spinInterval = null;
40
- process.stdout.write("\r\x1b[K");
41
+ if (spinInterval) {
42
+ clearInterval(spinInterval);
43
+ spinInterval = null;
44
+ process.stdout.write("\r\x1b[K"); // Clear line
45
+ }
46
+ }
47
+
48
+ /* =============================================================
49
+ 🧩 AUTO SCRIPT INJECTOR
50
+ ============================================================= */
51
+ const PKG = path.join(process.cwd(), "package.json");
52
+ function injectScript() {
53
+ if (!fs.existsSync(PKG)) return;
54
+ const pkg = JSON.parse(fs.readFileSync(PKG, "utf8"));
55
+ pkg.scripts ||= {};
56
+ if (!pkg.scripts.tea) {
57
+ pkg.scripts.tea = "drizzle-auto";
58
+ fs.writeFileSync(PKG, JSON.stringify(pkg, null, 2));
59
+ console.log(`${T.lime}☕ Script added → npm run tea${T.reset}`);
60
+ }
61
+ }
62
+ injectScript();
63
+
64
+ /* =============================================================
65
+ 🔍 ALL FILES DRIZZLE DETECTOR
66
+ ============================================================= */
67
+ function findDrizzleConfig(root) {
68
+ const exts = ["js","mjs","ts","mts","cjs"];
69
+ const files = [];
70
+
71
+ function walk(dir) {
72
+ fs.readdirSync(dir, { withFileTypes: true }).forEach(file => {
73
+ const full = path.join(dir, file.name);
74
+ if (file.isDirectory() && !/node_modules|\.git|\.next|dist/.test(file.name)) {
75
+ walk(full);
76
+ } else if (file.isFile() && exts.some(ext => file.name === `drizzle.config.${ext}`)) {
77
+ files.push(full);
78
+ }
79
+ });
80
+ }
81
+
82
+ walk(root);
83
+ return files;
84
+ }
85
+
86
+ function justifyStructure() {
87
+ const root = process.cwd();
88
+ const configs = findDrizzleConfig(root);
89
+ if (configs.length === 0) return { ok: false, msg: "Missing drizzle.config.*" };
90
+
91
+ for (const configPath of configs) {
92
+ try {
93
+ const content = fs.readFileSync(configPath, "utf8");
94
+ const schemaMatch = content.match(/schema:\s*["'](.+?)["']/);
95
+ if (schemaMatch && schemaMatch[1]) {
96
+ const schemaFull = path.resolve(path.dirname(configPath), schemaMatch[1]);
97
+ if (!fs.existsSync(schemaFull)) {
98
+ return { ok: false, msg: `Schema not found: ${schemaMatch[1]} in ${configPath}` };
99
+ }
100
+ }
101
+ } catch (e) {
102
+ return { ok: false, msg: `Config parse error in ${configPath}` };
41
103
  }
104
+ }
105
+
106
+ return { ok: true, config: configs };
42
107
  }
43
108
 
44
109
  /* =============================================================
45
110
  ⚙️ SAFE STEP RUNNER
46
- ============================================================= */
111
+ ============================================================= */
47
112
  function runStep(args, label) {
48
- return new Promise((resolve) => {
49
- startLoading(`${T.pink}${label}${T.reset}`);
50
-
51
- const child = spawn("npx", args, {
52
- shell: true,
53
- stdio: ["inherit", "pipe", "pipe"]
54
- });
55
-
56
- child.stdout.on("data", (data) => {
57
- const out = data.toString();
58
- if (!out.includes('Pulling')) {
59
- stopLoading();
60
- process.stdout.write(`${T.gray}${out}${T.reset}`);
61
- }
62
- });
63
-
64
- child.on("close", (code) => {
65
- stopLoading();
66
- resolve(code === 0);
67
- });
113
+ return new Promise((resolve) => {
114
+ startLoading(`${T.pink}${label}${T.reset}`);
115
+ let localErr = false;
116
+
117
+ const child = spawn("npx", args, { shell: true, stdio: ["inherit", "pipe", "pipe"] });
118
+
119
+ child.stdout.on("data", (data) => {
120
+ const out = data.toString();
121
+ if (!out.includes('Pulling schema')) {
122
+ stopLoading();
123
+ process.stdout.write(`${T.gray}${out}${T.reset}`);
124
+ }
125
+ if (/error|failed|ENOTFOUND/i.test(out)) localErr = true;
126
+ });
127
+
128
+ child.stderr.on("data", (data) => {
129
+ stopLoading();
130
+ process.stderr.write(`${T.red}${T.bold}✖ ${data}${T.reset}`);
131
+ localErr = true;
132
+ });
133
+
134
+ child.on("close", (code) => {
135
+ stopLoading();
136
+ resolve(code === 0 && !localErr);
68
137
  });
138
+ });
69
139
  }
70
140
 
71
141
  /* =============================================================
72
142
  🔁 ENGINE WORKFLOW
73
- ============================================================= */
143
+ ============================================================= */
74
144
  let isRunning = false;
75
-
76
- async function triggerEngine() {
77
- if (isRunning) return;
78
- isRunning = true;
79
-
80
- const steps = [
81
- { name: "Checking Integrity", args: ["drizzle-kit", "check"] },
82
- { name: "Generating Migrations", args: ["drizzle-kit", "generate"] },
83
- { name: "Pushing to Database", args: ["drizzle-kit", "push"] }
84
- ];
85
-
86
- for (const step of steps) {
87
- const success = await runStep(step.args, step.name);
88
- if (!success) {
89
- console.log(`\n${T.red}${T.bold}✖ PIPELINE HALTED AT [${step.name.toUpperCase()}]${T.reset}`);
90
- isRunning = false;
91
- return;
92
- }
145
+ let hasError = false;
146
+
147
+ async function triggerEngine(event) {
148
+ if (isRunning) return;
149
+ isRunning = true;
150
+
151
+ const audit = justifyStructure();
152
+ if (!audit.ok) {
153
+ console.log(`${T.red}${T.bold}🛑 CRITICAL FAILURE:${T.reset} ${audit.msg}`);
154
+ hasError = true; isRunning = false; return;
155
+ }
156
+
157
+ const steps = [
158
+ { name: "Confirming Integrity", args: ["drizzle-kit", "check"] },
159
+ { name: "Generating Migrations", args: ["drizzle-kit", "generate"] },
160
+ { name: "Pushing to Database", args: ["drizzle-kit", "push"] }
161
+ ];
162
+
163
+ for (const step of steps) {
164
+ const success = await runStep(step.args, step.name);
165
+ if (!success) {
166
+ console.log(`\n${T.red}${T.bold}✖ PIPELINE CRASHED AT [${step.name.toUpperCase()}]${T.reset}`);
167
+ hasError = true; isRunning = false; return;
93
168
  }
169
+ }
94
170
 
95
- console.log(`\n${T.lime}${T.bold}✔ DATABASE SYNCED${T.reset}`);
96
- isRunning = false;
171
+ hasError = false;
172
+ console.log(`\n${T.lime}${T.bold}✔ SYSTEM JUSTIFIED & SYNCED${T.reset}`);
173
+ console.log(`${T.gray}Waiting for next server-side change...${T.reset}\n`);
174
+ isRunning = false;
97
175
  }
98
176
 
99
177
  /* =============================================================
100
- 👀 WATCHER
101
- ============================================================= */
178
+ 👀 WATCHER & GLOBAL CRASH PROTECTION
179
+ ============================================================= */
102
180
  chokidar.watch(".", {
103
- ignored: [/node_modules/, /\.git/, /\.next/, /dist/],
104
- ignoreInitial: true,
105
- usePolling: true,
106
- interval: 500
107
- }).on("all", (event, file) => {
108
- if (file.includes("schema") || file.includes("drizzle.config")) {
109
- triggerEngine();
110
- }
181
+ ignored: [/node_modules/, /\.git/, /\.next/, /dist/],
182
+ ignoreInitial: true,
183
+ usePolling: true,
184
+ interval: 300
185
+ }).on("all", (e, f) => triggerEngine(`${e.toUpperCase()} -> ${path.basename(f)}`));
186
+
187
+ triggerEngine("Initial Audit");
188
+
189
+ process.on("uncaughtException", (err) => {
190
+ stopLoading();
191
+ console.log(`\n${T.red}${T.bold}🛡️ PROTECTIVE SHIELD:${T.reset} ${err.message}`);
192
+ isRunning = false;
111
193
  });
112
194
 
113
- // Initial run
114
- triggerEngine();
115
-
116
195
  process.on("SIGINT", () => {
117
- stopLoading();
118
- process.exit();
119
- });
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.13",
3
+ "version": "1.1.14",
4
4
  "description": "",
5
5
  "license": "ISC",
6
6
  "author": "pavel ahmmed hridoy",