@bobfrankston/npmglobalize 1.0.38 → 1.0.39

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
@@ -397,6 +397,40 @@ Check authentication:
397
397
  npm whoami
398
398
  ```
399
399
 
400
+ ## Development
401
+
402
+ ### Build Check
403
+
404
+ `npmglobalize` includes automatic build verification to ensure TypeScript files are compiled before execution. This prevents runtime errors from outdated JavaScript files.
405
+
406
+ **How it works:**
407
+ - When you run `npmglobalize`, it automatically checks if `.js` files are newer than their `.ts` sources
408
+ - If `.js` files are missing or outdated, execution stops with an error
409
+ - The check is skipped if `noEmit: true` is set in `tsconfig.json`
410
+
411
+ **Building the project:**
412
+ ```bash
413
+ npm run build # Compile TypeScript files
414
+ npm run watch # Watch mode for development
415
+ npm run check # Manually verify build status
416
+ ```
417
+
418
+ **Bypassing the check:**
419
+ ```bash
420
+ npmglobalize --force # Skip build check (not recommended)
421
+ ```
422
+
423
+ **Error example:**
424
+ ```
425
+ ❌ Error: TypeScript files not compiled
426
+ cli.js is older than cli.ts
427
+
428
+ Please run: npm run build
429
+ Or use --force to skip this check
430
+ ```
431
+
432
+ This ensures you never accidentally run outdated code when the TypeScript source has changed.
433
+
400
434
  ## License
401
435
 
402
436
  MIT
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=check-build.d.ts.map
package/check-build.js ADDED
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Check if TypeScript files are compiled before running
4
+ * Ensures .js files exist and are newer than their .ts source files
5
+ * Unless --force flag is specified or noEmit is set in tsconfig.json
6
+ */
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+ import { fileURLToPath } from 'url';
10
+ import JSON5 from 'json5';
11
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
12
+ // Check for --force flag
13
+ const hasForceFlag = process.argv.includes('--force');
14
+ // Read and parse tsconfig.json
15
+ function readTsConfig() {
16
+ try {
17
+ const tsconfigPath = path.join(__dirname, 'tsconfig.json');
18
+ const content = fs.readFileSync(tsconfigPath, 'utf8');
19
+ return JSON5.parse(content);
20
+ }
21
+ catch (error) {
22
+ console.error('Warning: Could not read tsconfig.json');
23
+ return null;
24
+ }
25
+ }
26
+ // Check if a path matches any of the exclude patterns
27
+ function isExcluded(relativePath, excludePatterns) {
28
+ if (!excludePatterns || excludePatterns.length === 0) {
29
+ return false;
30
+ }
31
+ // Normalize path separators for comparison
32
+ const normalizedPath = relativePath.replace(/\\/g, '/');
33
+ for (const pattern of excludePatterns) {
34
+ const normalizedPattern = pattern.replace(/\\/g, '/');
35
+ // Simple pattern matching (supports exact matches and wildcards)
36
+ if (normalizedPath === normalizedPattern) {
37
+ return true;
38
+ }
39
+ // Check if path starts with pattern (for directory exclusions)
40
+ if (normalizedPath.startsWith(normalizedPattern + '/') ||
41
+ normalizedPath === normalizedPattern) {
42
+ return true;
43
+ }
44
+ // Check if any path segment matches the pattern
45
+ const pathSegments = normalizedPath.split('/');
46
+ if (pathSegments.includes(normalizedPattern)) {
47
+ return true;
48
+ }
49
+ }
50
+ return false;
51
+ }
52
+ // Get all .ts files in the project (respecting tsconfig exclude)
53
+ function getTypeScriptFiles(tsconfig) {
54
+ const files = [];
55
+ const excludePatterns = tsconfig?.exclude || [];
56
+ // Always exclude node_modules and .git
57
+ const alwaysExclude = ['node_modules', '.git'];
58
+ const allExcludes = [...alwaysExclude, ...excludePatterns];
59
+ function scanDir(dir, relativePath = '') {
60
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
61
+ for (const entry of entries) {
62
+ const fullPath = path.join(dir, entry.name);
63
+ const relPath = relativePath ? path.join(relativePath, entry.name) : entry.name;
64
+ // Check if this path is excluded
65
+ if (isExcluded(relPath, allExcludes)) {
66
+ continue;
67
+ }
68
+ if (entry.isDirectory()) {
69
+ scanDir(fullPath, relPath);
70
+ }
71
+ else if (entry.isFile() && entry.name.endsWith('.ts')) {
72
+ files.push(fullPath);
73
+ }
74
+ }
75
+ }
76
+ scanDir(__dirname);
77
+ return files;
78
+ }
79
+ // Check if .js file exists and is newer than .ts file
80
+ function checkBuildStatus() {
81
+ const tsconfig = readTsConfig();
82
+ // Check for noEmit
83
+ if (tsconfig?.compilerOptions?.noEmit === true) {
84
+ console.log('✓ noEmit is set in tsconfig.json, skipping build check');
85
+ return true;
86
+ }
87
+ if (hasForceFlag) {
88
+ console.log('✓ --force flag specified, skipping build check');
89
+ return true;
90
+ }
91
+ const tsFiles = getTypeScriptFiles(tsconfig);
92
+ const errors = [];
93
+ for (const tsFile of tsFiles) {
94
+ const jsFile = tsFile.replace(/\.ts$/, '.js');
95
+ // Check if .js file exists
96
+ if (!fs.existsSync(jsFile)) {
97
+ const relPath = path.relative(__dirname, tsFile);
98
+ errors.push(`Missing: ${relPath.replace(/\.ts$/, '.js')}`);
99
+ continue;
100
+ }
101
+ // Check if .js is older than .ts
102
+ const tsStat = fs.statSync(tsFile);
103
+ const jsStat = fs.statSync(jsFile);
104
+ if (jsStat.mtime < tsStat.mtime) {
105
+ const relPath = path.relative(__dirname, tsFile);
106
+ errors.push(`Outdated: ${relPath.replace(/\.ts$/, '.js')} is older than ${relPath}`);
107
+ }
108
+ }
109
+ if (errors.length > 0) {
110
+ console.error('\n❌ Build check failed:\n');
111
+ errors.forEach(err => console.error(` • ${err}`));
112
+ console.error('\nPlease run: npm run build');
113
+ console.error('Or use --force to skip this check\n');
114
+ return false;
115
+ }
116
+ console.log('✓ All TypeScript files are compiled');
117
+ return true;
118
+ }
119
+ // Run the check
120
+ if (!checkBuildStatus()) {
121
+ process.exit(1);
122
+ }
123
+ //# sourceMappingURL=check-build.js.map
124
+ //# sourceMappingURL=check-build.js.map
125
+ //# sourceMappingURL=check-build.js.map
126
+ //# sourceMappingURL=check-build.js.map
127
+ //# sourceMappingURL=check-build.js.map
128
+ //# sourceMappingURL=check-build.js.map
129
+ //# sourceMappingURL=check-build.js.map
130
+ //# sourceMappingURL=check-build.js.map
131
+ //# sourceMappingURL=check-build.js.map
132
+ //# sourceMappingURL=check-build.js.map
133
+ //# sourceMappingURL=check-build.js.map
134
+ //# sourceMappingURL=check-build.js.map
135
+ //# sourceMappingURL=check-build.js.map
136
+ //# sourceMappingURL=check-build.js.map
137
+ //# sourceMappingURL=check-build.js.map
138
+ //# sourceMappingURL=check-build.js.map
139
+ //# sourceMappingURL=check-build.js.map
package/cli.d.ts CHANGED
File without changes
package/cli.js CHANGED
@@ -6,6 +6,7 @@ import { globalize, readConfig } from './lib.js';
6
6
  import fs from 'fs';
7
7
  import path from 'path';
8
8
  import { fileURLToPath } from 'url';
9
+ import JSON5 from 'json5';
9
10
  function printHelp() {
10
11
  console.log(`
