predeploy-check 1.0.0 → 1.1.0

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/index.js CHANGED
@@ -1,130 +1,137 @@
1
- 'use strict';
2
-
3
- const chalk = require('chalk');
4
- const path = require('path');
5
- const fs = require('fs');
6
-
7
- // Dynamically load all check modules from /checks/
8
- const checksDir = path.join(__dirname, 'checks');
9
- const checkFiles = fs.readdirSync(checksDir)
10
- .filter((f) => f.endsWith('.js'))
11
- .sort();
12
-
13
- const checks = checkFiles.map((f) => {
14
- const mod = require(path.join(checksDir, f));
15
- return {
16
- name: mod.name || f.replace('.js', ''),
17
- run: mod.run,
18
- };
19
- });
20
-
21
- const STATUS_ICONS = {
22
- pass: chalk.green('✅'),
23
- warn: chalk.yellow('⚠️ '),
24
- fail: chalk.red('❌'),
25
- skip: chalk.gray('⏭️ '),
26
- };
27
-
28
- const STATUS_COLORS = {
29
- pass: chalk.green,
30
- warn: chalk.yellow,
31
- fail: chalk.red,
32
- skip: chalk.gray,
33
- };
34
-
35
- /**
36
- * Format a single result line.
37
- */
38
- function formatResult(result) {
39
- const icon = STATUS_ICONS[result.status] || '?';
40
- const color = STATUS_COLORS[result.status] || chalk.white;
41
- const lines = [];
42
-
43
- lines.push(`${icon} ${color.bold(result.message)}`);
44
-
45
- if (result.details && result.details.length > 0) {
46
- for (const detail of result.details) {
47
- const loc = detail.file
48
- ? chalk.dim(` ${detail.file}${detail.line ? `:${detail.line}` : ''}`)
49
- : '';
50
- if (loc) lines.push(loc);
51
- if (detail.message) lines.push(chalk.dim(` → ${detail.message}`));
52
- }
53
- }
54
-
55
- if (result.fix && result.status !== 'pass') {
56
- lines.push(chalk.cyan(` 💡 Fix: ${result.fix}`));
57
- }
58
-
59
- return lines.join('\n');
60
- }
61
-
62
- /**
63
- * Run all checks against the given project root.
64
- * Returns exit code: 1 if any ❌, 0 otherwise.
65
- */
66
- async function runAllChecks(projectRoot) {
67
- console.log('');
68
- console.log(chalk.bold.underline(` predeploy-check`) + chalk.dim(` scanning ${projectRoot}`));
69
- console.log(chalk.dim(' ─'.repeat(30)));
70
- console.log('');
71
-
72
- let hasFail = false;
73
- let passCount = 0;
74
- let warnCount = 0;
75
- let failCount = 0;
76
- let skipCount = 0;
77
-
78
- for (const check of checks) {
79
- try {
80
- const results = await check.run(projectRoot);
81
-
82
- // A check can return a single result or an array of results
83
- const resultArray = Array.isArray(results) ? results : [results];
84
-
85
- for (const result of resultArray) {
86
- console.log(formatResult(result));
87
- console.log('');
88
-
89
- if (result.status === 'fail') {
90
- hasFail = true;
91
- failCount++;
92
- } else if (result.status === 'warn') {
93
- warnCount++;
94
- } else if (result.status === 'skip') {
95
- skipCount++;
96
- } else {
97
- passCount++;
98
- }
99
- }
100
- } catch (err) {
101
- console.log(chalk.red(`❌ ${check.name}: internal error — ${err.message}`));
102
- console.log('');
103
- hasFail = true;
104
- failCount++;
105
- }
106
- }
107
-
108
- // Summary bar
109
- console.log(chalk.dim(''.repeat(30)));
110
-
111
- const parts = [];
112
- if (passCount > 0) parts.push(chalk.green(`${passCount} passed`));
113
- if (warnCount > 0) parts.push(chalk.yellow(`${warnCount} warnings`));
114
- if (failCount > 0) parts.push(chalk.red(`${failCount} failed`));
115
- if (skipCount > 0) parts.push(chalk.gray(`${skipCount} skipped`));
116
-
117
- console.log(`\n ${chalk.bold('Summary:')} ${parts.join(chalk.dim(' · '))}`);
118
-
119
- if (hasFail) {
120
- console.log(chalk.red.bold('\n Deploy will likely fail. Fix ❌ issues above.\n'));
121
- } else if (warnCount > 0) {
122
- console.log(chalk.yellow('\n Some warnings detected. Review ⚠️ items above.\n'));
123
- } else {
124
- console.log(chalk.green.bold('\n All checks passed! You\'re good to deploy. 🚀\n'));
125
- }
126
-
127
- return hasFail ? 1 : 0;
128
- }
129
-
130
- module.exports = { runAllChecks };
1
+ 'use strict';
2
+
3
+ const chalk = require('chalk');
4
+ const path = require('path');
5
+ const fs = require('fs');
6
+
7
+ // Dynamically load all check modules from /checks/
8
+ const checksDir = path.join(__dirname, 'checks');
9
+ const checkFiles = fs.readdirSync(checksDir)
10
+ .filter((f) => f.endsWith('.js'))
11
+ .sort();
12
+
13
+ const checks = checkFiles.map((f) => {
14
+ const mod = require(path.join(checksDir, f));
15
+ return {
16
+ name: mod.name || f.replace('.js', ''),
17
+ run: mod.run,
18
+ };
19
+ });
20
+
21
+ const STATUS_ICONS = {
22
+ pass: chalk.green('✅'),
23
+ warn: chalk.yellow('⚠️ '),
24
+ fail: chalk.red('❌'),
25
+ skip: chalk.gray('⏭️ '),
26
+ };
27
+
28
+ const STATUS_COLORS = {
29
+ pass: chalk.green,
30
+ warn: chalk.yellow,
31
+ fail: chalk.red,
32
+ skip: chalk.gray,
33
+ };
34
+
35
+ /**
36
+ * Format a single result line.
37
+ */
38
+ function formatResult(result) {
39
+ const icon = STATUS_ICONS[result.status] || '?';
40
+ const color = STATUS_COLORS[result.status] || chalk.white;
41
+ const lines = [];
42
+
43
+ lines.push(`${icon} ${color.bold(result.message)}`);
44
+
45
+ if (result.details && result.details.length > 0) {
46
+ for (const detail of result.details) {
47
+ const loc = detail.file
48
+ ? chalk.dim(` ${detail.file}${detail.line ? `:${detail.line}` : ''}`)
49
+ : '';
50
+ if (loc) lines.push(loc);
51
+ if (detail.message) lines.push(chalk.dim(` → ${detail.message}`));
52
+ }
53
+ }
54
+
55
+ if (result.fix && result.status !== 'pass') {
56
+ lines.push(chalk.cyan(` 💡 Fix: ${result.fix}`));
57
+ }
58
+
59
+ return lines.join('\n');
60
+ }
61
+
62
+ /**
63
+ * Run all checks against the given project root.
64
+ * Returns exit code: 1 if any ❌, 0 otherwise.
65
+ */
66
+ async function runAllChecks(projectRoot, options = {}) {
67
+ console.log('');
68
+ console.log(chalk.bold.underline(` predeploy-check`) + chalk.dim(` scanning ${projectRoot}`));
69
+ if (options.live) {
70
+ if (typeof fetch === 'function') {
71
+ console.log(chalk.dim(' live mode: verifying wheel availability against PyPI (requires internet)'));
72
+ } else {
73
+ console.log(chalk.yellow(' live mode requested, but this Node.js version has no global fetch (needs Node 18+) — falling back to static checks'));
74
+ }
75
+ }
76
+ console.log(chalk.dim(' ─'.repeat(30)));
77
+ console.log('');
78
+
79
+ let hasFail = false;
80
+ let passCount = 0;
81
+ let warnCount = 0;
82
+ let failCount = 0;
83
+ let skipCount = 0;
84
+
85
+ for (const check of checks) {
86
+ try {
87
+ const results = await check.run(projectRoot, options);
88
+
89
+ // A check can return a single result or an array of results
90
+ const resultArray = Array.isArray(results) ? results : [results];
91
+
92
+ for (const result of resultArray) {
93
+ console.log(formatResult(result));
94
+ console.log('');
95
+
96
+ if (result.status === 'fail') {
97
+ hasFail = true;
98
+ failCount++;
99
+ } else if (result.status === 'warn') {
100
+ warnCount++;
101
+ } else if (result.status === 'skip') {
102
+ skipCount++;
103
+ } else {
104
+ passCount++;
105
+ }
106
+ }
107
+ } catch (err) {
108
+ console.log(chalk.red(`❌ ${check.name}: internal error — ${err.message}`));
109
+ console.log('');
110
+ hasFail = true;
111
+ failCount++;
112
+ }
113
+ }
114
+
115
+ // Summary bar
116
+ console.log(chalk.dim(' ─'.repeat(30)));
117
+
118
+ const parts = [];
119
+ if (passCount > 0) parts.push(chalk.green(`${passCount} passed`));
120
+ if (warnCount > 0) parts.push(chalk.yellow(`${warnCount} warnings`));
121
+ if (failCount > 0) parts.push(chalk.red(`${failCount} failed`));
122
+ if (skipCount > 0) parts.push(chalk.gray(`${skipCount} skipped`));
123
+
124
+ console.log(`\n ${chalk.bold('Summary:')} ${parts.join(chalk.dim(' · '))}`);
125
+
126
+ if (hasFail) {
127
+ console.log(chalk.red.bold('\n Deploy will likely fail. Fix ❌ issues above.\n'));
128
+ } else if (warnCount > 0) {
129
+ console.log(chalk.yellow('\n Some warnings detected. Review ⚠️ items above.\n'));
130
+ } else {
131
+ console.log(chalk.green.bold('\n All checks passed! You\'re good to deploy. 🚀\n'));
132
+ }
133
+
134
+ return hasFail ? 1 : 0;
135
+ }
136
+
137
+ module.exports = { runAllChecks };
package/package.json CHANGED
@@ -1,37 +1,37 @@
1
- {
2
- "name": "predeploy-check",
3
- "version": "1.0.0",
4
- "description": "Scan a project folder and flag known deployment-failure patterns for Render and Vercel before you push.",
5
- "main": "index.js",
6
- "bin": {
7
- "predeploy-check": "bin/cli.js"
8
- },
9
- "scripts": {
10
- "start": "node bin/cli.js",
11
- "test": "node bin/cli.js"
12
- },
13
- "keywords": [
14
- "deploy",
15
- "vercel",
16
- "render",
17
- "lint",
18
- "pre-deploy",
19
- "ci",
20
- "deployment",
21
- "check"
22
- ],
23
- "author": "",
24
- "license": "MIT",
25
- "dependencies": {
26
- "chalk": "^4.1.2"
27
- },
28
- "engines": {
29
- "node": ">=14.0.0"
30
- },
31
- "files": [
32
- "bin/",
33
- "checks/",
34
- "index.js",
35
- "README.md"
36
- ]
37
- }
1
+ {
2
+ "name": "predeploy-check",
3
+ "version": "1.1.0",
4
+ "description": "Scan a project folder and flag known deployment-failure patterns for Render and Vercel before you push.",
5
+ "main": "index.js",
6
+ "bin": {
7
+ "predeploy-check": "bin/cli.js"
8
+ },
9
+ "scripts": {
10
+ "start": "node bin/cli.js",
11
+ "test": "node --test test/*.test.js"
12
+ },
13
+ "keywords": [
14
+ "deploy",
15
+ "vercel",
16
+ "render",
17
+ "lint",
18
+ "pre-deploy",
19
+ "ci",
20
+ "deployment",
21
+ "check"
22
+ ],
23
+ "author": "",
24
+ "license": "MIT",
25
+ "dependencies": {
26
+ "chalk": "^4.1.2"
27
+ },
28
+ "engines": {
29
+ "node": ">=14.0.0"
30
+ },
31
+ "files": [
32
+ "bin/",
33
+ "checks/",
34
+ "index.js",
35
+ "README.md"
36
+ ]
37
+ }