rev-dep 1.0.0-alpha.0 → 1.0.0-alpha.3

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
@@ -117,7 +117,7 @@ For example, to support `*.ts` and `*.tsx` implicit extensions in globally insta
117
117
 
118
118
  ### Command `resolve`
119
119
 
120
- Description not available
120
+ Checks if a filePath is required from entryPoint(s) and prints the resolution path
121
121
 
122
122
  #### Usage
123
123
 
@@ -127,18 +127,58 @@ rev-dep resolve <filePath> [entryPoints...] [options]
127
127
 
128
128
  #### Arguments
129
129
 
130
- - `filePath` - undefined (**required**),\* `entryPoints...` - undefined (_optional_)
130
+ - `filePath` - Path to a file that should be resolved in entry points (**required**),\* `entryPoints...` - List of entry points to look for file (_optional_)
131
131
 
132
132
  #### Options
133
133
 
134
+ - `-wc, --webpackConfig <path>` - path to webpack config to enable webpack aliases support (_optional_)
135
+ - `--cwd <path>` - path to a directory that should be used as a resolution root (_optional_)
136
+ - `-rr --reexportRewire <value>` - resolve actual dependencies for "export \* from" statements (_optional_)
137
+ - `-i --include <globs...>` - A list of globs to determine files included in entry points search (_optional_)
138
+ - `-e --exclude <globs...>` - A list of globs to determine files excluded in entry points search (_optional_)
134
139
  - `-cs, --compactSummary` - print a compact summary of reverse resolution with a count of found paths (_optional_)
135
- - `--verbose` - print current action information (_optional_)
140
+ - `-a, --all` - finds all paths combination of a given dependency. Might work very slow or crash for some projects due to heavy usage of RAM (_optional_)
141
+
142
+ ### Command `entry-points`
143
+
144
+ Print list of entry points in current directory
145
+
146
+ #### Usage
147
+
148
+ ```sh
149
+ rev-dep entry-points [options]
150
+ ```
151
+
152
+ #### Options
153
+
154
+ - `-wc, --webpackConfig <path>` - path to webpack config to enable webpack aliases support (_optional_)
155
+ - `--cwd <path>` - path to a directory that should be used as a resolution root (_optional_)
156
+ - `-rr --reexportRewire <value>` - resolve actual dependencies for "export \* from" statements (_optional_)
157
+ - `-i --include <globs...>` - A list of globs to determine files included in entry points search (_optional_)
158
+ - `-e --exclude <globs...>` - A list of globs to determine files excluded in entry points search (_optional_)
159
+ - `-pdc, --printDependenciesCount` - print count of entry point dependencies (_optional_)
160
+ - `-c, --count` - print just count of found entry points (_optional_)
161
+
162
+ ### Command `files`
163
+
164
+ Get list of files required by entry point
165
+
166
+ #### Usage
167
+
168
+ ```sh
169
+ rev-dep files <entryPoint> [options]
170
+ ```
171
+
172
+ #### Arguments
173
+
174
+ - `entryPoint` - Path to entry point (**required**)
175
+
176
+ #### Options
177
+
136
178
  - `-wc, --webpackConfig <path>` - path to webpack config to enable webpack aliases support (_optional_)
137
- - `-tc, --typescriptConfig <path>` - path to TypeScript config to enable TS aliases support (_optional_)
138
- - `-md, --maxDepth <maxDepth>` - max depth of the dependency tree (_optional_)
139
- - `-pmd, --printMaxDepth` - print max depth in the tree (_optional_)
140
- - `-pdc, --printDependentCount` - print count of entry point dependencies (_optional_)
141
- - `-co, --checkOnly` - finds only one path to entry point instead of all (_optional_)
179
+ - `--cwd <path>` - path to a directory that should be used as a resolution root (_optional_)
180
+ - `-rr --reexportRewire <value>` - resolve actual dependencies for "export \* from" statements (_optional_)
181
+ - `-c, --count` - print only count of entry point dependencies (_optional_)
142
182
 
143
183
  ### Command `docs`
144
184
 
