safelaunch 1.0.23 → 1.0.25

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 (36) hide show
  1. package/README.md +65 -98
  2. package/bin/safelaunch.js +126 -0
  3. package/deploycheck-vscode/.vscode/launch.json +15 -0
  4. package/deploycheck-vscode/README.md +71 -0
  5. package/deploycheck-vscode/deploycheck-vscode-0.0.1.vsix +0 -0
  6. package/deploycheck-vscode/deploycheck-vscode-0.0.10.vsix +0 -0
  7. package/deploycheck-vscode/deploycheck-vscode-0.0.2.vsix +0 -0
  8. package/deploycheck-vscode/deploycheck-vscode-0.0.3.vsix +0 -0
  9. package/deploycheck-vscode/deploycheck-vscode-0.0.4.vsix +0 -0
  10. package/deploycheck-vscode/deploycheck-vscode-0.0.6.vsix +0 -0
  11. package/deploycheck-vscode/deploycheck-vscode-0.0.7.vsix +0 -0
  12. package/deploycheck-vscode/deploycheck-vscode-0.0.8.vsix +0 -0
  13. package/deploycheck-vscode/deploycheck-vscode-0.0.9.vsix +0 -0
  14. package/deploycheck-vscode/init.js +54 -0
  15. package/deploycheck-vscode/package.json +35 -0
  16. package/deploycheck-vscode/src/extension.js +277 -0
  17. package/package.json +11 -18
  18. package/src/hook.js +232 -0
  19. package/src/init.js +114 -0
  20. package/src/scan.js +333 -0
  21. package/src/setup.js +82 -0
  22. package/src/validate.js +375 -0
  23. package/.github/workflows/deploycheck.yml +0 -26
  24. package/index.js +0 -38
  25. package/safelaunch/README.md +0 -182
  26. package/safelaunch/bin/safelaunch.js +0 -33
  27. package/safelaunch/package-lock.json +0 -113
  28. package/safelaunch/package.json +0 -23
  29. package/safelaunch/src/hook.js +0 -88
  30. package/safelaunch/src/init.js +0 -107
  31. package/safelaunch/src/scan.js +0 -490
  32. package/safelaunch/src/setup.js +0 -488
  33. package/safelaunch/src/validate.js +0 -423
  34. /package/{safelaunch/env.manifest.json → env.manifest.json} +0 -0
  35. /package/{safelaunch/src → src}/telemetry.js +0 -0
  36. /package/{safelaunch/write-action.js → write-action.js} +0 -0
package/README.md CHANGED
@@ -1,10 +1,9 @@
1
1
  # safelaunch
2
-
3
- > The pre-deploy safety check for JavaScript projects.
2
+ > The pre-deploy guardrail for JavaScript projects.
4
3
 
