drizzle-auto 1.0.19 → 1.0.21

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 +87 -54
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -6,33 +6,43 @@ const chokidar = require("chokidar");
6
6
  const { spawn } = require("child_process");
7
7
 
8
8
  /* =========================
9
- 🧭 PROJECT ROOT (user project)
9
+ 🎨 COLORS & SPINNER
10
10
  ========================= */
11
- const ROOT = process.env.INIT_CWD || process.cwd(); // <-- important
12
- const PKG = path.join(ROOT, "package.json");
11
+ const COLORS = ["\x1b[31m","\x1b[32m","\x1b[33m","\x1b[34m","\x1b[35m","\x1b[36m"];
12
+ const RESET = "\x1b[0m";
13
+ const BOLD = "\x1b[1m"];
14
+ let colorIndex = 0;
15
+
16
+ function rainbow(text) {
17
+ return text.split("").map(c => `${COLORS[colorIndex++ % COLORS.length]}${c}`).join("") + RESET;
18
+ }
19
+
20
+ const SPINNER = ["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];
21
+ let spinIndex = 0;
22
+ let spinnerInterval;
23
+
24
+ function startSpinner(text) {
25
+ stopSpinner();
26
+ spinnerInterval = setInterval(() => {
27
+ process.stdout.write(`\r${COLORS[colorIndex++ % COLORS.length]}${SPINNER[spinIndex++ % SPINNER.length]} ${text}${RESET}`);
28
+ }, 80);
29
+ }
30
+ function stopSpinner() {
31
+ if (spinnerInterval) clearInterval(spinnerInterval);
32
+ spinnerInterval = null;
33
+ process.stdout.write("\r\x1b[K");
34
+ }
13
35
 
14
36
  /* =========================
15
- 🎨 COLORS
37
+ 🧭 USER PROJECT ROOT
16
38
  ========================= */
17
- const C = {
18
- reset: "\x1b[0m",
19
- green: "\x1b[32m",
20
- yellow: "\x1b[33m",
21
- cyan: "\x1b[36m",
22
- red: "\x1b[31m",
23
- };
24
-
25
- const log = {
26
- ok: (m) => console.log(`${C.green}✔${C.reset} ${m}`),
27
- warn: (m) => console.log(`${C.yellow}▲${C.reset} ${m}`),
28
- err: (m) => console.log(`${C.red}✖${C.reset} ${m}`),
29
- info: (m) => console.log(`${C.cyan}●${C.reset} ${m}`)
30
- };
39
+ const ROOT = process.env.INIT_CWD || process.cwd();
40
+ const PKG = path.join(ROOT, "package.json");
31
41
 
32
42
  /* =========================
33
- 🧩 SCRIPT INJECTOR
43
+ 🧩 INJECT TEA SCRIPT
34
44
  ========================= */
35
- function injectTeaScript() {
45
+ function injectTea() {
36
46
  if (!fs.existsSync(PKG)) return;
37
47
  const pkg = JSON.parse(fs.readFileSync(PKG, "utf8"));
38
48
  pkg.scripts ||= {};
@@ -40,78 +50,95 @@ function injectTeaScript() {
40
50
  if (!pkg.scripts.tea) {
41
51
  pkg.scripts.tea = "drizzle-auto";
42
52
  fs.writeFileSync(PKG, JSON.stringify(pkg, null, 2));
43
- log.ok("Script added → npm run tea");
44
- } else {
45
- log.info("Script 'tea' already exists ✅");
53
+ console.log(rainbow("Script injected → npm run tea"));
46
54
  }
47
55
  }
48
56
 
49
- /* =========================
50
- POSTINSTALL / INJECT HANDLER
51
- ========================= */
57
+ // Run injection only on install
52
58
  if (process.argv.includes("--postinstall")) {
53
- injectTeaScript();
59
+ injectTea();
54
60
  process.exit(0);
55
61
  }
56
62
 
57
63
  /* =========================
58
- SAFE RUNNER
64
+ 🔍 DETECT DRIZZLE CONFIG
65
+ ========================= */
66
+ function detectDrizzle() {
67
+ const configs = ["js","mjs","ts","mts"]
68
+ .map(e => `drizzle.config.${e}`)
69
+ .find(f => fs.existsSync(path.join(ROOT, f)));
70
+
71
+ if (!configs) {
72
+ console.log(rainbow("⚠️ No drizzle.config found"));
73
+ return null;
74
+ }
75
+
76
+ let schemaPath = null;
77
+ try {
78
+ const content = fs.readFileSync(path.join(ROOT, configs), "utf8");
79
+ const match = content.match(/schema:\s*["'](.+?)["']/);
80
+ if (match) schemaPath = path.join(ROOT, match[1]);
81
+ } catch {}
82
+
83
+ if (schemaPath && !fs.existsSync(schemaPath)) {
84
+ console.log(rainbow("❌ Schema file missing"));
85
+ return null;
86
+ }
87
+
88
+ return { config: configs, schema: schemaPath };
89
+ }
90
+
91
+ /* =========================
92
+ ⚙️ SAFE COMMAND RUNNER
59
93
  ========================= */
60
94
  function run(cmd) {
61
- return new Promise((resolve) => {
95
+ return new Promise(resolve => {
62
96
  let failed = false;
97
+ startSpinner(`npx ${cmd.join(" ")}`);
98
+
63
99
  const p = spawn("npx", cmd, { shell: true });
64
- p.stdout.on("data", d => process.stdout.write(d));
65
- p.stderr.on("data", d => {
66
- failed = true;
67
- process.stderr.write(d);
68
- });
100
+
101
+ p.stdout.on("data", d => { stopSpinner(); process.stdout.write(d); });
102
+ p.stderr.on("data", d => { stopSpinner(); process.stderr.write(d); failed = true; });
69
103
  p.on("close", code => resolve(code === 0 && !failed));
70
104
  });
71
105
  }
72
106
 
73
107
  /* =========================
74
- PIPELINE (NON-KILLING)
108
+ 🔁 PIPELINE (NON-KILLING)
75
109
  ========================= */
76
110
  let busy = false;
77
111
  async function pipeline(trigger) {
78
112
  if (busy) return;
79
113
  busy = true;
80
114
 
81
- console.log(`\n${C.cyan}⚡ Trigger → ${trigger}${C.reset}`);
82
-
83
- const configs = ["js","mjs","ts","mts"]
84
- .map(e => `drizzle.config.${e}`)
85
- .find(f => fs.existsSync(path.join(ROOT, f)));
115
+ console.log(`\n${BOLD}${rainbow("⚡ Trigger →")} ${trigger}${RESET}`);
86
116
 
87
- if (!configs) {
88
- log.warn("No drizzle.config found ❌");
89
- busy = false;
90
- return;
91
- }
117
+ const drizzle = detectDrizzle();
118
+ if (!drizzle) { busy = false; return; }
92
119
 
93
- const genOK = await run(["drizzle-kit", "generate"]);
120
+ const genOK = await run(["drizzle-kit","generate"]);
94
121
  if (!genOK) {
95
- log.err("Generate failed — pipeline paused");
122
+ console.log(rainbow("🛑 Generate failed — pipeline paused"));
96
123
  busy = false;
97
124
  return;
98
125
  }
99
126
 
100
- const pushOK = await run(["drizzle-kit", "push"]);
127
+ const pushOK = await run(["drizzle-kit","push"]);
101
128
  if (!pushOK) {
102
- log.err("Push failed — server still running");
129
+ console.log(rainbow("🛑 Push failed — server still running"));
103
130
  busy = false;
104
131
  return;
105
132
  }
106
133
 
107
- log.ok("Drizzle fully synced");
134
+ console.log(rainbow("Drizzle fully synced"));
108
135
  busy = false;
109
136
  }
110
137
 
111
138
  /* =========================
112
- WATCHER (ALWAYS ALIVE)
139
+ 👀 WATCHER (ALWAYS ALIVE)
113
140
  ========================= */
114
- injectTeaScript(); // manual npx start
141
+ injectTea(); // ensure script is added
115
142
  pipeline("Initial");
116
143
 
117
144
  chokidar.watch(ROOT, {
@@ -119,6 +146,12 @@ chokidar.watch(ROOT, {
119
146
  ignoreInitial: true,
120
147
  usePolling: true,
121
148
  interval: 300
122
- }).on("all", (_, file) => {
123
- pipeline(path.basename(file));
149
+ }).on("all", (_, file) => pipeline(path.basename(file)));
150
+
151
+ /* =========================
152
+ 💥 CRASH HANDLER
153
+ ========================= */
154
+ process.on("uncaughtException", e => {
155
+ stopSpinner();
156
+ console.log(rainbow("🔥 Crash:"), e.message);
124
157
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drizzle-auto",
3
- "version": "1.0.19",
3
+ "version": "1.0.21",
4
4
  "description": "",
5
5
  "license": "ISC",
6
6
  "author": "pavel ahmmed hridoy",