migrate-barrel-imports 0.0.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/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) Martin Brandhaug <martin@brandhaug.net> (https://brandhaug.net)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # migrate-barrel-imports
2
+
3
+ A CLI tool to migrate barrel imports in JavaScript/TypeScript monorepos.
4
+
5
+ Inspired by [Please Stop Using Barrel Files](https://tkdodo.eu/blog/please-stop-using-barrel-files)
6
+
7
+ ```typescript
8
+ // Before
9
+ import { foo, bar } from '@repo/package';
10
+
11
+ // After
12
+ import { foo } from '@repo/package/src/foo';
13
+ import { bar } from '@repo/package/src/bar';
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ Install the tool globally using npm:
19
+
20
+ ```bash
21
+ npm install -g migrate-barrel-imports
22
+ migrate-barrel-imports <source-path> [target-path] [options]
23
+ ```
24
+
25
+ Or use it directly with npx:
26
+
27
+ ```bash
28
+ npx migrate-barrel-imports <source-path> [target-path] [options]
29
+ ```
30
+
31
+ ### Arguments
32
+
33
+ - `source-path`: Path to the package containing barrel files (required)
34
+ - `target-path`: Path to the directory where imports should be migrated (default: current directory)
35
+
36
+ ### Options
37
+
38
+ Options can be specified either before or after the arguments:
39
+
40
+ - `--ignore-source-files <patterns>`: Comma-separated list of file patterns to ignore in source directory
41
+ - `--ignore-target-files <patterns>`: Comma-separated list of file patterns to ignore in target directory
42
+ - `--no-extension`: Exclude `js|jsx|ts|tsx|mjs|cjs` file extensions from import statements
43
+
44
+ ## Example
45
+
46
+ ```bash
47
+ # Options after arguments
48
+ migrate-barrel-imports ./packages/my-lib --ignore-source-files "**/__tests__/**,**/__mocks__/**" --ignore-target-files "**/*.test.ts"
49
+
50
+ # Options before arguments
51
+ migrate-barrel-imports --no-extension ./packages/my-lib .
52
+
53
+ # Mix of options before and after arguments
54
+ migrate-barrel-imports --no-extension ./packages/my-lib --ignore-target-files "**/*.test.ts"
55
+ ```
56
+
57
+ ## Contributing
58
+
59
+ Contributions are welcome! Feel free to open an issue or submit a pull request on GitHub.
60
+
61
+ ## License
62
+
63
+ This project is licensed under the MIT License.
package/dist/index.js ADDED
@@ -0,0 +1,466 @@
1
+ #!/usr/bin/env node
2
+ import {Command as $cUHbR$Command} from "commander";
3
+ import {readFileSync as $cUHbR$readFileSync, writeFileSync as $cUHbR$writeFileSync} from "node:fs";
4
+ import $cUHbR$nodepath, {join as $cUHbR$join} from "node:path";
5
+ import $cUHbR$babelgenerator from "@babel/generator";
6
+ import {parse as $cUHbR$parse} from "@babel/parser";
7
+ import $cUHbR$babeltraverse from "@babel/traverse";
8
+ import {isVariableDeclaration as $cUHbR$isVariableDeclaration, isIdentifier as $cUHbR$isIdentifier, isExportSpecifier as $cUHbR$isExportSpecifier, isFunctionDeclaration as $cUHbR$isFunctionDeclaration, isImportSpecifier as $cUHbR$isImportSpecifier, importDeclaration as $cUHbR$importDeclaration, importSpecifier as $cUHbR$importSpecifier, stringLiteral as $cUHbR$stringLiteral} from "@babel/types";
9
+ import $cUHbR$fastglob from "fast-glob";
10
+ import $cUHbR$micromatch from "micromatch";
11
+
12
+
13
+ /**
14
+ * @fileoverview Tool for migrating TypeScript projects from barrel file exports to direct file imports
15
+ *
16
+ * This tool helps migrate TypeScript projects that use barrel files (index.ts files that re-export)
17
+ * to use direct imports from source files instead. This improves:
18
+ * - Tree-shaking efficiency
19
+ * - Build performance
20
+ * - Code maintainability
21
+ * - TypeScript compilation speed
22
+ *
23
+ * The migration process:
24
+ * 1. Scans source package for all exports
25
+ * 2. Finds all files importing from the package
26
+ * 3. Updates imports to point directly to source files
27
+ * 4. Preserves original import names and types
28
+ */
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+ /**
37
+ * Reads and parses the package.json file for a given package path
38
+ *
39
+ * @param {string} packagePath - The path to the package directory
40
+ * @returns {Promise<PackageJson>} The parsed package.json contents
41
+ * @throws {Error} If package.json cannot be read or parsed
42
+ */ async function $1d95f64f52ade133$var$getPackageInfo(packagePath) {
43
+ const packageJsonPath = (0, $cUHbR$join)(packagePath, 'package.json');
44
+ const content = (0, $cUHbR$readFileSync)(packageJsonPath, 'utf-8');
45
+ return JSON.parse(content);
46
+ }
47
+ /**
48
+ * Recursively finds all exports in a package by scanning all TypeScript files
49
+ *
50
+ * This function:
51
+ * 1. Scans all .ts and .tsx files in the package
52
+ * 2. Identifies both named exports and default exports
53
+ * 3. Skips re-exports to avoid circular dependencies
54
+ * 4. Filters out ignored files based on patterns
55
+ *
56
+ * @param {FindExportsParams} params - Parameters for finding exports
57
+ * @returns {Promise<ExportInfo[]>} Array of export information, including source file and exported names
58
+ */ async function $1d95f64f52ade133$var$findExports({ packagePath: packagePath, ignoreSourceFiles: ignoreSourceFiles = [], stats: stats }) {
59
+ const exports = [];
60
+ console.log(`Scanning for TypeScript files in: ${packagePath}`);
61
+ const allFiles = await (0, $cUHbR$fastglob)('**/*.{ts,tsx}', {
62
+ cwd: packagePath,
63
+ ignore: [
64
+ '**/node_modules/**',
65
+ '**/dist/**',
66
+ '**/build/**'
67
+ ]
68
+ });
69
+ console.log(`Found ${allFiles.length} TypeScript files`);
70
+ for (const file of allFiles){
71
+ // Mark files that match ignore patterns but still process them
72
+ const isIgnored = ignoreSourceFiles.some((pattern)=>(0, $cUHbR$micromatch).isMatch(file, pattern));
73
+ if (isIgnored) {
74
+ console.log(`File matches ignore pattern but will be preserved: ${file}`);
75
+ if (stats) stats.sourceFilesSkipped++;
76
+ }
77
+ const fullPath = (0, $cUHbR$join)(packagePath, file);
78
+ console.log(`\nProcessing file: ${file}`);
79
+ const content = (0, $cUHbR$readFileSync)(fullPath, 'utf-8');
80
+ try {
81
+ const ast = (0, $cUHbR$parse)(content, {
82
+ sourceType: 'module',
83
+ plugins: [
84
+ 'typescript',
85
+ 'jsx',
86
+ 'decorators-legacy',
87
+ 'classProperties',
88
+ 'classPrivateProperties',
89
+ 'classPrivateMethods',
90
+ 'exportDefaultFrom',
91
+ 'exportNamespaceFrom',
92
+ 'functionBind',
93
+ 'functionSent',
94
+ 'dynamicImport',
95
+ 'nullishCoalescingOperator',
96
+ 'optionalChaining',
97
+ 'objectRestSpread',
98
+ 'asyncGenerators',
99
+ 'doExpressions',
100
+ 'importMeta',
101
+ 'logicalAssignment',
102
+ 'moduleBlocks',
103
+ 'moduleStringNames',
104
+ 'numericSeparator',
105
+ 'partialApplication',
106
+ 'privateIn',
107
+ 'throwExpressions',
108
+ 'topLevelAwait'
109
+ ]
110
+ });
111
+ (0, $cUHbR$babeltraverse)(ast, {
112
+ ExportNamedDeclaration (path) {
113
+ console.log(`Found named export in ${file}`);
114
+ // Skip exports from other files (we only want direct exports)
115
+ if (path.node.source) {
116
+ console.log(`Skipping re-export from ${path.node.source.value}`);
117
+ return;
118
+ }
119
+ // Handle variable declarations with exports
120
+ if (path.node.declaration) {
121
+ if ($cUHbR$isVariableDeclaration(path.node.declaration)) {
122
+ const declarations = path.node.declaration.declarations;
123
+ const namedExports = declarations.map((d)=>{
124
+ if ($cUHbR$isIdentifier(d.id)) return d.id.name;
125
+ return null;
126
+ }).filter((name)=>name !== null);
127
+ if (namedExports.length > 0) {
128
+ console.log(`Named exports found: ${namedExports.join(', ')}`);
129
+ exports.push({
130
+ source: file,
131
+ exports: namedExports,
132
+ isIgnored: isIgnored
133
+ });
134
+ }
135
+ }
136
+ return;
137
+ }
138
+ // Handle export specifiers
139
+ const namedExports = path.node.specifiers.map((s)=>{
140
+ if ($cUHbR$isExportSpecifier(s)) {
141
+ const exported = s.exported;
142
+ return $cUHbR$isIdentifier(exported) ? exported.name : exported.value;
143
+ }
144
+ return null;
145
+ }).filter((name)=>name !== null);
146
+ if (namedExports.length > 0) {
147
+ console.log(`Named exports found: ${namedExports.join(', ')}`);
148
+ exports.push({
149
+ source: file,
150
+ exports: namedExports,
151
+ isIgnored: isIgnored
152
+ });
153
+ }
154
+ },
155
+ ExportDefaultDeclaration (path) {
156
+ console.log(`Found default export in ${file}`);
157
+ const exported = path.node.declaration;
158
+ if ($cUHbR$isIdentifier(exported)) {
159
+ console.log(`Default export name: ${exported.name}`);
160
+ exports.push({
161
+ source: file,
162
+ exports: [
163
+ exported.name
164
+ ],
165
+ isIgnored: isIgnored
166
+ });
167
+ } else if ($cUHbR$isFunctionDeclaration(exported) && exported.id) {
168
+ console.log(`Default export name: ${exported.id.name}`);
169
+ exports.push({
170
+ source: file,
171
+ exports: [
172
+ exported.id.name
173
+ ],
174
+ isIgnored: isIgnored
175
+ });
176
+ } else console.log('Default export is not an identifier or named function');
177
+ }
178
+ });
179
+ } catch (error) {
180
+ console.error(`Error parsing ${file}:`, error);
181
+ }
182
+ }
183
+ console.log(`\nTotal exports found: ${exports.length}`);
184
+ return exports;
185
+ }
186
+ /**
187
+ * Finds all files in the monorepo that import from a specific package
188
+ *
189
+ * This function:
190
+ * 1. Uses fast-glob to find all TypeScript files
191
+ * 2. Parses each file's AST to find imports
192
+ * 3. Handles both direct package imports and subpath imports
193
+ * 4. Excludes node_modules, dist, and build directories
194
+ *
195
+ * @param {FindImportsParams} params - Parameters for finding imports
196
+ * @returns {Promise<string[]>} Array of file paths that import from the package
197
+ */ async function $1d95f64f52ade133$var$findImports({ packageName: packageName, monorepoRoot: monorepoRoot }) {
198
+ try {
199
+ const allFiles = new Set();
200
+ // Find all TypeScript files in the monorepo
201
+ const files = await (0, $cUHbR$fastglob)([
202
+ '**/*.{ts,tsx}'
203
+ ], {
204
+ cwd: monorepoRoot,
205
+ absolute: true,
206
+ ignore: [
207
+ '**/node_modules/**',
208
+ '**/dist/**',
209
+ '**/build/**'
210
+ ],
211
+ followSymbolicLinks: false
212
+ });
213
+ console.log(`Found ${files.length} TypeScript files to scan`);
214
+ // Scan each file for imports
215
+ for (const file of files)try {
216
+ const content = (0, $cUHbR$readFileSync)(file, 'utf-8');
217
+ const ast = (0, $cUHbR$parse)(content, {
218
+ sourceType: 'module',
219
+ plugins: [
220
+ 'typescript',
221
+ 'jsx'
222
+ ]
223
+ });
224
+ (0, $cUHbR$babeltraverse)(ast, {
225
+ ImportDeclaration (path) {
226
+ const source = path.node.source.value;
227
+ // Check for exact package import or subpath import
228
+ if (source === packageName || source.startsWith(`${packageName}/`)) allFiles.add(file);
229
+ }
230
+ });
231
+ } catch (error) {
232
+ console.error(`Error processing file ${file}:`, error);
233
+ }
234
+ const uniqueFiles = Array.from(allFiles);
235
+ if (uniqueFiles.length > 0) {
236
+ console.log(`Found total of ${uniqueFiles.length} files with imports from ${packageName}`);
237
+ console.log('Files found:');
238
+ for (const file of uniqueFiles)console.log(` ${file}`);
239
+ } else console.log(`No files found importing from ${packageName}`);
240
+ return uniqueFiles;
241
+ } catch (error) {
242
+ console.error('Error finding imports:', error);
243
+ return [];
244
+ }
245
+ }
246
+ /**
247
+ * Updates imports in a file to point directly to source files instead of using barrel files
248
+ *
249
+ * This function:
250
+ * 1. Parses the file's AST to find imports from the package
251
+ * 2. For each import, finds the source file containing the export
252
+ * 3. Updates the import to point directly to the source file
253
+ * 4. Preserves original import names and types
254
+ * 5. Only modifies the file if changes are needed
255
+ *
256
+ * @param {UpdateImportsParams} params - Parameters for updating imports
257
+ * @returns {Promise<void>}
258
+ */ async function $1d95f64f52ade133$var$updateImports({ filePath: filePath, packageName: packageName, exports: exports, includeExtension: includeExtension = true }) {
259
+ console.log(`\nProcessing file: ${filePath}`);
260
+ const content = (0, $cUHbR$readFileSync)(filePath, 'utf-8');
261
+ try {
262
+ const ast = (0, $cUHbR$parse)(content, {
263
+ sourceType: 'module',
264
+ plugins: [
265
+ 'typescript',
266
+ 'jsx',
267
+ 'decorators-legacy',
268
+ 'classProperties',
269
+ 'classPrivateProperties',
270
+ 'classPrivateMethods',
271
+ 'exportDefaultFrom',
272
+ 'exportNamespaceFrom',
273
+ 'functionBind',
274
+ 'functionSent',
275
+ 'dynamicImport',
276
+ 'nullishCoalescingOperator',
277
+ 'optionalChaining',
278
+ 'objectRestSpread',
279
+ 'asyncGenerators',
280
+ 'doExpressions',
281
+ 'importMeta',
282
+ 'logicalAssignment',
283
+ 'moduleBlocks',
284
+ 'moduleStringNames',
285
+ 'numericSeparator',
286
+ 'partialApplication',
287
+ 'privateIn',
288
+ 'throwExpressions',
289
+ 'topLevelAwait'
290
+ ]
291
+ });
292
+ let modified = false;
293
+ let importCount = 0;
294
+ (0, $cUHbR$babeltraverse)(ast, {
295
+ ImportDeclaration (path) {
296
+ if (path.node.source.value === packageName) {
297
+ importCount++;
298
+ console.log(`Found import from ${packageName}`);
299
+ const specifiers = path.node.specifiers;
300
+ const newImports = [];
301
+ for (const specifier of specifiers)if ($cUHbR$isImportSpecifier(specifier)) {
302
+ const imported = specifier.imported;
303
+ const importName = $cUHbR$isIdentifier(imported) ? imported.name : imported.value;
304
+ const exportInfo = exports.find((e)=>e.exports.includes(importName));
305
+ if (exportInfo) {
306
+ console.log(` Found export ${importName} in ${exportInfo.source}`);
307
+ // Skip modifying imports from ignored files
308
+ if (exportInfo.isIgnored) {
309
+ console.log(` Keeping original import for ignored file: ${exportInfo.source}`);
310
+ continue;
311
+ }
312
+ const importPath = includeExtension ? `${packageName}/${exportInfo.source}` : `${packageName}/${exportInfo.source.replace(/\.(js|jsx|ts|tsx|mjs|cjs)$/, '')}`;
313
+ newImports.push($cUHbR$importDeclaration([
314
+ $cUHbR$importSpecifier(specifier.local, specifier.imported)
315
+ ], $cUHbR$stringLiteral(importPath)));
316
+ modified = true;
317
+ } else console.log(` Warning: Could not find export ${importName}`);
318
+ }
319
+ if (newImports.length > 0) {
320
+ // If there are any remaining specifiers that weren't moved to direct imports,
321
+ // create a new import declaration for them
322
+ const remainingSpecifiers = specifiers.filter((s)=>{
323
+ if (!$cUHbR$isImportSpecifier(s)) return true;
324
+ const importName = $cUHbR$isIdentifier(s.imported) ? s.imported.name : s.imported.value;
325
+ const exportInfo = exports.find((e)=>e.exports.includes(importName));
326
+ return !exportInfo || exportInfo.isIgnored;
327
+ });
328
+ if (remainingSpecifiers.length > 0) newImports.unshift($cUHbR$importDeclaration(remainingSpecifiers, $cUHbR$stringLiteral(packageName)));
329
+ path.replaceWithMultiple(newImports);
330
+ console.log(' Replaced import with direct imports from source files');
331
+ }
332
+ }
333
+ }
334
+ });
335
+ if (modified) {
336
+ console.log(`Writing changes to ${filePath}`);
337
+ const output = (0, $cUHbR$babelgenerator)(ast, {
338
+ retainLines: false,
339
+ retainFunctionParens: true
340
+ }, content);
341
+ (0, $cUHbR$writeFileSync)(filePath, output.code);
342
+ } else if (importCount > 0) console.log(`No changes needed for ${importCount} imports`);
343
+ else console.log('No imports found to update');
344
+ } catch (error) {
345
+ console.error(`Error processing ${filePath}:`, error);
346
+ }
347
+ }
348
+ async function $1d95f64f52ade133$export$eb4d0c836e660010(options) {
349
+ const { sourcePath: sourcePath, targetPath: targetPath, ignoreSourceFiles: ignoreSourceFiles, ignoreTargetFiles: ignoreTargetFiles } = options;
350
+ // Track migration statistics
351
+ const stats = {
352
+ totalFiles: 0,
353
+ filesProcessed: 0,
354
+ filesSkipped: 0,
355
+ importsUpdated: 0,
356
+ filesWithNoUpdates: 0,
357
+ errors: 0,
358
+ totalExports: 0,
359
+ sourceFilesScanned: 0,
360
+ sourceFilesWithExports: 0,
361
+ sourceFilesSkipped: 0,
362
+ targetFilesFound: []
363
+ };
364
+ const packageInfo = await $1d95f64f52ade133$var$getPackageInfo(sourcePath);
365
+ const exports = await $1d95f64f52ade133$var$findExports({
366
+ packagePath: sourcePath,
367
+ ignoreSourceFiles: ignoreSourceFiles,
368
+ stats: stats
369
+ });
370
+ // Calculate total number of unique exports and source files
371
+ stats.totalExports = exports.reduce((total, exp)=>total + exp.exports.length, 0);
372
+ stats.sourceFilesWithExports = new Set(exports.map((exp)=>exp.source)).size;
373
+ stats.sourceFilesScanned = (await (0, $cUHbR$fastglob)('**/*.{ts,tsx}', {
374
+ cwd: sourcePath,
375
+ ignore: [
376
+ '**/node_modules/**',
377
+ '**/dist/**',
378
+ '**/build/**'
379
+ ]
380
+ })).length;
381
+ const files = await $1d95f64f52ade133$var$findImports({
382
+ packageName: packageInfo.name,
383
+ monorepoRoot: targetPath
384
+ });
385
+ stats.totalFiles = files.length;
386
+ stats.targetFilesFound = files;
387
+ for (const file of files){
388
+ const relativeFile = (0, $cUHbR$nodepath).relative(targetPath, file);
389
+ if (ignoreTargetFiles.some((pattern)=>(0, $cUHbR$micromatch).isMatch(relativeFile, pattern))) {
390
+ console.log(`Skipping ignored file: ${file} (matches pattern in ${ignoreTargetFiles.join(', ')})`);
391
+ stats.filesSkipped++;
392
+ continue;
393
+ }
394
+ try {
395
+ const originalContent = (0, $cUHbR$readFileSync)(file, 'utf-8');
396
+ await $1d95f64f52ade133$var$updateImports({
397
+ filePath: file,
398
+ packageName: packageInfo.name,
399
+ exports: exports,
400
+ includeExtension: options.includeExtension
401
+ });
402
+ const updatedContent = (0, $cUHbR$readFileSync)(file, 'utf-8');
403
+ if (originalContent !== updatedContent) stats.importsUpdated++;
404
+ else stats.filesWithNoUpdates++;
405
+ stats.filesProcessed++;
406
+ } catch (error) {
407
+ stats.errors++;
408
+ console.error(`Error processing ${file}:`, error);
409
+ }
410
+ }
411
+ // Print migration summary
412
+ console.log('\nMigration Summary');
413
+ console.log(`Source files found: ${stats.sourceFilesScanned}`);
414
+ console.log(`Source files with exports: ${stats.sourceFilesWithExports}`);
415
+ console.log(`Source files skipped: ${stats.sourceFilesSkipped}`);
416
+ console.log(`Exports found: ${stats.totalExports}`);
417
+ console.log(`Target files found: ${stats.totalFiles}`);
418
+ console.log(`Target files processed: ${stats.filesProcessed}`);
419
+ console.log(`Target files with imports updated: ${stats.importsUpdated}`);
420
+ console.log(`Target files with no changes needed: ${stats.filesWithNoUpdates}`);
421
+ console.log(`Target files skipped: ${stats.filesSkipped}`);
422
+ if (stats.errors > 0) console.log(`\nWarning: ${stats.errors} errors encountered during processing`);
423
+ }
424
+
425
+
426
+ /**
427
+ * Configuration options for the migration process
428
+ * @property {string} sourcePath - Path to the package being migrated
429
+ * @property {string} targetPath - Path to the monorepo root to search for imports
430
+ * @property {string[]} ignoreSourceFiles - Patterns to ignore when scanning source files
431
+ * @property {string[]} ignoreTargetFiles - Patterns to ignore when scanning target files
432
+ * @property {boolean} [includeExtension] - Whether to include file extensions in imports
433
+ */ const $bf36973fbb2420ae$export$ba43bf67f3d48107 = {
434
+ targetPath: '.',
435
+ ignoreSourceFiles: [],
436
+ ignoreTargetFiles: [],
437
+ includeExtension: false
438
+ };
439
+
440
+
441
+ async function $f2a4372f35794f3d$export$f22da7240b7add18() {
442
+ const program = new (0, $cUHbR$Command)();
443
+ program.name('migrate-barrel-imports').description('CLI tool to migrate barrel files imports to direct imports').argument('<source-path>', 'Path to the package containing barrel files').argument('[target-path]', 'Path to the directory where imports should be migrated (default: current directory)').option('--ignore-source-files <patterns>', 'Comma-separated list of file patterns to ignore in source directory').option('--ignore-target-files <patterns>', 'Comma-separated list of file patterns to ignore in target directory').option('--no-extension', 'Exclude js|jsx|ts|tsx|mjs|cjs file extensions from import statements').allowUnknownOption(false).parse(process.argv);
444
+ const args = program.args;
445
+ if (!args[0]) {
446
+ console.error('Error: source-path is required');
447
+ process.exit(1);
448
+ }
449
+ const sourcePath = args[0];
450
+ const targetPath = args[1] || (0, $bf36973fbb2420ae$export$ba43bf67f3d48107).targetPath;
451
+ const options = program.opts();
452
+ await (0, $1d95f64f52ade133$export$eb4d0c836e660010)({
453
+ sourcePath: sourcePath,
454
+ targetPath: targetPath,
455
+ ignoreSourceFiles: options.ignoreSourceFiles ? options.ignoreSourceFiles.split(',') : (0, $bf36973fbb2420ae$export$ba43bf67f3d48107).ignoreSourceFiles,
456
+ ignoreTargetFiles: options.ignoreTargetFiles ? options.ignoreTargetFiles.split(',') : (0, $bf36973fbb2420ae$export$ba43bf67f3d48107).ignoreTargetFiles,
457
+ includeExtension: options.extension !== false ? true : (0, $bf36973fbb2420ae$export$ba43bf67f3d48107).includeExtension
458
+ });
459
+ }
460
+
461
+
462
+ (async ()=>{
463
+ await (0, $f2a4372f35794f3d$export$f22da7240b7add18)();
464
+ })();
465
+
466
+
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "migrate-barrel-imports",
3
+ "version": "0.0.0",
4
+ "description": "A CLI tool to migrate barrel imports in JavaScript/TypeScript monorepos",
5
+ "files": ["dist/"],
6
+ "main": "./dist/index.js",
7
+ "keywords": [
8
+ "typescript",
9
+ "javascript",
10
+ "monorepo",
11
+ "cli",
12
+ "tool",
13
+ "migrate",
14
+ "barrel",
15
+ "import",
16
+ "imports"
17
+ ],
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/brandhaug/migrate-barrel-imports.git"
21
+ },
22
+ "bugs": {
23
+ "url": "https://github.com/brandhaug/migrate-barrel-imports/issues"
24
+ },
25
+ "homepage": "https://github.com/brandhaug/migrate-barrel-imports#readme",
26
+ "type": "module",
27
+ "bin": {
28
+ "migrate-barrel-imports": "dist/index.js"
29
+ },
30
+ "scripts": {
31
+ "build": "parcel build src/index.ts --no-source-maps",
32
+ "start": "node dist/index.js",
33
+ "lint": "biome lint",
34
+ "check-write": "biome check --write",
35
+ "typecheck": "tsc",
36
+ "prepare": "husky",
37
+ "test": "vitest",
38
+ "validate": "npm run lint && npm run typecheck && npm run test"
39
+ },
40
+ "dependencies": {
41
+ "@babel/generator": "7.26.10",
42
+ "@babel/parser": "7.26.10",
43
+ "@babel/traverse": "7.26.10",
44
+ "@babel/types": "7.26.10",
45
+ "commander": "13.1.0",
46
+ "fast-glob": "3.3.3",
47
+ "micromatch": "4.0.8",
48
+ "ts-morph": "25.0.1"
49
+ },
50
+ "devDependencies": {
51
+ "@biomejs/biome": "1.9.4",
52
+ "@commitlint/cli": "19.8.0",
53
+ "@commitlint/config-conventional": "19.8.0",
54
+ "@semantic-release/changelog": "6.0.3",
55
+ "@semantic-release/git": "10.0.1",
56
+ "@types/babel__generator": "7.6.8",
57
+ "@types/babel__traverse": "7.20.6",
58
+ "@types/micromatch": "4.0.9",
59
+ "execa": "9.5.2",
60
+ "husky": "9.1.7",
61
+ "lint-staged": "15.5.0",
62
+ "parcel": "2.14.1",
63
+ "semantic-release": "24.2.3",
64
+ "tsc-files": "1.1.4",
65
+ "tsx": "4.19.3",
66
+ "typescript": "5.8.2",
67
+ "vitest": "3.0.9"
68
+ },
69
+ "author": "Martin Brandhaug",
70
+ "license": "MIT",
71
+ "lint-staged": {
72
+ "*.{ts,json}": ["biome check --write"],
73
+ "*.ts": ["tsc-files"]
74
+ },
75
+ "engines": {
76
+ "node": ">=20"
77
+ }
78
+ }