5
4
  [![npm version](https://badge.fury.io/js/safelaunch.svg)](https://www.npmjs.com/package/safelaunch)
6
5
 
7
- Run one command before you deploy. safelaunch scans your entire project and tells you exactly what will break before it breaks in production.
6
+ One command turns safelaunch into a system that blocks bad pushes automaticallyforever.
8
7
 
9
8
  Works with **Node.js, Next.js, Vite, and Create React App**.
10
9
 
@@ -12,158 +11,126 @@ Works with **Node.js, Next.js, Vite, and Create React App**.
12
11
 
13
12
  ---
14
13
 
15
- ## Try it now zero setup
14
+ ## Get protected in one command
16
15
 
17
16
  ```bash
18
- npx safelaunch scan
17
+ npx safelaunch setup
19
18
  ```
20
19
 
21
- No installation. No config. Just run it in any JavaScript project.
22
-
23
- ```
24
- Scanning your project...
25
- Detected: Next.js
26
-
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
20
+ No installation. No config. Run it once in any JavaScript project.
39
21
 
40
- Impact:
41
- Your app cannot use DATABASE_URL
42
- → Will crash or behave incorrectly at runtime
22
+ safelaunch scans your project, shows you exactly what would break your next deploy, generates your environment manifest, and installs a git hook that **blocks bad pushes automatically from now on**.
43
23
 
44
24
  ---
45
25
 
46
- 2. STRIPE_SECRET_KEY is missing
26
+ ## What happens when you push
47
27
 
48
- Impact:
49
- Your app cannot use STRIPE_SECRET_KEY
50
- → Will crash or behave incorrectly at runtime
28
+ **If something will break production:**
51
29
 
52
- ────────────────────────────
53
-
54
- ⚠️ WARNINGS (may cause issues)
55
-
56
- 3. .env is not in .gitignore
57
-
58
- Impact:
59
- .env is not in your .gitignore
60
- → You are one git add away from leaking your secrets
61
-
62
- ────────────────────────────
30
+ ```
31
+ ✗ PUSH BLOCKED — 2 issues will break production
32
+ Fix all blockers before this code ships.
63
33
 
64
- What's working (5 checks passed)
34
+ ✗ STRIPE_SECRET_KEY is missing
35
+ Impact: Any code that reads process.env.STRIPE_SECRET_KEY will get undefined. This silently breaks at runtime.
36
+ → Add STRIPE_SECRET_KEY to your .env file.
65
37
 
66
- - Environment file detected
67
- - No hardcoded secrets found
68
- - Dependencies installed
69
- - No duplicate variables
70
- - NODE_ENV configured
38
+ ✗ DATABASE_URL is missing
39
+ Impact: Any code that reads process.env.DATABASE_URL will get undefined. This silently breaks at runtime.
40
+ Add DATABASE_URL to your .env file.
71
41
 
72
- ────────────────────────────
42
+ ─────────────────────────────────────────────────
43
+ 2 blockers · push aborted
73
44
 
74
- 💡 Next step
45
+ To skip (not recommended): git push --no-verify
46
+ ```
75
47
 
76
- Run:
77
- safelaunch init
48
+ **If everything is clean:**
78
49
 
79
- Lock this configuration and prevent future breakage
80
50
  ```
51
+ ✓ All checks passed (0.4s)
52
+ ```
53
+
54
+ Nothing else. Your push goes through.
81
55
 
82
56
  ---
83
57
 
84
58
  ## What safelaunch checks
85
59
 
86
60
  ### 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
61
+ - Missing required variables
62
+ - Empty variable values
63
+ - Duplicate variable definitions
64
+ - `VITE_` prefix validation (Vite projects)
65
+ - `REACT_APP_` prefix validation (CRA projects)
66
+ - `.env.example` gaps
93
67
 
94
68
  ### Secrets & Security
95
- - `.env` committed to git
69
+ - Secrets committed to staged files
96
70
  - `.env` not in `.gitignore`
97
- - Hardcoded secrets in source files
98
71
 
99
72
  ### Dependencies
100
73
  - `node_modules` not installed
101
74
  - Packages in `package.json` but not installed
102
- - Lockfile missing
75
+ - Lockfile out of sync with `package.json`
103
76
 
104
77
  ### Build Readiness
105
- - Build script missing
106
- - Required config files missing (next.config.js, vite.config.js)
107
- - TypeScript errors
78
+ - TypeScript errors (`tsc --noEmit`)
79
+ - Critical npm vulnerabilities
108
80
 
109
- ### Git State
110
- - Uncommitted changes before deploy
111
- - Unpushed commits
81
+ ### Runtime
82
+ - Node.js version mismatch (`.nvmrc`)
112
83
 
113
84
  ---
114
85
 
115
- ## Installation
86
+ ## Commands
116
87
 
117
88
  ```bash
118
- npm install -g safelaunch
89
+ npx safelaunch setup # Scan + generate manifest + install git hook
90
+ safelaunch scan # Run all checks
91
+ safelaunch init # Generate env.manifest.json from your .env
92
+ safelaunch validate # Validate current env against manifest
93
+ safelaunch hook install # Install the git hook manually
94
+ safelaunch hook uninstall # Remove the git hook
95
+ safelaunch hook status # Check if the hook is active
119
96
  ```
120
97
 
121
98
  ---
122
99
 
123
- ## Lock it in permanently
100
+ ## How the hook stays active
124
101
 
125
- Once scan shows you what's broken, lock your configuration so it never breaks again.
102
+ Once installed, the hook runs before every `git push`. If it ever goes missing, `safelaunch validate` detects and reinstalls it automatically.
126
103
 
127
- **Step 1 Generate your environment manifest**
128
-
129
- ```bash
130
- safelaunch init
131
- ```
132
-
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**
136
-
137
- ```bash
138
- safelaunch validate
139
- ```
140
-
141
- Checks your live environment against the manifest and tells you exactly what will break before it does.
104
+ New team members get the hook installed automatically via the `postinstall` script when they run `npm install`.
142
105
 
143
106
  ---
144
107
 
145
- ## Never think about it again
108
+ ## CI Integration
146
109
 
147
- ```bash
148
- safelaunch hook install
110
+ ```yaml
111
+ - name: Validate environment
112
+ run: npx safelaunch validate
149
113
  ```
150
114
 
151
- Installs a git hook that blocks `git push` automatically if validation fails. Set it once, forget about it.
115
+ Blocks the pipeline if required variables are missing or misconfigured.
152
116
 
153
117
  ---
154
118
 
155
- ## CI Integration
119
+ ## env.manifest.json
156
120
 
157
- ```yaml
158
- - name: Install safelaunch
159
- run: npm install -g safelaunch
121
+ `safelaunch setup` generates an `env.manifest.json` — a contract that locks which variables your project requires. Commit this file. Every push is validated against it.
160
122
 
161
- - name: Validate environment
162
- run: safelaunch validate
123
+ ```json
124
+ {
125
+ "version": "1.0.0",
126
+ "required": [
127
+ "DATABASE_URL",
128
+ "STRIPE_SECRET_KEY",
129
+ "NEXTAUTH_SECRET"
130
+ ]
131
+ }
163
132
  ```
164
133
 
165
- Blocks deployments automatically if anything is missing or misconfigured.
166
-
167
134
  ---
168
135
 
169
136
  ## Privacy & Security
@@ -0,0 +1,126 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { runScan } = require("../src/scan");
4
+ const { installHook, uninstallHook, verifyHook, hookStatus, handleHookCommand } = require("../src/hook");
5
+ const setup = require("../src/setup");
6
+ const init = require("../src/init");
7
+ const validate = require("../src/validate");
8
+
9
+ // ─── Colours ─────────────────────────────────────────────────────────────────
10
+ const c = {
11
+ reset: "\x1b[0m", bold: "\x1b[1m", dim: "\x1b[2m",
12
+ green: "\x1b[32m", cyan: "\x1b[36m", gray: "\x1b[90m",
13
+ };
14
+ const green = (s) => `${c.green}${c.bold}${s}${c.reset}`;
15
+ const cyan = (s) => `${c.cyan}${s}${c.reset}`;
16
+ const gray = (s) => `${c.gray}${s}${c.reset}`;
17
+ const dim = (s) => `${c.dim}${s}${c.reset}`;
18
+ const bold = (s) => `${c.bold}${s}${c.reset}`;
19
+
20
+ // ─── Version ──────────────────────────────────────────────────────────────────
21
+ let version = "1.0.24";
22
+ try {
23
+ version = require("../package.json").version;
24
+ } catch {}
25
+
26
+ // ─── Help text ────────────────────────────────────────────────────────────────
27
+ function printHelp() {
28
+ console.log(`
29
+ ${bold("safelaunch")} ${gray(`v${version}`)} — pre-deploy guardrail for JavaScript projects
30
+
31
+ ${bold("USAGE")}
32
+ ${cyan("npx safelaunch setup")} Scan, generate env.manifest.json, install git hook
33
+ ${cyan("safelaunch scan")} Run all checks and show issues
34
+ ${cyan("safelaunch init")} Generate env.manifest.json from current .env
35
+ ${cyan("safelaunch validate")} Validate current env against env.manifest.json
36
+ ${cyan("safelaunch hook install")} Install the pre-push git hook manually
37
+ ${cyan("safelaunch hook uninstall")} Remove the pre-push git hook
38
+ ${cyan("safelaunch hook status")} Check whether the hook is active
39
+
40
+ ${bold("FLAGS")}
41
+ ${cyan("--hook")} Used internally by the git hook (tighter output)
42
+ ${cyan("--force")} Force-replace an existing hook from another tool
43
+ ${cyan("--version")} Print version and exit
44
+ ${cyan("--help")} Print this help
45
+
46
+ ${bold("HOW IT WORKS")}
47
+ Run ${cyan("npx safelaunch setup")} once in your project.
48
+ From then on, every ${cyan("git push")} is scanned automatically.
49
+ Issues that will break production are blocked. Clean pushes pass silently.
50
+ `);
51
+ }
52
+
53
+ // ─── Parse flags ─────────────────────────────────────────────────────────────
54
+ const args = process.argv.slice(2);
55
+ const cmd = args.find((a) => !a.startsWith("-"));
56
+ const flags = {};
57
+ for (const a of args) {
58
+ if (a.startsWith("--")) flags[a] = true;
59
+ }
60
+ const hookMode = flags["--hook"] === true;
61
+ const silent = flags["--silent"] === true;
62
+
63
+ // ─── Dispatch ─────────────────────────────────────────────────────────────────
64
+ (async () => {
65
+ if (flags["--version"] || flags["-v"]) {
66
+ console.log(version);
67
+ process.exit(0);
68
+ }
69
+
70
+ if (flags["--help"] || flags["-h"]) {
71
+ printHelp();
72
+ process.exit(0);
73
+ }
74
+
75
+ switch (cmd) {
76
+ // ── setup: scan + init + hook install in one shot ──────────────────────
77
+ case "setup":
78
+ case undefined: {
79
+ // When called with no args and no --hook flag, run setup
80
+ if (!hookMode) {
81
+ await setup.run({ cwd: process.cwd() });
82
+ } else {
83
+ // --hook with no command: run scan in hook mode
84
+ const { blockers } = await runScan({ hookMode: true, cwd: process.cwd() });
85
+ process.exit(blockers.length > 0 ? 1 : 0);
86
+ }
87
+ break;
88
+ }
89
+
90
+ // ── scan ────────────────────────────────────────────────────────────────
91
+ case "scan": {
92
+ if (!hookMode && !silent) {
93
+ process.stdout.write(gray(`safelaunch v${version} — scanning...\n\n`));
94
+ }
95
+ const { blockers } = await runScan({ hookMode, cwd: process.cwd() });
96
+ process.exit(blockers.length > 0 ? 1 : 0);
97
+ }
98
+
99
+ // ── init ────────────────────────────────────────────────────────────────
100
+ case "init": {
101
+ await init.run({ cwd: process.cwd() });
102
+ break;
103
+ }
104
+
105
+ // ── validate ─────────────────────────────────────────────────────────────
106
+ case "validate": {
107
+ // Also verify the hook is still present
108
+ verifyHook({ silent: false, autoInstall: true, cwd: process.cwd() });
109
+ await validate.run({ cwd: process.cwd() });
110
+ break;
111
+ }
112
+
113
+ // ── hook ─────────────────────────────────────────────────────────────────
114
+ case "hook": {
115
+ const subcommand = args[args.indexOf("hook") + 1];
116
+ handleHookCommand(subcommand, flags);
117
+ break;
118
+ }
119
+
120
+ default: {
121
+ console.error(`\nUnknown command: ${cmd}\n`);
122
+ printHelp();
123
+ process.exit(1);
124
+ }
125
+ }
126
+ })();
@@ -0,0 +1,15 @@
1
+ {
2
+ // Use IntelliSense to learn about possible attributes.
3
+ // Hover to view descriptions of existing attributes.
4
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
+ "version": "0.2.0",
6
+ "configurations": [
7
+ {
8
+ "type": "chrome",
9
+ "request": "launch",
10
+ "name": "Launch Chrome against localhost",
11
+ "url": "http://localhost:8080",
12
+ "webRoot": "${workspaceFolder}"
13
+ }
14
+ ]
15
+ }
@@ -0,0 +1,71 @@
1
+ # deploycheck
2
+ > Catch what breaks production before it breaks.
3
+
4
+ Real time environment validation inside VS Code. deploycheck runs 11 checks on your environment before you push to production.
5
+
6
+ Works with Node.js, Next.js, Vite, and Create React App. Automatically detects your project type.
7
+
8
+ ## Commands
9
+
10
+ Open the Command Palette with Ctrl+Shift+P and run:
11
+
12
+ **deploycheck: Generate env.manifest.json**
13
+
14
+ Scans your entire project for environment variables and automatically generates env.manifest.json.
15
+
16
+ Works with:
17
+ - process.env for Node.js and Next.js projects
18
+ - import.meta.env for Vite projects
19
+ - REACT_APP_ variables for Create React App
20
+
21
+ **deploycheck: Validate Environment**
22
+
23
+ Runs 11 checks on your environment and tells you exactly what will break before you push.
24
+
25
+ ## What deploycheck checks
26
+
27
+ 1. Missing required environment variables
28
+ 2. Empty required environment variables
29
+ 3. Runtime version mismatch (Node version)
30
+ 4. Duplicate variables in .env
31
+ 5. Dependencies not installed
32
+ 6. Dependency drift (in package.json but not installed)
33
+ 7. Variables in .env.example but missing from .env
34
+ 8. VITE_ prefix warning (Vite projects — variables without VITE_ won't be exposed to the client)
35
+ 9. REACT_APP_ prefix warning (CRA projects — variables without REACT_APP_ won't be exposed to the client)
36
+ 10. NEXT_PUBLIC_ prefix awareness (Next.js — flags variables intended for the client)
37
+ 11. .env file priority conflicts (Next.js — warns when .env.local overrides .env silently)
38
+
39
+ ## Supported project types
40
+
41
+ deploycheck automatically detects your project type.
42
+
43
+ - Node.js scans process.env
44
+ - Next.js scans process.env, checks NEXT_PUBLIC_ and .env priority
45
+ - Vite scans import.meta.env, checks VITE_ prefix
46
+ - React CRA scans REACT_APP_ variables, checks REACT_APP_ prefix
47
+
48
+ ## How it works
49
+
50
+ Step 1: Open your project in VS Code
51
+ Step 2: Press Ctrl+Shift+P
52
+ Step 3: Type deploycheck
53
+ Step 4: Run Generate to create your manifest
54
+ Step 5: Run Validate before every push
55
+
56
+ ## CLI Version
57
+
58
+ For terminal and CI use install the CLI:
59
+
60
+ npm install -g safelaunch
61
+
62
+ safelaunch init
63
+
64
+ safelaunch validate
65
+
66
+ ## Built by Orches
67
+
68
+ JavaScript Reliability Infrastructure.
69
+
70
+ GitHub: https://github.com/karthicedric7-cloud/safelaunch
71
+ npm: https://www.npmjs.com/package/safelaunch
@@ -0,0 +1,54 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ function scanFiles(dir, extensions, found = new Set()) {
5
+ const items = fs.readdirSync(dir);
6
+ for (const item of items) {
7
+ if (item === 'node_modules' || item === '.git') continue;
8
+ const full = path.join(dir, item);
9
+ const stat = fs.statSync(full);
10
+ if (stat.isDirectory()) {
11
+ scanFiles(full, extensions, found);
12
+ } else if (extensions.some(ext => item.endsWith(ext))) {
13
+ const content = fs.readFileSync(full, 'utf8');
14
+ const matches = content.matchAll(/process\.env\.([A-Z_][A-Z0-9_]*)/g);
15
+ for (const match of matches) {
16
+ found.add(match[1]);
17
+ }
18
+ }
19
+ }
20
+ return found;
21
+ }
22
+
23
+ function init() {
24
+ console.log('\nscanning project for environment variables...\n');
25
+ const cwd = process.cwd();
26
+ const extensions = ['.js', '.ts', '.jsx', '.tsx'];
27
+ const found = scanFiles(cwd, extensions);
28
+ if (found.size === 0) {
29
+ console.log('no process.env references found.\n');
30
+ return;
31
+ }
32
+ const variables = {};
33
+ for (const key of [...found].sort()) {
34
+ variables[key] = { required: true, description: '' };
35
+ }
36
+ const manifest = {
37
+ version: '1',
38
+ runtime: { node: process.version.replace('v', '').split('.')[0] },
39
+ variables
40
+ };
41
+ const manifestPath = path.join(cwd, 'env.manifest.json');
42
+ if (fs.existsSync(manifestPath)) {
43
+ console.log('env.manifest.json already exists. delete it first.\n');
44
+ return;
45
+ }
46
+ fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
47
+ console.log('found ' + found.size + ' environment variables:\n');
48
+ for (const key of [...found].sort()) {
49
+ console.log(' ' + key);
50
+ }
51
+ console.log('\ncreated env.manifest.json\n');
52
+ }
53
+
54
+ init();
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "deploycheck-vscode",
3
+ "displayName": "deploycheck",
4
+ "description": "Catch what breaks production before it breaks. Real time environment validation inside VS Code.",
5
+ "version": "0.0.10",
6
+ "publisher": "Orches",
7
+ "engines": {
8
+ "vscode": "^1.74.0"
9
+ },
10
+ "categories": [
11
+ "Linters"
12
+ ],
13
+ "activationEvents": [
14
+ "*"
15
+ ],
16
+ "main": "./src/extension.js",
17
+ "contributes": {
18
+ "commands": [
19
+ {
20
+ "command": "deploycheck.init",
21
+ "title": "deploycheck: Generate env.manifest.json"
22
+ },
23
+ {
24
+ "command": "deploycheck.validate",
25
+ "title": "deploycheck: Validate Environment"
26
+ }
27
+ ]
28
+ },
29
+ "scripts": {
30
+ "test": "echo \"Error: no test specified\" && exit 1"
31
+ },
32
+ "devDependencies": {
33
+ "@types/vscode": "^1.74.0"
34
+ }
35
+ }