package/babel.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./dist/babel/index.js')
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+ /*eslint-disable @typescript-eslint/no-var-requires */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const node_path = require('path');
5
+ const fs = require('fs');
6
+ const parser = require('@babel/parser');
7
+ const template = require('@babel/template').default;
8
+ const utils_1 = require("../lib/utils");
9
+ const SKIP = Symbol('SKIP');
10
+ module.exports = function plugin({ types }, { tsConfigPath = (0, utils_1.findTsConfig)() }) {
11
+ const tsConfig = require(tsConfigPath);
12
+ const aliases = tsConfig.compilerOptions.paths;
13
+ const aliasesKeys = Object.keys(aliases);
14
+ const aliasesRegexes = Object.keys(aliases).map((alias) => {
15
+ return new RegExp(`^${alias.replace('*', '(.)+')}$`);
16
+ });
17
+ const cache = new Map();
18
+ const getFile = (original, paths) => {
19
+ if (paths.length === 0) {
20
+ throw new Error('Cannot resolve import ' + original);
21
+ }
22
+ const path = paths[0];
23
+ try {
24
+ return [path, fs.readFileSync(path).toString()];
25
+ }
26
+ catch (e) {
27
+ return getFile(original, paths.slice(1));
28
+ }
29
+ };
30
+ const isPathRelativeOrAliased = (path) => {
31
+ const aliasRegexIdx = aliasesRegexes.findIndex((aliasRegex) => aliasRegex.test(path));
32
+ const isRelative = path.startsWith('./') || path.startsWith('../');
33
+ return aliasRegexIdx > -1 || isRelative;
34
+ };
35
+ const cacheKey = (identifier, filePath) => `${identifier}-${filePath}`;
36
+ const lookup = (identifier, filePath, cwd) => {
37
+ const cached = cache.get(cacheKey(identifier, filePath));
38
+ if (cached) {
39
+ return cached;
40
+ }
41
+ const withExtension = /(\.ts|\.tsx)$/.test(filePath)
42
+ ? [filePath]
43
+ : [
44
+ `${filePath}.ts`,
45
+ `${filePath}.tsx`,
46
+ `${filePath}/index.ts`,
47
+ `${filePath}/index.tsx`,
48
+ `${filePath}.js`,
49
+ `${filePath}.jsx`,
50
+ `${filePath}/index.js`,
51
+ `${filePath}/index.jsx`
52
+ ];
53
+ const [resolvedFilePath, file] = getFile(filePath, withExtension);
54
+ const ast = parser.parse(file, {
55
+ sourceType: 'module',
56
+ plugins: [
57
+ 'jsx',
58
+ 'typescript',
59
+ 'objectRestSpread',
60
+ 'classProperties',
61
+ 'asyncGenerators',
62
+ 'decorators-legacy'
63
+ ]
64
+ });
65
+ /**
66
+ * {
67
+ * identifier?: string,
68
+ * source: string
69
+ * }
70
+ */
71
+ const toLookup = [];
72
+ let resolvedAs = null;
73
+ ast.program.body.forEach((declaration) => {
74
+ var _a;
75
+ if (resolvedAs === null) {
76
+ if (types.isExportNamedDeclaration(declaration)) {
77
+ if (types.isVariableDeclaration(declaration.declaration)) {
78
+ const hasIdentifier = declaration.declaration.declarations.find((declarator) => {
79
+ return declarator.id.name === identifier;
80
+ });
81
+ if (hasIdentifier) {
82
+ resolvedAs = {
83
+ type: 'named',
84
+ identifier,
85
+ source: filePath
86
+ };
87
+ }
88
+ }
89
+ else if (types.isFunctionDeclaration(declaration.declaration) ||
90
+ types.isClassDeclaration(declaration.declaration)) {
91
+ if (declaration.declaration.id.name === identifier) {
92
+ resolvedAs = {
93
+ type: 'named',
94
+ identifier,
95
+ source: filePath
96
+ };
97
+ }
98
+ }
99
+ else {
100
+ const source = (_a = declaration.source) === null || _a === void 0 ? void 0 : _a.value;
101
+ declaration.specifiers.forEach((specifier) => {
102
+ if (types.isExportSpecifier(specifier)) {
103
+ if (specifier.exported.name === identifier) {
104
+ if (specifier.local.name === 'default' && source) {
105
+ resolvedAs = {
106
+ type: 'default',
107
+ identifier,
108
+ source: getModulePath(source, resolvedFilePath, cwd)
109
+ };
110
+ }
111
+ else if (source === undefined) {
112
+ resolvedAs = {
113
+ type: 'named',
114
+ identifier,
115
+ source: filePath
116
+ };
117
+ }
118
+ else if (isPathRelativeOrAliased(source)) {
119
+ toLookup.push({
120
+ identifier: specifier.exported.local,
121
+ source: getModulePath(source, resolvedFilePath, cwd)
122
+ });
123
+ }
124
+ }
125
+ }
126
+ });
127
+ }
128
+ }
129
+ else if (types.isExportAllDeclaration(declaration) &&
130
+ isPathRelativeOrAliased(declaration.source.value)) {
131
+ toLookup.push({
132
+ identifier,
133
+ source: getModulePath(declaration.source.value, resolvedFilePath, cwd)
134
+ });
135
+ }
136
+ }
137
+ });
138
+ if (resolvedAs) {
139
+ return resolvedAs;
140
+ }
141
+ const nestedResult = toLookup
142
+ .map(({ identifier, source }) => lookup(identifier, source, cwd))
143
+ .filter(Boolean);
144
+ return nestedResult[0];
145
+ };
146
+ const getModulePath = (sourcePath, fileName, cwd) => {
147
+ var _a;
148
+ const aliasRegexIdx = aliasesRegexes.findIndex((aliasRegex) => aliasRegex.test(sourcePath));
149
+ const relativeFileName = node_path.relative(cwd, fileName);
150
+ const aliasKey = aliasesKeys[aliasRegexIdx];
151
+ const alias = (_a = aliases[aliasKey]) === null || _a === void 0 ? void 0 : _a[0];
152
+ let modulePath = '';
153
+ if (alias) {
154
+ let relative = alias;
155
+ if (aliasKey.endsWith('*')) {
156
+ const aliasKeyPrefix = aliasKey.replace('*', '');
157
+ relative = alias.replace('*', sourcePath.replace(aliasKeyPrefix, ''));
158
+ }
159
+ modulePath = node_path.resolve(cwd, relative);
160
+ }
161
+ else {
162
+ // we need ../ to skip current file name
163
+ modulePath = node_path.resolve(relativeFileName, '../' + sourcePath);
164
+ }
165
+ return modulePath;
166
+ };
167
+ return {
168
+ visitor: {
169
+ ImportDeclaration(path, { filename, cwd }) {
170
+ const sourceRelative = (source) => {
171
+ const rel = node_path.relative(node_path.dirname(filename), source);
172
+ return rel.startsWith('.') ? rel : './' + rel;
173
+ };
174
+ const node = path.node;
175
+ const source = node.source;
176
+ if (source.type !== 'StringLiteral') {
177
+ return;
178
+ }
179
+ const shouldSkip = node[SKIP] || !isPathRelativeOrAliased(source.value);
180
+ if (shouldSkip) {
181
+ return;
182
+ }
183
+ const modulePath = getModulePath(source.value, filename, cwd);
184
+ const defaultSpecifier = node.specifiers.find((specifier) => specifier.type === 'ImportDefaultSpecifier');
185
+ const namespaceSpecifier = node.specifiers.find((specifier) => specifier.type === 'ImportNamespaceSpecifier');
186
+ const specifiers = node.specifiers.filter((specifier) => specifier.type === 'ImportSpecifier');
187
+ const results = specifiers.map((specifier) => {
188
+ const importedName = specifier.imported.name;
189
+ const result = lookup(importedName, modulePath, cwd);
190
+ if (!result) {
191
+ return {
192
+ identifier: importedName,
193
+ local: specifier.local.name,
194
+ source: source.value
195
+ };
196
+ }
197
+ cache.set(cacheKey(importedName, modulePath), result);
198
+ return {
199
+ ...result,
200
+ source: sourceRelative(result.source),
201
+ local: specifier.local.name
202
+ };
203
+ });
204
+ const defaultResult = defaultSpecifier
205
+ ? lookup('default', modulePath, cwd)
206
+ : null;
207
+ if (defaultResult) {
208
+ cache.set(cacheKey('default', modulePath), defaultResult);
209
+ }
210
+ const buildNamed = template(`
211
+ import { %%IMPORT_NAME%% } from %%SOURCE%%;
212
+ `);
213
+ const buildNamedWithAlias = template(`
214
+ import { %%IMPORTED_NAME%% as %%LOCAL_NAME%% } from %%SOURCE%%;
215
+ `);
216
+ const buildDefault = template(`
217
+ import %%IMPORT_NAME%% from %%SOURCE%%;
218
+ `);
219
+ const buildNamespace = template(`
220
+ import * as %%IMPORT_NAME%% from %%SOURCE%%;
221
+ `);
222
+ const defaultImport = defaultResult
223
+ ? [
224
+ buildDefault({
225
+ IMPORT_NAME: types.identifier(defaultSpecifier.local.name),
226
+ SOURCE: types.stringLiteral(sourceRelative(defaultResult.source))
227
+ })
228
+ ]
229
+ : defaultSpecifier
230
+ ? [
231
+ buildDefault({
232
+ IMPORT_NAME: types.identifier(defaultSpecifier.local.name),
233
+ SOURCE: types.stringLiteral(source.value)
234
+ })
235
+ ]
236
+ : [];
237
+ const namespaceImport = namespaceSpecifier
238
+ ? [
239
+ buildNamespace({
240
+ IMPORT_NAME: types.identifier(namespaceSpecifier.local.name),
241
+ SOURCE: types.stringLiteral(source.value)
242
+ })
243
+ ]
244
+ : [];
245
+ const named = results.map(({ type, identifier, local, source }) => {
246
+ if (type === 'default') {
247
+ return buildDefault({
248
+ IMPORT_NAME: types.identifier(identifier),
249
+ SOURCE: types.stringLiteral(source)
250
+ });
251
+ }
252
+ else if (identifier !== local) {
253
+ return buildNamedWithAlias({
254
+ IMPORTED_NAME: types.identifier(identifier),
255
+ LOCAL_NAME: types.identifier(local),
256
+ SOURCE: types.stringLiteral(source)
257
+ });
258
+ }
259
+ else {
260
+ return buildNamed({
261
+ IMPORT_NAME: types.identifier(identifier),
262
+ SOURCE: types.stringLiteral(source)
263
+ });
264
+ }
265
+ });
266
+ const newImports = [...namespaceImport, ...defaultImport, ...named].map((node) => {
267
+ node[SKIP] = true;
268
+ return node;
269
+ });
270
+ path.replaceWithMultiple(newImports);
271
+ }
272
+ }
273
+ };
274
+ };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.reexportRewireOption = exports.cwdOption = exports.webpackConfigOption = void 0;
3
+ exports.excludeOption = exports.includeOption = exports.reexportRewireOption = exports.cwdOption = exports.webpackConfigOption = void 0;
4
4
  exports.webpackConfigOption = [
5
5
  '-wc, --webpackConfig <path>',
6
6
  'path to webpack config to enable webpack aliases support'
@@ -11,6 +11,14 @@ exports.cwdOption = [
11
11
  process.cwd()
12
12
  ];
13
13
  exports.reexportRewireOption = [
14
- '--rr reexportRewire <value>',
14
+ '-rr --reexportRewire <value>',
15
15
  'resolve actual dependencies for "export * from" statements'
16
16
  ];
17
+ exports.includeOption = [
18
+ '-i --include <globs...>',
19
+ 'A list of globs to determine files included in entry points search'
20
+ ];
21
+ exports.excludeOption = [
22
+ '-e --exclude <globs...>',
23
+ 'A list of globs to determine files excluded in entry points search'
24
+ ];
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const commonOptions_1 = require("../commonOptions");
4
4
  const getEntryPoints_1 = require("../../lib/getEntryPoints");
5
5
  const buildDepsGraph_1 = require("../../lib/buildDepsGraph");
6
+ const utils_1 = require("../../lib/utils");
6
7
  function createEntryPoints(program) {
7
8
  program
8
9
  .command('entry-points')
@@ -10,19 +11,32 @@ function createEntryPoints(program) {
10
11
  .option(...commonOptions_1.webpackConfigOption)
11
12
  .option(...commonOptions_1.cwdOption)
12
13
  .option(...commonOptions_1.reexportRewireOption)
13
- .option('-pdc, --printDependentCount', 'print count of entry point dependencies', false)
14
+ .option(...commonOptions_1.includeOption)
15
+ .option(...commonOptions_1.excludeOption)
16
+ .option('-pdc, --printDependenciesCount', 'print count of entry point dependencies', false)
17
+ .option('-c, --count', 'print just count of found entry points', false)
14
18
  .action(async (data) => {
15
- const { webpackConfig: webpackConfigPath, cwd, printDependentCount } = data;
19
+ const { webpackConfig: webpackConfigPath, cwd, printDependenciesCount, include, exclude, count } = data;
16
20
  const [entryPoints, depsTree] = await (0, getEntryPoints_1.getEntryPoints)({
17
- cwd,
18
- webpackConfigPath
21
+ cwd: (0, utils_1.resolvePath)(cwd),
22
+ webpackConfigPath,
23
+ exclude,
24
+ include
19
25
  });
20
26
  let depsCount = null;
21
- if (printDependentCount) {
27
+ if (printDependenciesCount) {
22
28
  depsCount = entryPoints
23
29
  .map((0, buildDepsGraph_1.buildGraphDpdm)(depsTree))
24
30
  .map(([_, __, vertices]) => vertices.size);
25
31
  }
32
+ if (count) {
33
+ console.log('Found', entryPoints.length, 'entry points.');
34
+ return;
35
+ }
36
+ if (entryPoints.length === 0) {
37
+ console.log('No results found');
38
+ return;
39
+ }
26
40
  entryPoints.forEach((pathName, idx) => {
27
41
  if (depsCount !== null) {
28
42
  console.log(pathName, depsCount[idx]);
@@ -6,7 +6,9 @@ const getDepsTree_1 = require("../../lib/getDepsTree");
6
6
  function createFiles(program) {
7
7
  program
8
8
  .command('files <entryPoint>')
9
- .description('Get list of files required by entry point')
9
+ .description('Get list of files required by entry point', {
10
+ entryPoint: 'Path to entry point'
11
+ })
10
12
  .option(...commonOptions_1.webpackConfigOption)
11
13
  .option(...commonOptions_1.cwdOption)
12
14
  .option(...commonOptions_1.reexportRewireOption)
@@ -14,8 +16,12 @@ function createFiles(program) {
14
16
  .action(async (entryPoint, data) => {
15
17
  const { webpackConfig: webpackConfigPath, cwd, count } = data;
16
18
  const sanitizedEntryPoints = (0, utils_1.sanitizeUserEntryPoints)([entryPoint]);
17
- const depsTree = await (0, getDepsTree_1.getDepsTree)(cwd, sanitizedEntryPoints, webpackConfigPath);
19
+ const depsTree = await (0, getDepsTree_1.getDepsTree)((0, utils_1.resolvePath)(cwd), sanitizedEntryPoints, webpackConfigPath);
18
20
  const filePaths = Object.keys(depsTree);
21
+ if (filePaths.length === 0) {
22
+ console.log('No results found');
23
+ return;
24
+ }
19
25
  if (count) {
20
26
  console.log(filePaths.length);
21
27
  }
@@ -1,6 +1,30 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
26
  exports.formatResults = void 0;
27
+ const colors = __importStar(require("colorette"));
4
28
  const pathToString = (str, filePath, indentation) => {
5
29
  return `${str ? `${str}\n` : ''}${' '.repeat(indentation)} ➞ ${filePath}`;
6
30
  };
@@ -10,10 +34,10 @@ function formatResults({ results, filePath, entryPoints, compactSummary }) {
10
34
  const hasAnyResults = results.some((paths) => paths.length > 0);
11
35
  if (!hasAnyResults) {
12
36
  formatted = join('No results found for', filePath, 'in', entryPoints);
13
- return;
37
+ return formatted;
14
38
  }
15
- formatted += join('Results:\n');
16
39
  if (compactSummary) {
40
+ formatted += join('Results:\n');
17
41
  const maxEntryLength = entryPoints.reduce((maxLength, entryPoint) => {
18
42
  return entryPoint.length > maxLength ? entryPoint.length : maxLength;
19
43
  }, 0);
@@ -26,11 +50,15 @@ function formatResults({ results, filePath, entryPoints, compactSummary }) {
26
50
  }
27
51
  else {
28
52
  results.forEach((entryPointResults, index) => {
29
- entryPointResults.forEach((path) => {
30
- formatted += join(path.reduce(pathToString, ''), '\n');
31
- });
32
- if (index < results.length - 1 && entryPointResults.length > 0) {
33
- formatted += join('_'.repeat(process.stdout.columns));
53
+ if (entryPointResults.length > 0) {
54
+ formatted += join(colors.bold(entryPoints[index]), ':', '\n');
55
+ entryPointResults.forEach((path, resultsIndex) => {
56
+ const isLast = resultsIndex === entryPointResults.length - 1;
57
+ formatted += join(path.reduce(pathToString, ''), isLast ? '' : '\n');
58
+ });
59
+ if (index < results.length - 1 && entryPointResults.length > 0) {
60
+ formatted += join('_'.repeat(process.stdout.columns)) + '\n';
61
+ }
34
62
  }
35
63
  });
36
64
  }
@@ -3,27 +3,36 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const find_1 = require("../../lib/find");
4
4
  const formatResults_1 = require("./formatResults");
5
5
  const utils_1 = require("../../lib/utils");
6
+ const commonOptions_1 = require("../commonOptions");
6
7
  function createResolve(program) {
7
8
  program
8
9
  .command('resolve <filePath> [entryPoints...]')
9
- .description('Checks if a filePath is required from entryPoint(s) and prints the resolution path')
10
+ .description('Checks if a filePath is required from entryPoint(s) and prints the resolution path', {
11
+ filePath: 'Path to a file that should be resolved in entry points',
12
+ 'entryPoints...': 'List of entry points to look for file'
13
+ })
14
+ .option(...commonOptions_1.webpackConfigOption)
15
+ .option(...commonOptions_1.cwdOption)
16
+ .option(...commonOptions_1.reexportRewireOption)
17
+ .option(...commonOptions_1.includeOption)
18
+ .option(...commonOptions_1.excludeOption)
10
19
  .option('-cs, --compactSummary', 'print a compact summary of reverse resolution with a count of found paths')
11
- .option('-wc, --webpackConfig <path>', 'path to webpack config to enable webpack aliases support')
12
- .option('-pmd, --printMaxDepth', 'print max depth in the tree', false)
13
- .option('-a, --all', 'finds all paths combination of a given dependency. Might work very slow and tend to crash for some projects', false)
20
+ .option('-a, --all', 'finds all paths combination of a given dependency. Might work very slow or crash for some projects due to heavy usage of RAM', false)
14
21
  .action(async (filePath, entryPoints, data) => {
15
- const { compactSummary, webpackConfig, printMaxDepth, all } = data;
22
+ const { compactSummary, webpackConfig, all, cwd, exclude, include } = data;
16
23
  const sanitizedEntryPoints = (0, utils_1.sanitizeUserEntryPoints)(entryPoints);
17
- const results = await (0, find_1.resolve)({
24
+ const [results, resolveEntryPoints] = await (0, find_1.resolve)({
18
25
  entryPoints: sanitizedEntryPoints,
19
26
  filePath,
20
27
  webpackConfig,
21
- printMaxDepth,
22
- all
28
+ all,
29
+ cwd: (0, utils_1.resolvePath)(cwd),
30
+ exclude,
31
+ include
23
32
  });
24
33
  const formatted = (0, formatResults_1.formatResults)({
25
34
  results,
26
- entryPoints,
35
+ entryPoints: resolveEntryPoints,
27
36
  compactSummary,
28
37
  filePath
29
38
  });
@@ -1,12 +1,18 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.cleanupDpdmDeps = void 0;
7
+ const is_builtin_module_1 = __importDefault(require("is-builtin-module"));
4
8
  const cleanupDpdmDeps = (deps) => {
5
9
  const newDeps = {};
6
10
  Object.entries(deps).forEach(([id, dependencies]) => {
7
- if (!id.includes('node_modules') && dependencies !== null) {
11
+ if (!(0, is_builtin_module_1.default)(id) &&
12
+ !id.includes('node_modules') &&
13
+ dependencies !== null) {
8
14
  newDeps[id] = dependencies
9
- .filter(({ id }) => id && !id.includes('node_modules'))
15
+ .filter(({ id }) => id && !id.includes('node_modules') && !(0, is_builtin_module_1.default)(id))
10
16
  .map(({ id, request }) => ({
11
17
  id,
12
18
  request
package/dist/lib/find.js CHANGED
@@ -4,7 +4,6 @@ exports.resolve = void 0;
4
4
  const buildDepsGraph_1 = require("./buildDepsGraph");
5
5
  const getDepsTree_1 = require("./getDepsTree");
6
6
  const getEntryPoints_1 = require("./getEntryPoints");
7
- const getMaxDepthInGrapth_1 = require("./getMaxDepthInGrapth");
8
7
  const utils_1 = require("./utils");
9
8
  const resolvePathsToRoot = (node, all = false, resolvedPaths = [[]]) => {
10
9
  const newPaths = resolvedPaths.map((resolvedPath) => [
@@ -21,7 +20,7 @@ const resolvePathsToRoot = (node, all = false, resolvedPaths = [[]]) => {
21
20
  }
22
21
  return resolvePathsToRoot(node.parents[0], false, newPaths);
23
22
  };
24
- const resolve = async ({ entryPoints: _entryPoints, filePath, webpackConfig, cwd = process.cwd(), printMaxDepth, all }) => {
23
+ const resolve = async ({ entryPoints: _entryPoints, filePath, webpackConfig, cwd = process.cwd(), all, include, exclude }) => {
25
24
  let deps, entryPoints;
26
25
  if (_entryPoints.length > 0) {
27
26
  entryPoints = _entryPoints;
@@ -29,16 +28,11 @@ const resolve = async ({ entryPoints: _entryPoints, filePath, webpackConfig, cwd
29
28
  }
30
29
  else {
31
30
  ;
32
- [entryPoints, deps] = await (0, getEntryPoints_1.getEntryPoints)({ cwd });
31
+ [entryPoints, deps] = await (0, getEntryPoints_1.getEntryPoints)({ cwd, exclude, include });
33
32
  }
34
33
  const cleanedEntryPoints = entryPoints.map(utils_1.removeInitialDot);
35
34
  const cleanedFilePath = (0, utils_1.removeInitialDot)(filePath);
36
35
  const forest = cleanedEntryPoints.map((0, buildDepsGraph_1.buildGraphDpdm)(deps, cleanedFilePath));
37
- if (printMaxDepth) {
38
- forest.forEach(([tree]) => {
39
- console.log('Max depth', ...(0, getMaxDepthInGrapth_1.getMaxDepth)()(tree));
40
- });
41
- }
42
36
  const resolvedPaths = forest.reduce((allPaths, [_, fileNode]) => {
43
37
  if (!fileNode) {
44
38
  return [...allPaths, []];
@@ -46,6 +40,6 @@ const resolve = async ({ entryPoints: _entryPoints, filePath, webpackConfig, cwd
46
40
  const pathsForTree = resolvePathsToRoot(fileNode, all);
47
41
  return [...allPaths, pathsForTree];
48
42
  }, []);
49
- return resolvedPaths;
43
+ return [resolvedPaths, entryPoints];
50
44
  };
51
45
  exports.resolve = resolve;
@@ -5,11 +5,19 @@ const getDepsSetWebpack_1 = require("./getDepsSetWebpack");
5
5
  const dpdm_1 = require("dpdm");
6
6
  const cleanupDpdmDeps_1 = require("./cleanupDpdmDeps");
7
7
  async function getDepsTree(cwd, entryPoints, webpackConfigPath) {
8
- const deps = webpackConfigPath
9
- ? (0, getDepsSetWebpack_1.getDepsSetWebpack)(entryPoints, webpackConfigPath, cwd)
10
- : (0, cleanupDpdmDeps_1.cleanupDpdmDeps)(await (0, dpdm_1.parseDependencyTree)(entryPoints, {
8
+ let deps;
9
+ if (webpackConfigPath) {
10
+ deps = (0, getDepsSetWebpack_1.getDepsSetWebpack)(entryPoints, webpackConfigPath, cwd);
11
+ }
12
+ else {
13
+ // dpdm does not support custom search directory :/
14
+ const oldProcessCwd = process.cwd;
15
+ process.cwd = () => cwd;
16
+ deps = (0, cleanupDpdmDeps_1.cleanupDpdmDeps)(await (0, dpdm_1.parseDependencyTree)(entryPoints, {
11
17
  context: cwd
12
18
  }));
19
+ process.cwd = oldProcessCwd;
20
+ }
13
21
  return deps;
14
22
  }
15
23
  exports.getDepsTree = getDepsTree;
@@ -9,6 +9,8 @@ const path_1 = __importDefault(require("path"));
9
9
  const promises_1 = __importDefault(require("fs/promises"));
10
10
  const utils_1 = require("./utils");
11
11
  const getDepsTree_1 = require("./getDepsTree");
12
+ const ignore_1 = __importDefault(require("ignore"));
13
+ const glob_escape_1 = __importDefault(require("glob-escape"));
12
14
  const getDirectoriesForEntryPointsSearch = async (dir) => {
13
15
  const entries = await promises_1.default.readdir(dir);
14
16
  const directories = await (0, utils_1.asyncFilter)(entries, async (pathName) => {
@@ -25,7 +27,7 @@ const getDirectoriesForEntryPointsSearch = async (dir) => {
25
27
  ];
26
28
  };
27
29
  exports.getDirectoriesForEntryPointsSearch = getDirectoriesForEntryPointsSearch;
28
- const findEntryPointsInDepsTree = (deps, exclude = []) => {
30
+ const findEntryPointsInDepsTree = (deps, exclude = [], include = undefined) => {
29
31
  const referencedIds = new Set();
30
32
  Object.values(deps).forEach((entry) => {
31
33
  if (entry !== null) {
@@ -36,17 +38,35 @@ const findEntryPointsInDepsTree = (deps, exclude = []) => {
36
38
  .filter((id) => /\.(ts|tsx|mjs|js|jsx)$/.test(id) &&
37
39
  !/node_modules/.test(id) &&
38
40
  !referencedIds.has(id))
39
- .filter((id) => exclude.reduce((result, pattern) => result && !(0, minimatch_1.default)(id, pattern), true));
41
+ .filter((id) => exclude.reduce((result, pattern) => result && !(0, minimatch_1.default)(id, pattern), true))
42
+ .filter((id) => include
43
+ ? include.reduce((result, pattern) => result || (0, minimatch_1.default)(id, pattern), false)
44
+ : true)
45
+ .sort();
40
46
  };
41
47
  exports.findEntryPointsInDepsTree = findEntryPointsInDepsTree;
42
- const getEntryPoints = async ({ cwd, exclude, webpackConfigPath }) => {
48
+ const getEntryPoints = async ({ cwd, exclude, include, webpackConfigPath }) => {
43
49
  const dirs = await (0, exports.getDirectoriesForEntryPointsSearch)(cwd);
44
50
  const globs = dirs
45
51
  .map((dirName) => path_1.default.relative(cwd, dirName))
46
- .map((dirName) => `${dirName}/*`);
52
+ .map((dirName) => `${(0, glob_escape_1.default)(dirName)}/*`);
47
53
  const globsWithRoot = ['*', ...globs];
48
54
  const depsTree = await (0, getDepsTree_1.getDepsTree)(cwd, globsWithRoot, webpackConfigPath);
49
- const possibleEntryPoints = (0, exports.findEntryPointsInDepsTree)(depsTree, exclude);
50
- return [possibleEntryPoints, depsTree];
55
+ const possibleEntryPoints = (0, exports.findEntryPointsInDepsTree)(depsTree, exclude, include);
56
+ const ignoreInstance = (0, ignore_1.default)();
57
+ let gitignore = '';
58
+ try {
59
+ gitignore = (await promises_1.default.readFile(path_1.default.join(cwd, '.gitignore'))).toString();
60
+ const lines = gitignore.split('\n');
61
+ const nonCommentedNonEmptyLines = lines
62
+ .filter((line) => !/^(\s*)#/.test(line))
63
+ .filter((line) => !/^(\s*)$/.test(line));
64
+ gitignore = nonCommentedNonEmptyLines.join('\n');
65
+ }
66
+ catch (e) {
67
+ e;
68
+ }
69
+ ignoreInstance.add(gitignore);
70
+ return [ignoreInstance.filter(possibleEntryPoints), depsTree];
51
71
  };
52
72
  exports.getEntryPoints = getEntryPoints;
package/dist/lib/utils.js CHANGED
@@ -3,8 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.sanitizeUserEntryPoints = exports.asyncFilter = exports.createResolveAbsolutePath = exports.removeInitialDot = void 0;
6
+ exports.findTsConfig = exports.resolvePath = exports.sanitizeUserEntryPoints = exports.asyncFilter = exports.createResolveAbsolutePath = exports.removeInitialDot = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
+ const fs_1 = __importDefault(require("fs"));
8
9
  const glob_escape_1 = __importDefault(require("glob-escape"));
9
10
  const removeInitialDot = (path) => path.replace(/^\.\//, '');
10
11
  exports.removeInitialDot = removeInitialDot;
@@ -20,3 +21,24 @@ const sanitizeUserEntryPoints = (entryPoints) => {
20
21
  return globEscapedEntryPoints;
21
22
  };
22
23
  exports.sanitizeUserEntryPoints = sanitizeUserEntryPoints;
24
+ const resolvePath = (p) => {
25
+ if (!p || path_1.default.isAbsolute(p)) {
26
+ return p;
27
+ }
28
+ return path_1.default.resolve(p);
29
+ };
30
+ exports.resolvePath = resolvePath;
31
+ const findTsConfig = (cwd = process.cwd()) => {
32
+ try {
33
+ const tsconfig = path_1.default.join(cwd, 'tsconfig.json');
34
+ const stat = fs_1.default.statSync(tsconfig);
35
+ if (stat.isFile()) {
36
+ return tsconfig;
37
+ }
38
+ }
39
+ catch {
40
+ /**/
41
+ }
42
+ return undefined;
43
+ };
44
+ exports.findTsConfig = findTsConfig;
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "rev-dep",
3
- "version": "1.0.0-alpha.0",
3
+ "version": "1.0.0-alpha.3",
4
4
  "description": "Reverse dependency resolution tool built with dependency-cruiser",
5
5
  "main": "lib/find.js",
6
6
  "bin": "bin.js",
7
7
  "files": [
8
8
  "dist/**",
9
9
  "lib/**",
10
- "bin.js"
10
+ "bin.js",
11
+ "babel.js"
11
12
  ],
12
13
  "author": "Jakub Mazurek @jayu",
13
14
  "license": "MIT",
@@ -31,15 +32,21 @@
31
32
  "typecheck": "tsc --noEmit"
32
33
  },
33
34
  "dependencies": {
35
+ "@babel/parser": "^7.17.8",
36
+ "@babel/template": "^7.16.7",
34
37
  "@types/dedent": "^0.7.0",
38
+ "colorette": "^2.0.16",
35
39
  "commander": "^6.1.0",
36
40
  "dedent": "^0.7.0",
37
41
  "dependency-cruiser": "9.23.0",
38
42
  "dpdm": "^3.8.0",
39
43
  "glob-escape": "^0.0.2",
44
+ "ignore": "^5.2.0",
45
+ "is-builtin-module": "^3.1.0",
40
46
  "minimatch": "^5.0.1"
41
47
  },
42
48
  "devDependencies": {
49
+ "@babel/types": "^7.17.0",
43
50
  "@typescript-eslint/eslint-plugin": "^5.16.0",
44
51
  "@typescript-eslint/parser": "^5.16.0",
45
52
  "eslint": "^7.11.0",