drizzle-auto 1.0.24 β†’ 1.1.1

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 +119 -67
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -6,124 +6,176 @@ const chokidar = require("chokidar");
6
6
  const { spawn } = require("child_process");
7
7
 
8
8
  /* =========================
9
- 🧭 PROJECT ROOT
9
+ 🎨 COLORS (clean & pro)
10
10
  ========================= */
11
- const ROOT = process.cwd();
12
- const PKG = path.join(ROOT, "package.json");
13
-
14
- /* =========================
15
- 🎨 COLORS
16
- ========================= */
17
- const colors = {
11
+ const C = {
18
12
  reset: "\x1b[0m",
19
- red: "\x1b[31m",
13
+ dim: "\x1b[2m",
14
+ bold: "\x1b[1m",
15
+ cyan: "\x1b[36m",
20
16
  green: "\x1b[32m",
21
17
  yellow: "\x1b[33m",
22
- cyan: "\x1b[36m",
18
+ red: "\x1b[31m",
23
19
  magenta: "\x1b[35m",
24
20
  };
25
21
 
22
+ const log = {
23
+ info: (m) => console.log(`${C.cyan}β„Ή ${m}${C.reset}`),
24
+ ok: (m) => console.log(`${C.green}βœ“ ${m}${C.reset}`),
25
+ warn: (m) => console.log(`${C.yellow}⚠ ${m}${C.reset}`),
26
+ err: (m) => console.log(`${C.red}βœ— ${m}${C.reset}`),
27
+ trig: (m) => console.log(`${C.magenta}⚑ ${m}${C.reset}`),
28
+ };
29
+
26
30
  /* =========================
27
- 🧩 SCRIPT INJECTOR
31
+ 🧭 PROJECT ROOT
28
32
  ========================= */
29
- function injectTeaScript() {
33
+ const ROOT = process.cwd();
34
+ const PKG = path.join(ROOT, "package.json");
35
+
36
+ /* =========================
37
+ 🧩 SCRIPT INJECTOR
38
+ ========================= */
39
+ function injectScript() {
30
40
  if (!fs.existsSync(PKG)) return;
41
+
31
42
  const pkg = JSON.parse(fs.readFileSync(PKG, "utf8"));
32
43
  pkg.scripts ||= {};
44
+
33
45
  if (!pkg.scripts.tea) {
34
46
  pkg.scripts.tea = "drizzle-auto";
35
47
  fs.writeFileSync(PKG, JSON.stringify(pkg, null, 2));
36
- console.log(`${colors.cyan}β˜• Added npm run tea${colors.reset}`);
48
+ log.ok("Added script β†’ npm run tea");
37
49
  }
38
50
  }
39
51
 
40
52
  /* =========================
41
- πŸ” DRIZZLE CONFIG DETECTION
53
+ πŸ” FIND DRIZZLE CONFIG
54
+ (js | mjs | ts | mts)
42
55
  ========================= */
43
56
  function findDrizzleConfig() {
44
- const files = ["drizzle.config.js","drizzle.config.mjs","drizzle.config.ts","drizzle.config.mts"];
45
- const found = files.map(f => path.join(ROOT, f)).find(fs.existsSync);
46
- if (!found) {
47
- console.log(`${colors.yellow}⚠️ No drizzle.config found${colors.reset}`);
48
- return null;
49
- }
50
-
51
- let schema = null;
52
- try {
53
- const content = fs.readFileSync(found, "utf8");
54
- const match = content.match(/schema:\s*["'](.+?)["']/);
55
- if (match) schema = path.join(ROOT, match[1]);
56
- } catch {}
57
-
58
- if (schema && !fs.existsSync(schema)) {
59
- console.log(`${colors.red}❌ Schema file missing: ${schema}${colors.reset}`);
60
- return null;
57
+ const exts = ["js", "mjs", "ts", "mts"];
58
+ for (const e of exts) {
59
+ const p = path.join(ROOT, `drizzle.config.${e}`);
60
+ if (fs.existsSync(p)) return p;
61
61
  }
62
+ return null;
63
+ }
62
64
 
63
- return { config: found, schema };
65
+ /* =========================
66
+ πŸ”Ž FILE FILTER (ALL TYPES)
67
+ ========================= */
68
+ const WATCH_EXTS = [
69
+ ".js", ".mjs", ".cjs",
70
+ ".ts", ".mts",
71
+ ".jsx", ".tsx",
72
+ ".sql"
73
+ ];
74
+
75
+ function isValidFile(file) {
76
+ return WATCH_EXTS.includes(path.extname(file));
64
77
  }
65
78
 
66
79
  /* =========================
67
- βš™οΈ SAFE RUNNER
80
+ βš™οΈ SAFE SPAWN (NO SHELL)
68
81
  ========================= */
69
- function run(cmd) {
70
- return new Promise(resolve => {
71
- let failed = false;
72
- const p = spawn("npx", cmd, { shell: true });
73
- p.stdout.on("data", d => process.stdout.write(`${colors.green}${d}${colors.reset}`));
74
- p.stderr.on("data", d => {
75
- failed = true;
76
- process.stderr.write(`${colors.red}${d}${colors.reset}`);
82
+ function exec(cmd, args = []) {
83
+ return new Promise((resolve) => {
84
+ const p = spawn(cmd, args, { stdio: "inherit" });
85
+
86
+ p.on("error", (e) => {
87
+ log.err(`Process error: ${e.message}`);
88
+ resolve(false);
89
+ });
90
+
91
+ p.on("close", (code) => {
92
+ resolve(code === 0);
77
93
  });
78
- p.on("close", code => resolve(code === 0 && !failed));
79
94
  });
80
95
  }
81
96
 
82
97
  /* =========================
83
- πŸ” PIPELINE
98
+ πŸ›‘οΈ CRASH PROTECTION
99
+ ========================= */
100
+ process.on("uncaughtException", (e) => {
101
+ log.err(`Crash prevented: ${e.message}`);
102
+ });
103
+ process.on("unhandledRejection", (e) => {
104
+ log.err(`Promise rejected: ${e}`);
105
+ });
106
+
107
+ /* =========================
108
+ πŸ” PIPELINE (DEV SAFE)
84
109
  ========================= */
85
- let busy = false;
110
+ let running = false;
111
+ let lastPush = 0;
112
+
113
+ const DEV_MODE = process.argv.includes("--dev");
114
+ const PUSH_COOLDOWN = DEV_MODE ? 120_000 : 30_000; // safer in dev
86
115
 
87
116
  async function pipeline(trigger) {
88
- if (busy) return;
89
- busy = true;
90
- console.log(`${colors.magenta}\n⚑ Trigger β†’ ${trigger}${colors.reset}`);
117
+ if (running) return;
118
+ running = true;
119
+
120
+ log.trig(`Trigger β†’ ${trigger}`);
91
121
 
92
- const drizzle = findDrizzleConfig();
93
- if (!drizzle) {
94
- busy = false;
122
+ const config = findDrizzleConfig();
123
+ if (!config) {
124
+ log.warn("No drizzle.config found");
125
+ running = false;
95
126
  return;
96
127
  }
97
128
 
98
- // 1️⃣ Generate
99
- const genOK = await run(["drizzle-kit", "generate"]);
100
- if (!genOK) {
101
- console.log(`${colors.red}πŸ›‘ Generate failed β€” pipeline paused${colors.reset}`);
102
- busy = false;
129
+ log.info("Running drizzle generate…");
130
+ const gen = await exec("npx", ["drizzle-kit", "generate"]);
131
+ if (!gen) {
132
+ log.err("Generate failed β€” watching continues");
133
+ running = false;
103
134
  return;
104
135
  }
105
136
 
106
- // 2️⃣ Push
107
- const pushOK = await run(["drizzle-kit", "push"]);
108
- if (!pushOK) {
109
- console.log(`${colors.red}πŸ›‘ Push failed β€” server still running${colors.reset}`);
110
- busy = false;
137
+ const now = Date.now();
138
+ if (now - lastPush < PUSH_COOLDOWN) {
139
+ log.warn("Push skipped (cooldown)");
140
+ running = false;
111
141
  return;
112
142
  }
113
143
 
114
- console.log(`${colors.cyan}✨ Drizzle fully synced${colors.reset}`);
115
- busy = false;
144
+ log.info("Running drizzle push…");
145
+ lastPush = now;
146
+
147
+ const push = await exec("npx", ["drizzle-kit", "push"]);
148
+ if (!push) {
149
+ log.err("Push failed β€” DB untouched, server alive");
150
+ running = false;
151
+ return;
152
+ }
153
+
154
+ log.ok("Drizzle fully synced");
155
+ running = false;
116
156
  }
117
157
 
118
158
  /* =========================
119
- πŸ‘€ WATCHER
159
+ πŸ‘€ WATCHER (ALL FILES)
120
160
  ========================= */
121
- injectTeaScript();
161
+ injectScript();
122
162
  pipeline("Initial");
123
163
 
164
+ log.info(`Watching files (${DEV_MODE ? "DEV MODE" : "SAFE MODE"})…`);
165
+
124
166
  chokidar.watch(ROOT, {
125
- ignored: [/node_modules/, /\.git/, /\.next/, /dist/],
167
+ ignored: [
168
+ /node_modules/,
169
+ /\.git/,
170
+ /\.next/,
171
+ /dist/,
172
+ /build/
173
+ ],
126
174
  ignoreInitial: true,
127
175
  usePolling: true,
128
- interval: 300
129
- }).on("all", (_, file) => pipeline(file));
176
+ interval: 300,
177
+ }).on("all", (_, file) => {
178
+ if (isValidFile(file)) {
179
+ pipeline(path.relative(ROOT, file));
180
+ }
181
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drizzle-auto",
3
- "version": "1.0.24",
3
+ "version": "1.1.1",
4
4
  "description": "",
5
5
  "license": "ISC",
6
6
  "author": "pavel ahmmed hridoy",