safelaunch 1.0.18 → 1.0.19

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "safelaunch",
3
- "version": "1.0.18",
3
+ "version": "1.0.19",
4
4
  "description": "Validate your environment before every push. Catch missing, empty, and misconfigured env variables before they break production.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -1,7 +1,12 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
+ const { track, shutdown } = require('./telemetry');
3
4
 
4
- // ─── Impact messages per check type ───────────────────────────────────────────
5
+ // ─── Impact messages ──────────────────────────────────────────────────────────
6
+
7
+ function impactBlock(lines) {
8
+ return ' Impact:\n' + lines.map(l => ' ' + l).join('\n');
9
+ }
5
10
 
6
11
  const IMPACT = {
7
12
  missing: (key) => impactBlock([
@@ -38,12 +43,6 @@ const IMPACT = {
38
43
  ]),
39
44
  };
40
45
 
41
- function impactBlock(lines) {
42
- return ' Impact:\n' + lines.map(l => ' ' + l).join('\n');
43
- }
44
-
45
- // ─── Divider ──────────────────────────────────────────────────────────────────
46
-
47
46
  const DIVIDER = '────────────────────────────';
48
47
 
49
48
  // ─── Helpers ──────────────────────────────────────────────────────────────────
@@ -119,39 +118,26 @@ function checkDependencies(cwd) {
119
118
  return { notInstalled: false, missing };
120
119
  }
121
120
 
122
- // ─── Render helpers ───────────────────────────────────────────────────────────
123
-
124
- function renderIssue(number, title, impactLines) {
121
+ function renderIssue(number, title, impact) {
125
122
  return (
126
123
  number + '. ' + title + '\n' +
127
124
  '\n' +
128
- impactLines + '\n'
125
+ impact + '\n'
129
126
  );
130
127
  }
131
128
 
132
129
  // ─── Main ─────────────────────────────────────────────────────────────────────
133
130
 
134
131
  async function scan() {
135
- // Lazy-load telemetry so it doesn't affect output
136
- let track = async () => {};
137
- let shutdown = async () => {};
138
- try {
139
- const telemetry = require('./safelaunch/src/telemetry');
140
- track = telemetry.track;
141
- shutdown = telemetry.shutdown;
142
- } catch (_) {}
132
+ console.log('');
133
+ console.log('Scanning your project...');
143
134
 
144
135
  const cwd = process.cwd();
145
136
  const projectType = detectProjectType(cwd);
146
137
  const typeLabels = { vite: 'Vite', next: 'Next.js', cra: 'Create React App', node: 'Node.js' };
147
-
148
- console.log('');
149
- console.log('Scanning your project...');
150
138
  console.log('Detected: ' + typeLabels[projectType]);
151
139
  console.log('');
152
140
 
153
- // ── Collect env vars used in codebase ──
154
-
155
141
  const extensions = ['.js', '.ts', '.jsx', '.tsx', '.vue', '.svelte'];
156
142
  let pattern;
157
143
  if (projectType === 'vite') {
@@ -164,8 +150,6 @@ async function scan() {
164
150
 
165
151
  const found = scanFiles(cwd, extensions, pattern);
166
152
 
167
- // ── No env vars in codebase at all ──
168
-
169
153
  if (found.size === 0) {
170
154
  console.log('🛡️ Safelaunch Scan Report');
171
155
  console.log('');
@@ -182,8 +166,6 @@ async function scan() {
182
166
  return;
183
167
  }
184
168
 
185
- // ── No .env file found ──
186
-
187
169
  const result = readEnvDetailed(cwd);
188
170
 
189
171
  if (!result) {
@@ -191,12 +173,7 @@ async function scan() {
191
173
  const criticals = [];
192
174
  let issueNum = 1;
193
175
 
194
- criticals.push(renderIssue(
195
- issueNum++,
196
- '.env file is missing',
197
- IMPACT.noEnvFile()
198
- ));
199
-
176
+ criticals.push(renderIssue(issueNum++, '.env file is missing', IMPACT.noEnvFile()));
200
177
  for (const key of varList) {
201
178
  criticals.push(renderIssue(issueNum++, key + ' is missing', IMPACT.missing(key)));
202
179
  }
@@ -233,8 +210,6 @@ async function scan() {
233
210
  return;
234
211
  }
235
212
 
236
- // ── Full scan ──
237
-
238
213
  const { envVars, duplicates } = result;
239
214
  const missing = [];
240
215
  const empty = [];
@@ -252,7 +227,6 @@ async function scan() {
252
227
 
253
228
  const drift = checkDependencies(cwd);
254
229
 
255
- // Prefix issues (warnings only)
256
230
  const prefixWarnings = [];
257
231
  for (const key of found) {
258
232
  if (key === 'NODE_ENV') continue;
@@ -264,40 +238,27 @@ async function scan() {
264
238
  }
265
239
  }
266
240
 
267
- // ── Build issue lists ──
268
-
269
- const criticalIssues = []; // { title, impact }
270
- const warningIssues = []; // { title, impact }
271
- const passingChecks = []; // string[]
241
+ const criticalIssues = [];
242
+ const warningIssues = [];
243
+ const passingChecks = [];
272
244
 
273
- // Criticals: missing vars
274
245
  for (const key of missing) {
275
246
  criticalIssues.push({ title: key + ' is missing', impact: IMPACT.missing(key) });
276
247
  }
277
-
278
- // Criticals: empty vars
279
248
  for (const key of empty) {
280
249
  criticalIssues.push({ title: key + ' is empty', impact: IMPACT.empty(key) });
281
250
  }
282
-
283
- // Criticals: deps not installed at all
284
251
  if (drift && drift.notInstalled) {
285
252
  criticalIssues.push({ title: 'Dependencies are not installed', impact: IMPACT.depsNotInstalled() });
286
253
  }
287
-
288
- // Warnings: dependency drift
289
254
  if (drift && !drift.notInstalled && drift.missing.length > 0) {
290
255
  for (const dep of drift.missing) {
291
256
  warningIssues.push({ title: dep + ' is not installed', impact: IMPACT.depsDrift(dep) });
292
257
  }
293
258
  }
294
-
295
- // Warnings: duplicate vars
296
259
  for (const key of duplicates) {
297
260
  warningIssues.push({ title: key + ' is defined more than once', impact: IMPACT.duplicate(key) });
298
261
  }
299
-
300
- // Warnings: prefix issues
301
262
  for (const { key, type } of prefixWarnings) {
302
263
  if (type === 'vite') {
303
264
  warningIssues.push({ title: key + ' is missing VITE_ prefix', impact: IMPACT.prefixVite(key) });
@@ -306,7 +267,6 @@ async function scan() {
306
267
  }
307
268
  }
308
269
 
309
- // Passing checks
310
270
  if (result) passingChecks.push('Environment file detected');
311
271
  if (!drift || (!drift.notInstalled && drift.missing.length === 0)) passingChecks.push('Dependencies installed');
312
272
  if (duplicates.length === 0) passingChecks.push('No duplicate variables');
@@ -317,23 +277,17 @@ async function scan() {
317
277
  const totalIssues = criticalIssues.length + warningIssues.length;
318
278
  const hasFailed = totalIssues > 0;
319
279
 
320
- // ─── Render ───────────────────────────────────────────────────────────────
321
-
322
280
  if (hasFailed) {
323
- const critCount = criticalIssues.length;
324
- const warnCount = warningIssues.length;
325
-
326
- let summary = totalIssues + ' issue' + (totalIssues !== 1 ? 's' : '') + ' found';
327
281
  const parts = [];
328
- if (critCount > 0) parts.push(critCount + ' critical');
329
- if (warnCount > 0) parts.push(warnCount + ' warning' + (warnCount !== 1 ? 's' : ''));
330
- summary += '\n' + parts.join(' · ');
282
+ if (criticalIssues.length > 0) parts.push(criticalIssues.length + ' critical');
283
+ if (warningIssues.length > 0) parts.push(warningIssues.length + ' warning' + (warningIssues.length !== 1 ? 's' : ''));
331
284
 
332
285
  console.log('🚨 Safelaunch Scan Report');
333
286
  console.log('');
334
287
  console.log('This project is NOT safe to deploy');
335
288
  console.log('');
336
- console.log(summary);
289
+ console.log(totalIssues + ' issue' + (totalIssues !== 1 ? 's' : '') + ' found');
290
+ console.log(parts.join(' · '));
337
291
  console.log('');
338
292
  console.log(DIVIDER);
339
293
  console.log('');
@@ -370,7 +324,7 @@ async function scan() {
370
324
  }
371
325
 
372
326
  if (passingChecks.length > 0) {
373
- console.log('✅ What\'s working (' + passingChecks.length + ' checks passed)');
327
+ console.log("✅ What's working (" + passingChecks.length + ' checks passed)');
374
328
  console.log('');
375
329
  for (const check of passingChecks) {
376
330
  console.log('- ' + check);
@@ -389,8 +343,6 @@ async function scan() {
389
343
  console.log('');
390
344
 
391
345
  } else {
392
- // ── All clean ──
393
-
394
346
  console.log('🛡️ Safelaunch Scan Report');
395
347
  console.log('');
396
348
  console.log('Your project is safe to deploy');
@@ -407,7 +359,7 @@ async function scan() {
407
359
  console.log('');
408
360
  console.log(DIVIDER);
409
361
  console.log('');
410
- console.log('🎉 You\'re good to go');
362
+ console.log("🎉 You're good to go");
411
363
  console.log('');
412
364
  console.log(' Deploy with confidence');
413
365
  console.log('');