@bobfrankston/importgen 0.1.26 → 0.1.27
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 +32 -28
- package/package.json +2 -2
package/index.js
CHANGED
|
@@ -8,6 +8,10 @@ import path from 'node:path';
|
|
|
8
8
|
import { execSync } from 'node:child_process';
|
|
9
9
|
import chokidar from 'chokidar';
|
|
10
10
|
import packageJson from './package.json' with { type: 'json' };
|
|
11
|
+
/** Timestamp prefix for log messages */
|
|
12
|
+
function ts() {
|
|
13
|
+
return `[${new Date().toLocaleTimeString()}]`;
|
|
14
|
+
}
|
|
11
15
|
/**
|
|
12
16
|
* Resolve dependency path based on version specifier
|
|
13
17
|
*/
|
|
@@ -91,7 +95,7 @@ function collectDependencies(packageJsonPath, visited, dependencies, htmlDir, no
|
|
|
91
95
|
let depPath = resolveDependencyPath(packageDir, depName, versionToUse);
|
|
92
96
|
if (!depPath) {
|
|
93
97
|
const warning = `Could not follow path for ${depName} (${versionToUse})`;
|
|
94
|
-
console.warn(
|
|
98
|
+
console.warn(`${ts()} [generate-importmap] Warning: ${warning}`);
|
|
95
99
|
warnings.push(warning);
|
|
96
100
|
continue;
|
|
97
101
|
}
|
|
@@ -99,7 +103,7 @@ function collectDependencies(packageJsonPath, visited, dependencies, htmlDir, no
|
|
|
99
103
|
const dependencyBackupPath = depPath + '.dependency';
|
|
100
104
|
if (fs.existsSync(dependencyBackupPath)) {
|
|
101
105
|
const warning = `Using backup path ${dependencyBackupPath}`;
|
|
102
|
-
console.warn(
|
|
106
|
+
console.warn(`${ts()} [generate-importmap] Warning: ${warning}`);
|
|
103
107
|
warnings.push(warning);
|
|
104
108
|
depPath = dependencyBackupPath;
|
|
105
109
|
}
|
|
@@ -110,7 +114,7 @@ function collectDependencies(packageJsonPath, visited, dependencies, htmlDir, no
|
|
|
110
114
|
const depPackageJsonPath = path.join(depPath, 'package.json');
|
|
111
115
|
if (!fs.existsSync(depPackageJsonPath)) {
|
|
112
116
|
const warning = `Could not follow path for ${depName} - no package.json found at ${depPath}`;
|
|
113
|
-
console.warn(
|
|
117
|
+
console.warn(`${ts()} [generate-importmap] Warning: ${warning}`);
|
|
114
118
|
warnings.push(warning);
|
|
115
119
|
continue;
|
|
116
120
|
}
|
|
@@ -135,7 +139,7 @@ function collectDependencies(packageJsonPath, visited, dependencies, htmlDir, no
|
|
|
135
139
|
}
|
|
136
140
|
}
|
|
137
141
|
catch (e) {
|
|
138
|
-
console.error(
|
|
142
|
+
console.error(`${ts()} [generate-importmap] Error processing ${packageJsonPath}:`, e.message);
|
|
139
143
|
throw e; // Propagate so callers can avoid overwriting HTML with empty map
|
|
140
144
|
}
|
|
141
145
|
}
|
|
@@ -184,14 +188,14 @@ function generateImportMap(packageJsonPath, htmlFilePath) {
|
|
|
184
188
|
}
|
|
185
189
|
// Write back to HTML file
|
|
186
190
|
fs.writeFileSync(htmlFilePath, html, 'utf-8');
|
|
187
|
-
console.log(
|
|
191
|
+
console.log(`${ts()} [generate-importmap] Updated import map`);
|
|
188
192
|
console.log(` Scanned ${visited.size} dependencies, generated ${dependencies.size} entries`);
|
|
189
193
|
if (dependencies.size > 0) {
|
|
190
194
|
console.log(' Packages:', Array.from(dependencies.keys()).join(', '));
|
|
191
195
|
}
|
|
192
196
|
}
|
|
193
197
|
catch (e) {
|
|
194
|
-
console.error(
|
|
198
|
+
console.error(`${ts()} [generate-importmap] Error:`, e.message);
|
|
195
199
|
process.exit(1);
|
|
196
200
|
}
|
|
197
201
|
return result;
|
|
@@ -203,7 +207,7 @@ function generateImportMap(packageJsonPath, htmlFilePath) {
|
|
|
203
207
|
function freezeDependencies(packageJsonPath) {
|
|
204
208
|
const nodeModulesDir = path.join(process.cwd(), 'node_modules');
|
|
205
209
|
if (!fs.existsSync(nodeModulesDir)) {
|
|
206
|
-
console.error(
|
|
210
|
+
console.error(`${ts()} [importgen] Error: node_modules not found`);
|
|
207
211
|
process.exit(1);
|
|
208
212
|
}
|
|
209
213
|
/** Check if a directory entry is a junction or symlink by comparing realpath to its path */
|
|
@@ -220,7 +224,7 @@ function freezeDependencies(packageJsonPath) {
|
|
|
220
224
|
}
|
|
221
225
|
}
|
|
222
226
|
catch (e) {
|
|
223
|
-
console.error(
|
|
227
|
+
console.error(`${ts()} [importgen] Error checking ${entryPath}: ${e.message}`);
|
|
224
228
|
}
|
|
225
229
|
return false;
|
|
226
230
|
}
|
|
@@ -229,11 +233,11 @@ function freezeDependencies(packageJsonPath) {
|
|
|
229
233
|
if (!isLinked(entryPath))
|
|
230
234
|
return;
|
|
231
235
|
const target = fs.realpathSync(entryPath);
|
|
232
|
-
console.log(
|
|
236
|
+
console.log(`${ts()} Freezing ${displayName} (${target})`);
|
|
233
237
|
fs.rmSync(entryPath, { recursive: true });
|
|
234
238
|
fs.cpSync(target, entryPath, { recursive: true });
|
|
235
239
|
}
|
|
236
|
-
console.log(
|
|
240
|
+
console.log(`${ts()} [importgen] Freezing dependencies...`);
|
|
237
241
|
let frozenCount = 0;
|
|
238
242
|
const entries = fs.readdirSync(nodeModulesDir);
|
|
239
243
|
for (const entry of entries) {
|
|
@@ -258,7 +262,7 @@ function freezeDependencies(packageJsonPath) {
|
|
|
258
262
|
frozenCount++;
|
|
259
263
|
}
|
|
260
264
|
}
|
|
261
|
-
console.log(
|
|
265
|
+
console.log(`${ts()} [importgen] Frozen ${frozenCount} linked packages`);
|
|
262
266
|
// Add preinstall guard to package.json
|
|
263
267
|
try {
|
|
264
268
|
const pkgRaw = fs.readFileSync(packageJsonPath, 'utf-8');
|
|
@@ -268,14 +272,14 @@ function freezeDependencies(packageJsonPath) {
|
|
|
268
272
|
if (pkg.scripts.preinstall) {
|
|
269
273
|
// Rename existing preinstall so unfreeze can restore it
|
|
270
274
|
pkg.scripts['frozen-preinstall'] = pkg.scripts.preinstall;
|
|
271
|
-
console.log(
|
|
275
|
+
console.log(`${ts()} [importgen] Saved existing preinstall script as "frozen-preinstall"`);
|
|
272
276
|
}
|
|
273
277
|
pkg.scripts.preinstall = 'echo FROZEN: dependencies were frozen by importgen. Use importgen --unfreeze to restore. && exit 1';
|
|
274
278
|
fs.writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
|
|
275
|
-
console.log(
|
|
279
|
+
console.log(`${ts()} [importgen] Added preinstall guard to package.json`);
|
|
276
280
|
}
|
|
277
281
|
catch (e) {
|
|
278
|
-
console.error(
|
|
282
|
+
console.error(`${ts()} [importgen] Error updating package.json: ${e.message}`);
|
|
279
283
|
}
|
|
280
284
|
}
|
|
281
285
|
/**
|
|
@@ -286,32 +290,32 @@ function unfreezeDependencies(packageJsonPath) {
|
|
|
286
290
|
const pkgRaw = fs.readFileSync(packageJsonPath, 'utf-8');
|
|
287
291
|
const pkg = JSON.parse(pkgRaw);
|
|
288
292
|
if (!pkg.scripts?.preinstall) {
|
|
289
|
-
console.log(
|
|
293
|
+
console.log(`${ts()} [importgen] No preinstall guard found — nothing to unfreeze`);
|
|
290
294
|
return;
|
|
291
295
|
}
|
|
292
296
|
if (pkg.scripts['frozen-preinstall']) {
|
|
293
297
|
pkg.scripts.preinstall = pkg.scripts['frozen-preinstall'];
|
|
294
298
|
delete pkg.scripts['frozen-preinstall'];
|
|
295
|
-
console.log(
|
|
299
|
+
console.log(`${ts()} [importgen] Restored original preinstall script`);
|
|
296
300
|
}
|
|
297
301
|
else {
|
|
298
302
|
delete pkg.scripts.preinstall;
|
|
299
|
-
console.log(
|
|
303
|
+
console.log(`${ts()} [importgen] Removed preinstall guard`);
|
|
300
304
|
}
|
|
301
305
|
fs.writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
|
|
302
306
|
}
|
|
303
307
|
catch (e) {
|
|
304
|
-
console.error(
|
|
308
|
+
console.error(`${ts()} [importgen] Error updating package.json: ${e.message}`);
|
|
305
309
|
process.exit(1);
|
|
306
310
|
}
|
|
307
311
|
// Run npm install to restore proper dependencies
|
|
308
|
-
console.log(
|
|
312
|
+
console.log(`${ts()} [importgen] Running npm install...`);
|
|
309
313
|
try {
|
|
310
314
|
execSync('npm install', { stdio: 'inherit', cwd: process.cwd() });
|
|
311
|
-
console.log(
|
|
315
|
+
console.log(`${ts()} [importgen] Unfreeze complete`);
|
|
312
316
|
}
|
|
313
317
|
catch (e) {
|
|
314
|
-
console.error(
|
|
318
|
+
console.error(`${ts()} [importgen] npm install failed: ${e.message}`);
|
|
315
319
|
process.exit(1);
|
|
316
320
|
}
|
|
317
321
|
}
|
|
@@ -325,7 +329,7 @@ const knownFlags = new Set(['-w', '--watch', '--freeze', '-freeze', '--unfreeze'
|
|
|
325
329
|
// Report unrecognized flags as errors
|
|
326
330
|
const unknownArgs = args.filter(a => a.startsWith('-') && !knownFlags.has(a));
|
|
327
331
|
if (unknownArgs.length > 0) {
|
|
328
|
-
console.error(
|
|
332
|
+
console.error(`${ts()} [importgen] Error: unrecognized argument(s): ${unknownArgs.join(', ')}`);
|
|
329
333
|
console.error(` Usage: importgen [htmlfile] [-w|--watch] [--freeze] [--unfreeze] [-v|--version]`);
|
|
330
334
|
process.exit(1);
|
|
331
335
|
}
|
|
@@ -334,7 +338,7 @@ const freezeMode = args.includes('--freeze') || args.includes('-freeze');
|
|
|
334
338
|
const unfreezeMode = args.includes('--unfreeze') || args.includes('-unfreeze');
|
|
335
339
|
const positionalArgs = args.filter(a => !a.startsWith('-'));
|
|
336
340
|
if (positionalArgs.length > 1) {
|
|
337
|
-
console.error(
|
|
341
|
+
console.error(`${ts()} [importgen] Error: too many arguments: ${positionalArgs.join(', ')}`);
|
|
338
342
|
console.error(` Usage: importgen [htmlfile] [-w|--watch] [--freeze] [--unfreeze] [-v|--version]`);
|
|
339
343
|
process.exit(1);
|
|
340
344
|
}
|
|
@@ -346,7 +350,7 @@ const htmlFileName = htmlArg || possibleHtmlFiles.find(f => fs.existsSync(path.j
|
|
|
346
350
|
const htmlFilePath = htmlFileName ? path.join(process.cwd(), htmlFileName) : null;
|
|
347
351
|
// Check if files exist
|
|
348
352
|
if (!fs.existsSync(packageJsonPath)) {
|
|
349
|
-
console.error(
|
|
353
|
+
console.error(`${ts()} [generate-importmap] Error: package.json not found in current directory`);
|
|
350
354
|
process.exit(1);
|
|
351
355
|
}
|
|
352
356
|
if (freezeMode) {
|
|
@@ -359,10 +363,10 @@ if (unfreezeMode) {
|
|
|
359
363
|
}
|
|
360
364
|
if (!htmlFilePath || !fs.existsSync(htmlFilePath)) {
|
|
361
365
|
if (htmlArg) {
|
|
362
|
-
console.error(
|
|
366
|
+
console.error(`${ts()} [generate-importmap] Error: ${htmlArg} not found in current directory`);
|
|
363
367
|
}
|
|
364
368
|
else {
|
|
365
|
-
console.error(
|
|
369
|
+
console.error(`${ts()} [generate-importmap] Error: No HTML file found. Looking for: ${possibleHtmlFiles.join(', ')}`);
|
|
366
370
|
}
|
|
367
371
|
process.exit(1);
|
|
368
372
|
}
|
|
@@ -405,7 +409,7 @@ if (watchMode) {
|
|
|
405
409
|
watcher.on('unlink', onChange);
|
|
406
410
|
watcher.on('ready', () => {
|
|
407
411
|
const total = 1 + watchedDepDirs.size;
|
|
408
|
-
console.log(
|
|
412
|
+
console.log(`${ts()} [generate-importmap] Watching ${total} directories for changes...`);
|
|
409
413
|
if (watchedDepDirs.size > 0) {
|
|
410
414
|
for (const dir of watchedDepDirs) {
|
|
411
415
|
console.log(` ${dir}`);
|
|
@@ -413,7 +417,7 @@ if (watchMode) {
|
|
|
413
417
|
}
|
|
414
418
|
});
|
|
415
419
|
watcher.on('error', (error) => {
|
|
416
|
-
console.error(
|
|
420
|
+
console.error(`${ts()} [generate-importmap] Watcher error:`, error.message);
|
|
417
421
|
});
|
|
418
422
|
}
|
|
419
423
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobfrankston/importgen",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.27",
|
|
4
4
|
"description": "Generate ES Module import maps from package.json dependencies for native browser module loading",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"chokidar": "^4.0.3"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@types/node": "^25.
|
|
37
|
+
"@types/node": "^25.3.0"
|
|
38
38
|
},
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"access": "public"
|