importy 0.0.11 → 0.1.2
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 +59 -2
- package/dist/index.js +38 -30
- package/package.json +31 -3
package/README.md
CHANGED
|
@@ -1,10 +1,28 @@
|
|
|
1
1
|
# Importy
|
|
2
|
+
<img align="right" src="public/importy.png" alt="Importy CLI Tool" height="120" />
|
|
2
3
|
|
|
3
4
|
A powerful CLI tool for analyzing JavaScript/TypeScript imports from libraries.
|
|
4
5
|
|
|
5
6
|
[](https://www.npmjs.com/package/importy)
|
|
6
7
|
[](https://opensource.org/licenses/MIT)
|
|
7
8
|
|
|
9
|
+
> **Version 0.1.1** - First stable release! 🎉 See [CHANGELOG.md](CHANGELOG.md) for details.
|
|
10
|
+
|
|
11
|
+
## 📖 Documentation
|
|
12
|
+
|
|
13
|
+
**[📚 Complete Documentation →](https://tvshevchuk.github.io/Importy/)**
|
|
14
|
+
|
|
15
|
+
- [🚀 Getting Started Guide](https://tvshevchuk.github.io/Importy/guide/getting-started)
|
|
16
|
+
- [📋 API Reference](https://tvshevchuk.github.io/Importy/api/cli)
|
|
17
|
+
- [💡 Examples & Use Cases](https://tvshevchuk.github.io/Importy/examples/basic-usage)
|
|
18
|
+
- [🤝 Contributing Guide](https://tvshevchuk.github.io/Importy/contributing)
|
|
19
|
+
|
|
20
|
+
## 🎬 Live Demo
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+
*See Importy in action analyzing a React project! [View full demo →](DEMO.md)*
|
|
25
|
+
|
|
8
26
|
## Overview
|
|
9
27
|
|
|
10
28
|
Importy scans your codebase to identify and analyze imports from specific libraries. It helps you:
|
|
@@ -25,6 +43,9 @@ yarn global add importy
|
|
|
25
43
|
|
|
26
44
|
# Using pnpm
|
|
27
45
|
pnpm add -g importy
|
|
46
|
+
|
|
47
|
+
# Verify installation
|
|
48
|
+
importy --version # Should output: 0.1.0
|
|
28
49
|
```
|
|
29
50
|
|
|
30
51
|
## Usage
|
|
@@ -111,7 +132,7 @@ Importy uses parallel processing with promises, making it efficient even for lar
|
|
|
111
132
|
|
|
112
133
|
### Prerequisites
|
|
113
134
|
|
|
114
|
-
- Node.js
|
|
135
|
+
- Node.js 18+
|
|
115
136
|
- npm, yarn, or pnpm
|
|
116
137
|
|
|
117
138
|
### Setup
|
|
@@ -158,13 +179,49 @@ Contributions are welcome! Please feel free to submit a Pull Request.
|
|
|
158
179
|
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
159
180
|
5. Open a Pull Request
|
|
160
181
|
|
|
182
|
+
### Development Workflow
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
# Setup
|
|
186
|
+
git clone https://github.com/tvshevchuk/Importy.git
|
|
187
|
+
cd importy
|
|
188
|
+
pnpm install
|
|
189
|
+
|
|
190
|
+
# Development
|
|
191
|
+
npm run dev # Development mode
|
|
192
|
+
npm run check # Code quality checks
|
|
193
|
+
npm test # Run tests
|
|
194
|
+
npm run build # Build project
|
|
195
|
+
|
|
196
|
+
# Release (maintainers only)
|
|
197
|
+
npm run release:check # Check if ready for release
|
|
198
|
+
npm run release:patch # Create patch release
|
|
199
|
+
npm run release:minor # Create minor release
|
|
200
|
+
npm run release:major # Create major release
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Automated Releases
|
|
204
|
+
|
|
205
|
+
This project uses automated releases via GitHub Actions. When a pull request with a version bump is merged to main, it automatically:
|
|
206
|
+
|
|
207
|
+
- Runs tests and quality checks
|
|
208
|
+
- Updates the changelog
|
|
209
|
+
- Creates a GitHub release
|
|
210
|
+
- Publishes to npm
|
|
211
|
+
|
|
212
|
+
See [Release Process](.github/RELEASE_PROCESS.md) for detailed information.
|
|
213
|
+
|
|
161
214
|
## Troubleshooting
|
|
162
215
|
|
|
163
216
|
### Common Issues
|
|
164
217
|
|
|
165
|
-
- **ES Module Compatibility**: If you encounter issues with ES modules, ensure your Node.js version is compatible (
|
|
218
|
+
- **ES Module Compatibility**: If you encounter issues with ES modules, ensure your Node.js version is compatible (18+) and you're using the correct import syntax.
|
|
166
219
|
- **Parsing Errors**: Complex TypeScript/JSX syntax may occasionally cause parsing errors. These files are skipped with a warning.
|
|
167
220
|
|
|
221
|
+
## Changelog
|
|
222
|
+
|
|
223
|
+
See [CHANGELOG.md](CHANGELOG.md) for a detailed history of changes and releases.
|
|
224
|
+
|
|
168
225
|
## License
|
|
169
226
|
|
|
170
227
|
This project is licensed under the MIT License - see the LICENSE file for details.
|
package/dist/index.js
CHANGED
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import fs2 from "fs";
|
|
5
5
|
import path2 from "path";
|
|
6
|
-
import { program } from "commander";
|
|
7
|
-
import { fileURLToPath } from "url";
|
|
8
6
|
import { dirname } from "path";
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
8
|
+
import { program } from "commander";
|
|
9
9
|
|
|
10
10
|
// src/cli.ts
|
|
11
11
|
import fs from "fs";
|
|
12
|
+
import os from "os";
|
|
12
13
|
import path from "path";
|
|
13
14
|
import * as parser from "@babel/parser";
|
|
14
15
|
import _traverse from "@babel/traverse";
|
|
15
|
-
import os from "os";
|
|
16
16
|
var traverse = _traverse.default;
|
|
17
17
|
function isJavaScriptFile(file) {
|
|
18
18
|
return /\.(js|ts|jsx|tsx)$/.test(file);
|
|
@@ -40,11 +40,17 @@ function getAllFiles(dirPath, arrayOfFiles = [], includePattern, excludePattern,
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
} catch (error) {
|
|
43
|
-
if (verbose)
|
|
43
|
+
if (verbose)
|
|
44
|
+
console.warn(
|
|
45
|
+
`Error accessing file ${fullPath}: ${error instanceof Error ? error.message : String(error)}`
|
|
46
|
+
);
|
|
44
47
|
}
|
|
45
48
|
}
|
|
46
49
|
} catch (error) {
|
|
47
|
-
if (verbose)
|
|
50
|
+
if (verbose)
|
|
51
|
+
console.error(
|
|
52
|
+
`Error reading directory ${dirPath}: ${error instanceof Error ? error.message : String(error)}`
|
|
53
|
+
);
|
|
48
54
|
}
|
|
49
55
|
return arrayOfFiles;
|
|
50
56
|
}
|
|
@@ -54,7 +60,7 @@ function minimatch(filePath, pattern) {
|
|
|
54
60
|
const regex = new RegExp(`^${regExpPattern}$`, "i");
|
|
55
61
|
const result = regex.test(filePath);
|
|
56
62
|
return result;
|
|
57
|
-
} catch (
|
|
63
|
+
} catch (_error) {
|
|
58
64
|
console.warn(`Invalid pattern: ${pattern}`);
|
|
59
65
|
return false;
|
|
60
66
|
}
|
|
@@ -82,7 +88,9 @@ async function processFilesInBatches(items, batchSize, processor, onProgress) {
|
|
|
82
88
|
}
|
|
83
89
|
return result;
|
|
84
90
|
} catch (error) {
|
|
85
|
-
console.warn(
|
|
91
|
+
console.warn(
|
|
92
|
+
`Error processing item: ${error instanceof Error ? error.message : String(error)}`
|
|
93
|
+
);
|
|
86
94
|
completed++;
|
|
87
95
|
if (onProgress) {
|
|
88
96
|
onProgress(completed, total);
|
|
@@ -105,7 +113,7 @@ function extractImportsFromFile(filePath, targetLib) {
|
|
|
105
113
|
plugins: ["typescript", "jsx"],
|
|
106
114
|
errorRecovery: true
|
|
107
115
|
});
|
|
108
|
-
} catch (
|
|
116
|
+
} catch (_err) {
|
|
109
117
|
try {
|
|
110
118
|
ast = parser.parse(code, {
|
|
111
119
|
sourceType: "module",
|
|
@@ -118,7 +126,6 @@ function extractImportsFromFile(filePath, targetLib) {
|
|
|
118
126
|
}
|
|
119
127
|
}
|
|
120
128
|
const matches = [];
|
|
121
|
-
const lines = code.split("\n");
|
|
122
129
|
traverse(ast, {
|
|
123
130
|
ImportDeclaration(path3) {
|
|
124
131
|
const node = path3.node;
|
|
@@ -149,7 +156,9 @@ function extractImportsFromFile(filePath, targetLib) {
|
|
|
149
156
|
});
|
|
150
157
|
return matches;
|
|
151
158
|
} catch (error) {
|
|
152
|
-
console.warn(
|
|
159
|
+
console.warn(
|
|
160
|
+
`Error reading file ${filePath}: ${error instanceof Error ? error.message : String(error)}`
|
|
161
|
+
);
|
|
153
162
|
return [];
|
|
154
163
|
}
|
|
155
164
|
}
|
|
@@ -176,7 +185,8 @@ async function analyzeImports(options2) {
|
|
|
176
185
|
};
|
|
177
186
|
}
|
|
178
187
|
const batchSize = Math.max(1, Math.ceil(allFiles.length / concurrency));
|
|
179
|
-
if (verbose)
|
|
188
|
+
if (verbose)
|
|
189
|
+
console.log(`Processing ${allFiles.length} files with ${concurrency} concurrent processes`);
|
|
180
190
|
let processedCount = 0;
|
|
181
191
|
const results = await processFilesInBatches(
|
|
182
192
|
allFiles,
|
|
@@ -211,7 +221,9 @@ async function analyzeImports(options2) {
|
|
|
211
221
|
const totalImports = Object.values(output).reduce((sum, files) => sum + files.length, 0);
|
|
212
222
|
const totalComponents = Object.keys(output).length;
|
|
213
223
|
if (verbose) {
|
|
214
|
-
console.log(
|
|
224
|
+
console.log(
|
|
225
|
+
`Analysis complete - Found ${totalComponents} components with ${totalImports} total imports across ${allFiles.length} files`
|
|
226
|
+
);
|
|
215
227
|
}
|
|
216
228
|
return {
|
|
217
229
|
summary: {
|
|
@@ -225,6 +237,15 @@ async function analyzeImports(options2) {
|
|
|
225
237
|
}
|
|
226
238
|
|
|
227
239
|
// src/index.ts
|
|
240
|
+
var REQUIRED_NODE_VERSION = 18;
|
|
241
|
+
var currentNodeVersion = Number.parseInt(process.version.slice(1).split(".")[0], 10);
|
|
242
|
+
if (currentNodeVersion < REQUIRED_NODE_VERSION) {
|
|
243
|
+
console.error(
|
|
244
|
+
`\u274C Error: Node.js ${REQUIRED_NODE_VERSION}+ is required. You are running Node.js ${process.version}`
|
|
245
|
+
);
|
|
246
|
+
console.error("Please upgrade your Node.js version: https://nodejs.org/");
|
|
247
|
+
process.exit(1);
|
|
248
|
+
}
|
|
228
249
|
var __filename = fileURLToPath(import.meta.url);
|
|
229
250
|
var __dirname = dirname(__filename);
|
|
230
251
|
var packageJson;
|
|
@@ -232,20 +253,11 @@ try {
|
|
|
232
253
|
const packagePath = path2.resolve(__dirname, "../package.json");
|
|
233
254
|
const packageData = fs2.readFileSync(packagePath, "utf8");
|
|
234
255
|
packageJson = JSON.parse(packageData);
|
|
235
|
-
} catch (
|
|
256
|
+
} catch (_error) {
|
|
236
257
|
packageJson = { version: "0.0.0", name: "importy" };
|
|
237
258
|
console.warn("Could not load package.json, using default version");
|
|
238
259
|
}
|
|
239
|
-
program.version(packageJson.version).description("Analyze JavaScript/TypeScript imports from a specific library").requiredOption("-d, --dir <directory>", "Directory to scan").requiredOption("-l, --lib <library>", "Library name to match").option(
|
|
240
|
-
"-o, --output <file>",
|
|
241
|
-
"Output results to a JSON file instead of stdout"
|
|
242
|
-
).option("-v, --verbose", "Enable verbose logging").option(
|
|
243
|
-
"-i, --include <pattern>",
|
|
244
|
-
"Only include files matching pattern (glob)"
|
|
245
|
-
).option("-e, --exclude <pattern>", "Exclude files matching pattern (glob)").option(
|
|
246
|
-
"-c, --concurrency <number>",
|
|
247
|
-
"Number of worker threads (defaults to CPU count - 1)"
|
|
248
|
-
).parse(process.argv);
|
|
260
|
+
program.version(packageJson.version).description("Analyze JavaScript/TypeScript imports from a specific library").requiredOption("-d, --dir <directory>", "Directory to scan").requiredOption("-l, --lib <library>", "Library name to match").option("-o, --output <file>", "Output results to a JSON file instead of stdout").option("-v, --verbose", "Enable verbose logging").option("-i, --include <pattern>", "Only include files matching pattern (glob)").option("-e, --exclude <pattern>", "Exclude files matching pattern (glob)").option("-c, --concurrency <number>", "Number of worker threads (defaults to CPU count - 1)").parse(process.argv);
|
|
249
261
|
var options = program.opts();
|
|
250
262
|
async function main() {
|
|
251
263
|
try {
|
|
@@ -255,7 +267,7 @@ async function main() {
|
|
|
255
267
|
include: options.include,
|
|
256
268
|
exclude: options.exclude,
|
|
257
269
|
verbose: options.verbose || false,
|
|
258
|
-
concurrency: options.concurrency ? parseInt(options.concurrency, 10) : void 0
|
|
270
|
+
concurrency: options.concurrency ? Number.parseInt(options.concurrency, 10) : void 0
|
|
259
271
|
});
|
|
260
272
|
if (options.output) {
|
|
261
273
|
try {
|
|
@@ -271,9 +283,7 @@ async function main() {
|
|
|
271
283
|
console.log(JSON.stringify(result, null, 2));
|
|
272
284
|
}
|
|
273
285
|
if (Object.keys(result.components).length === 0) {
|
|
274
|
-
console.warn(
|
|
275
|
-
`No imports from '${options.lib}' were found in the specified directory.`
|
|
276
|
-
);
|
|
286
|
+
console.warn(`No imports from '${options.lib}' were found in the specified directory.`);
|
|
277
287
|
process.exit(0);
|
|
278
288
|
}
|
|
279
289
|
return result;
|
|
@@ -285,8 +295,6 @@ async function main() {
|
|
|
285
295
|
}
|
|
286
296
|
}
|
|
287
297
|
main().catch((error) => {
|
|
288
|
-
console.error(
|
|
289
|
-
`Unhandled error: ${error instanceof Error ? error.message : String(error)}`
|
|
290
|
-
);
|
|
298
|
+
console.error(`Unhandled error: ${error instanceof Error ? error.message : String(error)}`);
|
|
291
299
|
process.exit(1);
|
|
292
300
|
});
|
package/package.json
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "importy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "A CLI tool for analyzing JavaScript/TypeScript imports from libraries",
|
|
5
|
+
"homepage": "https://tvshevchuk.github.io/Importy/",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/tvshevchuk/Importy/issues"
|
|
8
|
+
},
|
|
5
9
|
"repository": {
|
|
6
10
|
"type": "git",
|
|
7
11
|
"url": "https://github.com/tvshevchuk/Importy"
|
|
8
12
|
},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=18.0.0"
|
|
15
|
+
},
|
|
9
16
|
"type": "module",
|
|
10
17
|
"main": "./dist/index.js",
|
|
11
18
|
"bin": {
|
|
@@ -21,12 +28,14 @@
|
|
|
21
28
|
],
|
|
22
29
|
"devDependencies": {
|
|
23
30
|
"@babel/types": "7.27.3",
|
|
31
|
+
"@biomejs/biome": "1.9.4",
|
|
24
32
|
"@types/babel__traverse": "7.20.7",
|
|
25
33
|
"@types/node": "22.15.29",
|
|
26
34
|
"ts-node": "10.9.2",
|
|
27
35
|
"tsup": "8.5.0",
|
|
28
36
|
"typescript": "5.8.3",
|
|
29
|
-
"
|
|
37
|
+
"vitepress": "^1.6.3",
|
|
38
|
+
"vitest": "1.6.1"
|
|
30
39
|
},
|
|
31
40
|
"dependencies": {
|
|
32
41
|
"@babel/parser": "7.27.5",
|
|
@@ -81,6 +90,25 @@
|
|
|
81
90
|
"start": "node dist/index.js",
|
|
82
91
|
"dev": "ts-node src/index.ts",
|
|
83
92
|
"test": "vitest run",
|
|
84
|
-
"test:watch": "vitest"
|
|
93
|
+
"test:watch": "vitest",
|
|
94
|
+
"lint": "biome lint src/",
|
|
95
|
+
"lint:fix": "biome lint --write src/",
|
|
96
|
+
"format": "biome format src/",
|
|
97
|
+
"format:fix": "biome format --write src/",
|
|
98
|
+
"check": "biome check src/",
|
|
99
|
+
"check:fix": "biome check --write src/",
|
|
100
|
+
"prebuild": "npm run check",
|
|
101
|
+
"version": "npm run check:fix && git add -A src",
|
|
102
|
+
"postversion": "git push && git push --tags",
|
|
103
|
+
"release": "./scripts/release.sh",
|
|
104
|
+
"release:patch": "./scripts/release.sh patch",
|
|
105
|
+
"release:minor": "./scripts/release.sh minor",
|
|
106
|
+
"release:major": "./scripts/release.sh major",
|
|
107
|
+
"release:check": "./scripts/release.sh --check",
|
|
108
|
+
"release:manual": "./scripts/release.sh --manual",
|
|
109
|
+
"prerelease": "npm run test && npm run check",
|
|
110
|
+
"docs:dev": "vitepress dev docs",
|
|
111
|
+
"docs:build": "vitepress build docs",
|
|
112
|
+
"docs:preview": "vitepress preview docs"
|
|
85
113
|
}
|
|
86
114
|
}
|