@bobfrankston/importgen 0.1.27 → 0.1.28
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 +3 -133
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import fs from 'node:fs';
|
|
7
7
|
import path from 'node:path';
|
|
8
|
-
import { execSync } from 'node:child_process';
|
|
9
8
|
import chokidar from 'chokidar';
|
|
10
9
|
import packageJson from './package.json' with { type: 'json' };
|
|
11
10
|
/** Timestamp prefix for log messages */
|
|
@@ -200,146 +199,25 @@ function generateImportMap(packageJsonPath, htmlFilePath) {
|
|
|
200
199
|
}
|
|
201
200
|
return result;
|
|
202
201
|
}
|
|
203
|
-
/**
|
|
204
|
-
* Freeze dependencies: replace junctions/symlinks in node_modules with real copies.
|
|
205
|
-
* Also adds a preinstall guard to package.json to prevent npm install from undoing the freeze.
|
|
206
|
-
*/
|
|
207
|
-
function freezeDependencies(packageJsonPath) {
|
|
208
|
-
const nodeModulesDir = path.join(process.cwd(), 'node_modules');
|
|
209
|
-
if (!fs.existsSync(nodeModulesDir)) {
|
|
210
|
-
console.error(`${ts()} [importgen] Error: node_modules not found`);
|
|
211
|
-
process.exit(1);
|
|
212
|
-
}
|
|
213
|
-
/** Check if a directory entry is a junction or symlink by comparing realpath to its path */
|
|
214
|
-
function isLinked(entryPath) {
|
|
215
|
-
try {
|
|
216
|
-
const stat = fs.lstatSync(entryPath);
|
|
217
|
-
// Symlink check (works on Linux/Mac symlinks)
|
|
218
|
-
if (stat.isSymbolicLink())
|
|
219
|
-
return true;
|
|
220
|
-
// Junction check (Windows): realpath differs from the entry path
|
|
221
|
-
if (stat.isDirectory()) {
|
|
222
|
-
const real = fs.realpathSync(entryPath);
|
|
223
|
-
return path.resolve(real) !== path.resolve(entryPath);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
catch (e) {
|
|
227
|
-
console.error(`${ts()} [importgen] Error checking ${entryPath}: ${e.message}`);
|
|
228
|
-
}
|
|
229
|
-
return false;
|
|
230
|
-
}
|
|
231
|
-
/** Freeze a single entry if it's a junction/symlink */
|
|
232
|
-
function freezeEntry(entryPath, displayName) {
|
|
233
|
-
if (!isLinked(entryPath))
|
|
234
|
-
return;
|
|
235
|
-
const target = fs.realpathSync(entryPath);
|
|
236
|
-
console.log(`${ts()} Freezing ${displayName} (${target})`);
|
|
237
|
-
fs.rmSync(entryPath, { recursive: true });
|
|
238
|
-
fs.cpSync(target, entryPath, { recursive: true });
|
|
239
|
-
}
|
|
240
|
-
console.log(`${ts()} [importgen] Freezing dependencies...`);
|
|
241
|
-
let frozenCount = 0;
|
|
242
|
-
const entries = fs.readdirSync(nodeModulesDir);
|
|
243
|
-
for (const entry of entries) {
|
|
244
|
-
const entryPath = path.join(nodeModulesDir, entry);
|
|
245
|
-
if (entry.startsWith('@')) {
|
|
246
|
-
// Scoped package — walk one level deeper
|
|
247
|
-
if (!fs.statSync(entryPath).isDirectory())
|
|
248
|
-
continue;
|
|
249
|
-
const scopedEntries = fs.readdirSync(entryPath);
|
|
250
|
-
for (const scoped of scopedEntries) {
|
|
251
|
-
const scopedPath = path.join(entryPath, scoped);
|
|
252
|
-
const before = isLinked(scopedPath);
|
|
253
|
-
freezeEntry(scopedPath, `${entry}/${scoped}`);
|
|
254
|
-
if (before)
|
|
255
|
-
frozenCount++;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
else {
|
|
259
|
-
const before = isLinked(entryPath);
|
|
260
|
-
freezeEntry(entryPath, entry);
|
|
261
|
-
if (before)
|
|
262
|
-
frozenCount++;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
console.log(`${ts()} [importgen] Frozen ${frozenCount} linked packages`);
|
|
266
|
-
// Add preinstall guard to package.json
|
|
267
|
-
try {
|
|
268
|
-
const pkgRaw = fs.readFileSync(packageJsonPath, 'utf-8');
|
|
269
|
-
const pkg = JSON.parse(pkgRaw);
|
|
270
|
-
if (!pkg.scripts)
|
|
271
|
-
pkg.scripts = {};
|
|
272
|
-
if (pkg.scripts.preinstall) {
|
|
273
|
-
// Rename existing preinstall so unfreeze can restore it
|
|
274
|
-
pkg.scripts['frozen-preinstall'] = pkg.scripts.preinstall;
|
|
275
|
-
console.log(`${ts()} [importgen] Saved existing preinstall script as "frozen-preinstall"`);
|
|
276
|
-
}
|
|
277
|
-
pkg.scripts.preinstall = 'echo FROZEN: dependencies were frozen by importgen. Use importgen --unfreeze to restore. && exit 1';
|
|
278
|
-
fs.writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
|
|
279
|
-
console.log(`${ts()} [importgen] Added preinstall guard to package.json`);
|
|
280
|
-
}
|
|
281
|
-
catch (e) {
|
|
282
|
-
console.error(`${ts()} [importgen] Error updating package.json: ${e.message}`);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* Unfreeze: remove preinstall guard, restore original preinstall if saved, then run npm install.
|
|
287
|
-
*/
|
|
288
|
-
function unfreezeDependencies(packageJsonPath) {
|
|
289
|
-
try {
|
|
290
|
-
const pkgRaw = fs.readFileSync(packageJsonPath, 'utf-8');
|
|
291
|
-
const pkg = JSON.parse(pkgRaw);
|
|
292
|
-
if (!pkg.scripts?.preinstall) {
|
|
293
|
-
console.log(`${ts()} [importgen] No preinstall guard found — nothing to unfreeze`);
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
if (pkg.scripts['frozen-preinstall']) {
|
|
297
|
-
pkg.scripts.preinstall = pkg.scripts['frozen-preinstall'];
|
|
298
|
-
delete pkg.scripts['frozen-preinstall'];
|
|
299
|
-
console.log(`${ts()} [importgen] Restored original preinstall script`);
|
|
300
|
-
}
|
|
301
|
-
else {
|
|
302
|
-
delete pkg.scripts.preinstall;
|
|
303
|
-
console.log(`${ts()} [importgen] Removed preinstall guard`);
|
|
304
|
-
}
|
|
305
|
-
fs.writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
|
|
306
|
-
}
|
|
307
|
-
catch (e) {
|
|
308
|
-
console.error(`${ts()} [importgen] Error updating package.json: ${e.message}`);
|
|
309
|
-
process.exit(1);
|
|
310
|
-
}
|
|
311
|
-
// Run npm install to restore proper dependencies
|
|
312
|
-
console.log(`${ts()} [importgen] Running npm install...`);
|
|
313
|
-
try {
|
|
314
|
-
execSync('npm install', { stdio: 'inherit', cwd: process.cwd() });
|
|
315
|
-
console.log(`${ts()} [importgen] Unfreeze complete`);
|
|
316
|
-
}
|
|
317
|
-
catch (e) {
|
|
318
|
-
console.error(`${ts()} [importgen] npm install failed: ${e.message}`);
|
|
319
|
-
process.exit(1);
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
202
|
// Parse CLI arguments
|
|
323
203
|
const args = process.argv.slice(2);
|
|
324
204
|
if (args.includes('-v') || args.includes('--version')) {
|
|
325
205
|
console.log(`importgen ${packageJson.version}`);
|
|
326
206
|
process.exit(0);
|
|
327
207
|
}
|
|
328
|
-
const knownFlags = new Set(['-w', '--watch', '
|
|
208
|
+
const knownFlags = new Set(['-w', '--watch', '-v', '--version']);
|
|
329
209
|
// Report unrecognized flags as errors
|
|
330
210
|
const unknownArgs = args.filter(a => a.startsWith('-') && !knownFlags.has(a));
|
|
331
211
|
if (unknownArgs.length > 0) {
|
|
332
212
|
console.error(`${ts()} [importgen] Error: unrecognized argument(s): ${unknownArgs.join(', ')}`);
|
|
333
|
-
console.error(` Usage: importgen [htmlfile] [-w|--watch] [
|
|
213
|
+
console.error(` Usage: importgen [htmlfile] [-w|--watch] [-v|--version]`);
|
|
334
214
|
process.exit(1);
|
|
335
215
|
}
|
|
336
216
|
const watchMode = args.includes('-w') || args.includes('--watch');
|
|
337
|
-
const freezeMode = args.includes('--freeze') || args.includes('-freeze');
|
|
338
|
-
const unfreezeMode = args.includes('--unfreeze') || args.includes('-unfreeze');
|
|
339
217
|
const positionalArgs = args.filter(a => !a.startsWith('-'));
|
|
340
218
|
if (positionalArgs.length > 1) {
|
|
341
219
|
console.error(`${ts()} [importgen] Error: too many arguments: ${positionalArgs.join(', ')}`);
|
|
342
|
-
console.error(` Usage: importgen [htmlfile] [-w|--watch] [
|
|
220
|
+
console.error(` Usage: importgen [htmlfile] [-w|--watch] [-v|--version]`);
|
|
343
221
|
process.exit(1);
|
|
344
222
|
}
|
|
345
223
|
const htmlArg = positionalArgs[0];
|
|
@@ -353,14 +231,6 @@ if (!fs.existsSync(packageJsonPath)) {
|
|
|
353
231
|
console.error(`${ts()} [generate-importmap] Error: package.json not found in current directory`);
|
|
354
232
|
process.exit(1);
|
|
355
233
|
}
|
|
356
|
-
if (freezeMode) {
|
|
357
|
-
freezeDependencies(packageJsonPath);
|
|
358
|
-
process.exit(0);
|
|
359
|
-
}
|
|
360
|
-
if (unfreezeMode) {
|
|
361
|
-
unfreezeDependencies(packageJsonPath);
|
|
362
|
-
process.exit(0);
|
|
363
|
-
}
|
|
364
234
|
if (!htmlFilePath || !fs.existsSync(htmlFilePath)) {
|
|
365
235
|
if (htmlArg) {
|
|
366
236
|
console.error(`${ts()} [generate-importmap] Error: ${htmlArg} not found in current directory`);
|