11
12
  npmglobalize - Transform file: dependencies to npm versions for publishing
@@ -250,6 +251,45 @@ export async function main() {
250
251
  console.log(pkg.version);
251
252
  process.exit(0);
252
253
  }
254
+ // Check if TypeScript files are compiled (unless --force or --help/--version)
255
+ if (!cliOptions.force && !cliOptions.help && !cliOptions.version) {
256
+ const __filename = fileURLToPath(import.meta.url);
257
+ const __dirname = path.dirname(__filename);
258
+ // Check for noEmit in tsconfig.json
259
+ let noEmit = false;
260
+ try {
261
+ const tsconfigPath = path.join(__dirname, 'tsconfig.json');
262
+ const content = fs.readFileSync(tsconfigPath, 'utf-8');
263
+ const tsconfig = JSON5.parse(content);
264
+ noEmit = tsconfig.compilerOptions?.noEmit === true;
265
+ }
266
+ catch (error) {
267
+ // If we can't read tsconfig, assume we need to check
268
+ }
269
+ if (!noEmit) {
270
+ // Check if this .js file is older than its .ts source
271
+ const jsFile = __filename;
272
+ const tsFile = jsFile.replace(/\.js$/, '.ts');
273
+ if (fs.existsSync(tsFile)) {
274
+ if (!fs.existsSync(jsFile)) {
275
+ console.error('\n❌ Error: TypeScript files not compiled');
276
+ console.error(`Missing: ${path.basename(jsFile)}`);
277
+ console.error('\nPlease run: npm run build');
278
+ console.error('Or use --force to skip this check\n');
279
+ process.exit(1);
280
+ }
281
+ const tsStat = fs.statSync(tsFile);
282
+ const jsStat = fs.statSync(jsFile);
283
+ if (jsStat.mtime < tsStat.mtime) {
284
+ console.error('\n❌ Error: TypeScript files not compiled');
285
+ console.error(`${path.basename(jsFile)} is older than ${path.basename(tsFile)}`);
286
+ console.error('\nPlease run: npm run build');
287
+ console.error('Or use --force to skip this check\n');
288
+ process.exit(1);
289
+ }
290
+ }
291
+ }
292
+ }
253
293
  if (cliOptions.error) {
254
294
  console.error(`Error: ${cliOptions.error}`);
255
295
  console.error('Run with --help for usage.');
package/index.d.ts CHANGED
File without changes
package/index.js CHANGED
File without changes
package/lib.d.ts CHANGED
File without changes
package/lib.js CHANGED
File without changes
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/npmglobalize",
3
- "version": "1.0.38",
3
+ "version": "1.0.39",
4
4
  "description": "Transform file: dependencies to npm versions for publishing",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -9,7 +9,9 @@
9
9
  },
10
10
  "scripts": {
11
11
  "build": "tsc",
12
- "watch": "tsc -w"
12
+ "watch": "tsc -w",
13
+ "prestart": "node check-build.js",
14
+ "check": "node check-build.js"
13
15
  },
14
16
  "keywords": [
15
17
  "npm",
package/set-npm-token.ps1 CHANGED
File without changes
package/set-npm-token.sh CHANGED
File without changes