safelaunch 1.0.20 → 1.0.22

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/README.md CHANGED
@@ -1,60 +1,119 @@
1
1
  # safelaunch
2
2
 
3
- > Ship without breaking production.
3
+ > The pre-deploy safety check for JavaScript projects.
4
4
 
5
5
  [![npm version](https://badge.fury.io/js/safelaunch.svg)](https://www.npmjs.com/package/safelaunch)
6
6
 
7
- safelaunch validates your environment before every push. Catches missing variables, empty values, duplicates, dependency drift, and prefix misconfigurations — before they reach production.
7
+ Run one command before you deploy. safelaunch scans your entire project and tells you exactly what will break — before it breaks in production.
8
8
 
9
- Works with **Node.js, Next.js, Vite, and Create React App**. Not just backend. Any JavaScript project.
9
+ Works with **Node.js, Next.js, Vite, and Create React App**.
10
10
 
11
11
  🌐 [orches.dev](https://karthicedric7-cloud.github.io/Orches)
12
12
 
13
13
  ---
14
14
 
15
- ## Privacy & Security
16
-
17
- safelaunch runs **entirely on your machine**. It never sends your environment variables, secrets, or any project data to external servers. Your `.env` files stay local. Always.
15
+ ## Try it now — zero setup
18
16
 
19
- ---
20
-
21
- ## Try it right now — zero setup
22
17
  ```bash
23
18
  npx safelaunch scan
24
19
  ```
25
20
 
26
21
  No installation. No config. Just run it in any JavaScript project.
27
22
 
28
- Scans your entire codebase, checks your `.env`, and tells you exactly what would break your next deploy.
29
23
  ```
30
24
  Scanning your project...
31
-
32
25
  Detected: Next.js
33
26
 
34
- Found 8 env variables in your codebase
27
+ 🚨 Safelaunch Scan Report
28
+
29
+ This project is NOT safe to deploy
30
+
31
+ 3 issues found
32
+ 2 critical · 1 warning
33
+
34
+ ────────────────────────────
35
+
36
+ 🚨 CRITICAL (will break your app)
37
+
38
+ 1. DATABASE_URL is missing
35
39
 
36
- ⚠️ DUPLICATE VARIABLES (1 found)
40
+ Impact:
41
+ Your app cannot use DATABASE_URL
42
+ → Will crash or behave incorrectly at runtime
37
43
 
38
- DATABASE_URL defined more than once in .env
44
+ ---
45
+
46
+ 2. STRIPE_SECRET_KEY is missing
47
+
48
+ Impact:
49
+ Your app cannot use STRIPE_SECRET_KEY
50
+ → Will crash or behave incorrectly at runtime
51
+
52
+ ────────────────────────────
53
+
54
+ ⚠️ WARNINGS (may cause issues)
39
55
 
40
- MISSING VARIABLES (2 found)
56
+ 3. .env is not in .gitignore
41
57
 
42
- NEXTAUTH_SECRET missing from .env
43
- STRIPE_SECRET_KEY missing from .env
58
+ Impact:
59
+ .env is not in your .gitignore
60
+ → You are one git add away from leaking your secrets
44
61
 
45
- ✅ PASSING (6)
62
+ ────────────────────────────
46
63
 
47
- API_KEY present
48
- NODE_ENV present
64
+ ✅ What's working (5 checks passed)
49
65
 
50
- Your next deploy would have failed.
66
+ - Environment file detected
67
+ - No hardcoded secrets found
68
+ - Dependencies installed
69
+ - No duplicate variables
70
+ - NODE_ENV configured
51
71
 
52
- Run safelaunch init to lock this in permanently.
72
+ ────────────────────────────
73
+
74
+ 💡 Next step
75
+
76
+ Run:
77
+ safelaunch init
78
+
79
+ Lock this configuration and prevent future breakage
53
80
  ```
54
81
 
55
82
  ---
56
83
 
84
+ ## What safelaunch checks
85
+
86
+ ### Environment
87
+ - Missing variables
88
+ - Empty variables
89
+ - Duplicate variables
90
+ - `VITE_` prefix validation
91
+ - `REACT_APP_` prefix validation
92
+ - `.env.example` out of sync
93
+
94
+ ### Secrets & Security
95
+ - `.env` committed to git
96
+ - `.env` not in `.gitignore`
97
+ - Hardcoded secrets in source files
98
+
99
+ ### Dependencies
100
+ - `node_modules` not installed
101
+ - Packages in `package.json` but not installed
102
+ - Lockfile missing
103
+
104
+ ### Build Readiness
105
+ - Build script missing
106
+ - Required config files missing (next.config.js, vite.config.js)
107
+ - TypeScript errors
108
+
109
+ ### Git State
110
+ - Uncommitted changes before deploy
111
+ - Unpushed commits
112
+
113
+ ---
114
+
57
115
  ## Installation
116
+
58
117
  ```bash
59
118
  npm install -g safelaunch
60
119
  ```
@@ -63,62 +122,38 @@ npm install -g safelaunch
63
122
 
64
123
  ## Lock it in permanently
65
124
 
66
- Once you've seen what scan finds, lock it in with two commands:
125
+ Once scan shows you what's broken, lock your configuration so it never breaks again.
67
126
 
68
127
  **Step 1 — Generate your environment manifest**
128
+
69
129
  ```bash
70
130
  safelaunch init
71
131
  ```
72
132
 
73
- Scans your codebase and generates an `env.manifest.json` contract file automatically.
133
+ Scans your codebase and creates an `env.manifest.json` — a contract file that defines exactly what your app needs to run.
134
+
135
+ **Step 2 — Validate before every deploy**
74
136
 
75
- **Step 2 — Validate before every push**
76
137
  ```bash
77
138
  safelaunch validate
78
139
  ```
79
140
 
80
- Runs 11 checks against your `.env` and tells you exactly what will break before it does.
141
+ Checks your live environment against the manifest and tells you exactly what will break before it does.
81
142
 
82
143
  ---
83
144
 
84
- ## Never think about it again — install the git hook
145
+ ## Never think about it again
146
+
85
147
  ```bash
86
148
  safelaunch hook install
87
149
  ```
88
150
 
89
- Blocks `git push` automatically if validation fails. Set it once, forget about it.
90
-
91
- ---
92
-
93
- ## What scan checks
94
-
95
- 1. Missing variables
96
- 2. Empty variables
97
- 3. Duplicate variables
98
- 4. Dependencies not installed
99
- 5. Dependency drift
100
- 6. `VITE_` prefix validation
101
- 7. `REACT_APP_` prefix validation
102
-
103
- ## What validate checks
104
-
105
- 1. Missing required variables
106
- 2. Empty variables
107
- 3. Runtime version mismatch
108
- 4. Duplicate variables
109
- 5. Dependencies not installed
110
- 6. Dependency drift
111
- 7. `.env` vs `.env.example` sync
112
- 8. `VITE_` prefix validation
113
- 9. `REACT_APP_` prefix validation
114
- 10. `NEXT_PUBLIC_` awareness
115
- 11. `.env` file priority order
151
+ Installs a git hook that blocks `git push` automatically if validation fails. Set it once, forget about it.
116
152
 
117
153
  ---
118
154
 
119
155
  ## CI Integration
120
156
 
121
- Block deployments automatically by adding this to your GitHub Actions workflow:
122
157
  ```yaml
123
158
  - name: Install safelaunch
124
159
  run: npm install -g safelaunch
@@ -127,6 +162,16 @@ Block deployments automatically by adding this to your GitHub Actions workflow:
127
162
  run: safelaunch validate
128
163
  ```
129
164
 
165
+ Blocks deployments automatically if anything is missing or misconfigured.
166
+
167
+ ---
168
+
169
+ ## Privacy & Security
170
+
171
+ safelaunch runs **entirely on your machine**. It never sends your environment variables, secrets, or project data to external servers. Your `.env` files stay local. Always.
172
+
173
+ Anonymous usage telemetry is collected to help improve the product. No personal data, no secrets, no file contents — ever.
174
+
130
175
  ---
131
176
 
132
177
  Built by [Karthi Cedric](https://twitter.com/karthiced) · Part of [Orches](https://karthicedric7-cloud.github.io/Orches)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "safelaunch",
3
- "version": "1.0.20",
3
+ "version": "1.0.22",
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,61 +1,119 @@
1
1
  # safelaunch
2
2
 
3
- > Ship without breaking production ever.
3
+ > The pre-deploy safety check for JavaScript projects.
4
4
 
5
5
  [![npm version](https://badge.fury.io/js/safelaunch.svg)](https://www.npmjs.com/package/safelaunch)
6
6
 
7
- safelaunch validates your environment before every push. Catches missing variables, empty values, duplicates, dependency drift, and prefix misconfigurations — before they reach production.
7
+ Run one command before you deploy. safelaunch scans your entire project and tells you exactly what will break — before it breaks in production.
8
8
 
9
- Works with **Node.js, Next.js, Vite, and Create React App**. Not just backend. Any JavaScript project.
9
+ Works with **Node.js, Next.js, Vite, and Create React App**.
10
10
 
11
11
  🌐 [orches.dev](https://karthicedric7-cloud.github.io/Orches)
12
12
 
13
13
  ---
14
14
 
15
- ## Privacy & Security
16
-
17
- safelaunch runs **entirely on your machine**. It never sends your environment variables, secrets, or any project data to external servers. Your `.env` files stay local. Always.
18
-
19
- ---
15
+ ## Try it now — zero setup
20
16
 
21
- ## Try it right now — zero setup
22
17
  ```bash
23
18
  npx safelaunch scan
24
19
  ```
25
20
 
26
21
  No installation. No config. Just run it in any JavaScript project.
27
22
 
28
- Scans your entire codebase, checks your `.env`, and tells you exactly what would break your next deploy.
29
23
  ```
30
24
  Scanning your project...
31
-
32
25
  Detected: Next.js
33
26
 
34
- Found 8 env variables in your codebase
27
+ 🚨 Safelaunch Scan Report
28
+
29
+ This project is NOT safe to deploy
35
30
 
36
- ⚠️ DUPLICATE VARIABLES (1 found)
31
+ 3 issues found
32
+ 2 critical · 1 warning
37
33
 
38
- DATABASE_URL defined more than once in .env
34
+ ────────────────────────────
35
+
36
+ 🚨 CRITICAL (will break your app)
37
+
38
+ 1. DATABASE_URL is missing
39
+
40
+ Impact:
41
+ Your app cannot use DATABASE_URL
42
+ → Will crash or behave incorrectly at runtime
43
+
44
+ ---
39
45
 
40
- MISSING VARIABLES (2 found)
46
+ 2. STRIPE_SECRET_KEY is missing
41
47
 
42
- NEXTAUTH_SECRET missing from .env
43
- STRIPE_SECRET_KEY missing from .env
48
+ Impact:
49
+ Your app cannot use STRIPE_SECRET_KEY
50
+ → Will crash or behave incorrectly at runtime
44
51
 
45
- ✅ PASSING (6)
52
+ ────────────────────────────
46
53
 
47
- API_KEY present
48
- NODE_ENV present
49
- ...
54
+ ⚠️ WARNINGS (may cause issues)
50
55
 
51
- Your next deploy would have failed.
56
+ 3. .env is not in .gitignore
52
57
 
53
- Run safelaunch init to lock this in permanently.
58
+ Impact:
59
+ .env is not in your .gitignore
60
+ → You are one git add away from leaking your secrets
61
+
62
+ ────────────────────────────
63
+
64
+ ✅ What's working (5 checks passed)
65
+
66
+ - Environment file detected
67
+ - No hardcoded secrets found
68
+ - Dependencies installed
69
+ - No duplicate variables
70
+ - NODE_ENV configured
71
+
72
+ ────────────────────────────
73
+
74
+ 💡 Next step
75
+
76
+ Run:
77
+ safelaunch init
78
+
79
+ Lock this configuration and prevent future breakage
54
80
  ```
55
81
 
56
82
  ---
57
83
 
84
+ ## What safelaunch checks
85
+
86
+ ### Environment
87
+ - Missing variables
88
+ - Empty variables
89
+ - Duplicate variables
90
+ - `VITE_` prefix validation
91
+ - `REACT_APP_` prefix validation
92
+ - `.env.example` out of sync
93
+
94
+ ### Secrets & Security
95
+ - `.env` committed to git
96
+ - `.env` not in `.gitignore`
97
+ - Hardcoded secrets in source files
98
+
99
+ ### Dependencies
100
+ - `node_modules` not installed
101
+ - Packages in `package.json` but not installed
102
+ - Lockfile missing
103
+
104
+ ### Build Readiness
105
+ - Build script missing
106
+ - Required config files missing (next.config.js, vite.config.js)
107
+ - TypeScript errors
108
+
109
+ ### Git State
110
+ - Uncommitted changes before deploy
111
+ - Unpushed commits
112
+
113
+ ---
114
+
58
115
  ## Installation
116
+
59
117
  ```bash
60
118
  npm install -g safelaunch
61
119
  ```
@@ -64,52 +122,38 @@ npm install -g safelaunch
64
122
 
65
123
  ## Lock it in permanently
66
124
 
67
- Once you've seen what scan finds, lock it in with two commands:
125
+ Once scan shows you what's broken, lock your configuration so it never breaks again.
68
126
 
69
127
  **Step 1 — Generate your environment manifest**
128
+
70
129
  ```bash
71
130
  safelaunch init
72
131
  ```
73
132
 
74
- Scans your codebase and generates an `env.manifest.json` contract file automatically.
133
+ Scans your codebase and creates an `env.manifest.json` — a contract file that defines exactly what your app needs to run.
134
+
135
+ **Step 2 — Validate before every deploy**
75
136
 
76
- **Step 2 — Validate before every push**
77
137
  ```bash
78
138
  safelaunch validate
79
139
  ```
80
140
 
81
- Runs 11 checks against your `.env` and tells you exactly what will break before it does.
141
+ Checks your live environment against the manifest and tells you exactly what will break before it does.
82
142
 
83
143
  ---
84
144
 
85
- ## Never think about it again — install the git hook
145
+ ## Never think about it again
146
+
86
147
  ```bash
87
148
  safelaunch hook install
88
149
  ```
89
150
 
90
- Blocks `git push` automatically if validation fails. Set it once, forget about it.
91
-
92
- ---
93
-
94
- ## What it checks
95
-
96
- 1. Missing required variables
97
- 2. Empty variables
98
- 3. Runtime version mismatch
99
- 4. Duplicate variables
100
- 5. Dependencies not installed
101
- 6. Dependency drift
102
- 7. `.env` vs `.env.example` sync
103
- 8. `VITE_` prefix validation
104
- 9. `REACT_APP_` prefix validation
105
- 10. `NEXT_PUBLIC_` awareness
106
- 11. `.env` file priority order
151
+ Installs a git hook that blocks `git push` automatically if validation fails. Set it once, forget about it.
107
152
 
108
153
  ---
109
154
 
110
155
  ## CI Integration
111
156
 
112
- Block deployments automatically by adding this to your GitHub Actions workflow:
113
157
  ```yaml
114
158
  - name: Install safelaunch
115
159
  run: npm install -g safelaunch
@@ -118,6 +162,16 @@ Block deployments automatically by adding this to your GitHub Actions workflow:
118
162
  run: safelaunch validate
119
163
  ```
120
164
 
165
+ Blocks deployments automatically if anything is missing or misconfigured.
166
+
167
+ ---
168
+
169
+ ## Privacy & Security
170
+
171
+ safelaunch runs **entirely on your machine**. It never sends your environment variables, secrets, or project data to external servers. Your `.env` files stay local. Always.
172
+
173
+ Anonymous usage telemetry is collected to help improve the product. No personal data, no secrets, no file contents — ever.
174
+
121
175
  ---
122
176
 
123
177
  Built by [Karthi Cedric](https://twitter.com/karthiced) · Part of [Orches](https://karthicedric7-cloud.github.io/Orches)
@@ -72,6 +72,14 @@ const IMPACT = {
72
72
  'You have commits that have not been pushed',
73
73
  '\u2192 Your deploy may not include your latest changes'
74
74
  ]),
75
+ typescriptErrors: () => impactBlock([
76
+ 'Your project has TypeScript type errors',
77
+ '\u2192 These may cause your build to fail in CI or production'
78
+ ]),
79
+ configFileMissing: (file) => impactBlock([
80
+ file + ' is missing',
81
+ '\u2192 Your framework will not know how to build or run this project'
82
+ ]),
75
83
  };
76
84
 
77
85
  const DIVIDER = '\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500';
@@ -91,11 +99,12 @@ function detectProjectType(cwd) {
91
99
  }
92
100
 
93
101
  function scanFiles(dir, extensions, pattern, found = new Set()) {
94
- const items = fs.readdirSync(dir);
102
+ let items;
103
+ try { items = fs.readdirSync(dir); } catch (_) { return found; }
95
104
  for (const item of items) {
96
105
  if (item === 'node_modules' || item === '.git') continue;
97
106
  const full = path.join(dir, item);
98
- const stat = fs.statSync(full);
107
+ let stat; try { stat = fs.statSync(full); } catch (_) { continue; }
99
108
  if (stat.isDirectory()) {
100
109
  scanFiles(full, extensions, pattern, found);
101
110
  } else if (extensions.some(ext => item.endsWith(ext))) {
@@ -187,11 +196,12 @@ function checkHardcodedSecrets(cwd) {
187
196
  const hits = [];
188
197
  function walk(dir) {
189
198
  try {
190
- const items = fs.readdirSync(dir);
199
+ let items;
200
+ try { items = fs.readdirSync(dir); } catch (_) { return found; }
191
201
  for (const item of items) {
192
202
  if (item === 'node_modules' || item === '.git') continue;
193
203
  const full = path.join(dir, item);
194
- const stat = fs.statSync(full);
204
+ let stat; try { stat = fs.statSync(full); } catch (_) { continue; }
195
205
  if (stat.isDirectory()) {
196
206
  walk(full);
197
207
  } else if (extensions.some(ext => item.endsWith(ext))) {
@@ -230,6 +240,33 @@ function checkGitStatus(cwd) {
230
240
  } catch (_) { return { uncommitted: false, unpushed: false }; }
231
241
  }
232
242
 
243
+ function checkTypeScript(cwd) {
244
+ if (!fs.existsSync(path.join(cwd, 'tsconfig.json'))) return false;
245
+ try {
246
+ execSync('npx tsc --noEmit', { cwd, stdio: ['pipe', 'pipe', 'ignore'] });
247
+ return false;
248
+ } catch (_) {
249
+ return true;
250
+ }
251
+ }
252
+
253
+ function checkRequiredConfigFiles(cwd, projectType) {
254
+ const missing = [];
255
+ if (projectType === 'next') {
256
+ if (!fs.existsSync(path.join(cwd, 'next.config.js')) &&
257
+ !fs.existsSync(path.join(cwd, 'next.config.ts'))) {
258
+ missing.push('next.config.js');
259
+ }
260
+ }
261
+ if (projectType === 'vite') {
262
+ if (!fs.existsSync(path.join(cwd, 'vite.config.js')) &&
263
+ !fs.existsSync(path.join(cwd, 'vite.config.ts'))) {
264
+ missing.push('vite.config.js');
265
+ }
266
+ }
267
+ return missing;
268
+ }
269
+
233
270
  function renderIssue(number, title, impact) {
234
271
  return number + '. ' + title + '\n\n' + impact + '\n';
235
272
  }
@@ -263,6 +300,8 @@ async function scan() {
263
300
  const hardcodedSecrets = checkHardcodedSecrets(cwd);
264
301
  const hasBuildScript = checkBuildScript(cwd);
265
302
  const gitStatus = checkGitStatus(cwd);
303
+ const hasTypeScriptErrors = checkTypeScript(cwd);
304
+ const missingConfigFiles = checkRequiredConfigFiles(cwd, projectType);
266
305
 
267
306
  let missing = [], empty = [], present = [], duplicates = [], envExampleOutOfSync = [];
268
307
 
@@ -296,6 +335,8 @@ async function scan() {
296
335
  if (drift && drift.notInstalled) criticalIssues.push({ title: 'Dependencies are not installed', impact: IMPACT.depsNotInstalled() });
297
336
  for (const file of envInGit) criticalIssues.push({ title: file + ' is tracked by git', impact: IMPACT.envInGit(file) });
298
337
  for (const file of hardcodedSecrets) criticalIssues.push({ title: 'Hardcoded secret in ' + file, impact: IMPACT.hardcodedSecret(file) });
338
+ for (const file of missingConfigFiles) criticalIssues.push({ title: file + ' is missing', impact: IMPACT.configFileMissing(file) });
339
+ if (hasTypeScriptErrors) criticalIssues.push({ title: 'TypeScript errors found', impact: IMPACT.typescriptErrors() });
299
340
 
300
341
  if (drift && !drift.notInstalled && drift.missing.length > 0) {
301
342
  for (const dep of drift.missing) warningIssues.push({ title: dep + ' is not installed', impact: IMPACT.depsDrift(dep) });
@@ -320,6 +361,8 @@ async function scan() {
320
361
  if (!drift || (!drift.notInstalled && drift.missing.length === 0)) passingChecks.push('Dependencies installed');
321
362
  if (duplicates.length === 0) passingChecks.push('No duplicate variables');
322
363
  if (hasBuildScript) passingChecks.push('Build script found');
364
+ if (!hasTypeScriptErrors && fs.existsSync(path.join(cwd, 'tsconfig.json'))) passingChecks.push('No TypeScript errors');
365
+ if (missingConfigFiles.length === 0) passingChecks.push('Config files present');
323
366
  if (!gitStatus.uncommitted) passingChecks.push('No uncommitted changes');
324
367
  if (!gitStatus.unpushed) passingChecks.push('No unpushed commits');
325
368
  for (const key of present) passingChecks.push(key + ' configured');
@@ -435,6 +478,8 @@ async function scan() {
435
478
  lockfile_missing: lockfileMissing,
436
479
  env_not_ignored: !envIgnored,
437
480
  build_script_missing: !hasBuildScript,
481
+ typescript_errors: hasTypeScriptErrors,
482
+ config_files_missing: missingConfigFiles.length,
438
483
  uncommitted: gitStatus.uncommitted,
439
484
  unpushed: gitStatus.unpushed
440
485
  });