Skip to content

feat: add noTypeDefinitions option #130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ var tree = dependencyTree({
entry: 'module'
}, // optional
filter: path => path.indexOf('node_modules') === -1, // optional
nonExistent: [] // optional
nonExistent: [], // optional
noTypeDefinitions: false // optional
});

// Returns a post-order traversal (list form) of the tree with duplicate sub-trees pruned.
Expand All @@ -51,6 +52,7 @@ var list = dependencyTree.toList({
* `detective`: object with configuration specific to detectives used to find dependencies of a file
- for example `detective.amd.skipLazyLoaded: true` tells the AMD detective to omit inner requires
- See [precinct's usage docs](https://github.com/dependents/node-precinct#usage) for the list of module types you can pass options to.
* `noTypeDefinitions`: For TypeScript imports, whether to resolve to `*.js` instead of `*.d.ts`.

#### Format Details

Expand Down
32 changes: 32 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
declare namespace dependencyTree {
interface TreeInnerNode {
[parent: string]: TreeInnerNode | string;
}
type Tree = TreeInnerNode | string;

interface Options {
filename: string;
directory: string;
visited?: Tree;
nonExistent?: string[];
isListForm?: boolean;
requireConfig?: string;
webpackConfig?: string;
nodeModulesConfig?: any;
detectiveConfig?: any;
tsConfig?: string | Record<string, any>;
noTypeDefinitions?: boolean;
filter?: (path: string) => boolean;
}

interface Config extends Options {
clone: () => Config;
}

function toList (options: Options): string[];
function _getDependencies (config: Config): string[];
}

declare function dependencyTree (options: dependencyTree.Options): dependencyTree.Tree;

export = dependencyTree;
4 changes: 3 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const Config = require('./lib/Config');
* @param {Array} [options.nonExistent] - List of partials that do not exist
* @param {Boolean} [options.isListForm=false]
* @param {String|Object} [options.tsConfig] Path to a typescript config (or a preloaded one).
* @param {Boolean} [options.noTypeDefinitions] For TypeScript imports, whether to resolve to `*.js` instead of `*.d.ts`.
* @return {Object}
*/
module.exports = function(options) {
Expand Down Expand Up @@ -109,7 +110,8 @@ module.exports._getDependencies = function(config) {
config: config.requireConfig,
webpackConfig: config.webpackConfig,
nodeModulesConfig: config.nodeModulesConfig,
tsConfig: config.tsConfig
tsConfig: config.tsConfig,
noTypeDefinitions: config.noTypeDefinitions
});

if (!result) {
Expand Down
1 change: 1 addition & 0 deletions lib/Config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class Config {
this.nodeModulesConfig = options.nodeModulesConfig;
this.detectiveConfig = options.detective || options.detectiveConfig || {};
this.tsConfig = options.tsConfig;
this.noTypeDefinitions = options.noTypeDefinitions;

this.filter = options.filter;

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "8.0.0",
"description": "Get the dependency tree of a module",
"main": "index.js",
"types": "index.d.ts",
"scripts": {
"test": "jscs index.js test/test.js && ./node_modules/.bin/mocha --require esm test/test.js"
},
Expand Down
1 change: 1 addition & 0 deletions test/example/noTypeDefinitions/entrypoint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import { theAnswer } from './required';
1 change: 1 addition & 0 deletions test/example/noTypeDefinitions/required.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const theAnswer: number;
3 changes: 3 additions & 0 deletions test/example/noTypeDefinitions/required.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
theAnswer: 42
};
36 changes: 36 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,16 @@ describe('dependencyTree', function() {
assert(tree.length === 3);
});

it('resolves TypeScript imports to their type definition files by default', function() {
const directory = path.join(__dirname, 'example', 'noTypeDefinitions');
const filename = path.join(directory, 'entrypoint.ts');

const list = dependencyTree.toList({filename, directory});

assert(list.includes(path.join(directory, 'required.d.ts')));
assert(!list.includes(path.join(directory, 'required.js')));
});

describe('when given a detective configuration', function() {
it('passes it through to precinct', function() {
const spy = sinon.spy(precinct, 'paperwork');
Expand Down Expand Up @@ -903,6 +913,32 @@ describe('dependencyTree', function() {
});
});

describe('when noTypeDefinitions is set', function() {
describe('and it is set to false', function() {
it('resolves TypeScript imports to their definition files', function() {
const directory = path.join(__dirname, 'example', 'noTypeDefinitions');
const filename = path.join(directory, 'entrypoint.ts');

const list = dependencyTree.toList({filename, directory, noTypeDefinitions: false});

assert(list.includes(path.join(directory, 'required.d.ts')));
assert(!list.includes(path.join(directory, 'required.js')));
});
});

describe('and it is set to true', function() {
it('resolves TypeScript imports to their JavaScript implementation files', function() {
const directory = path.join(__dirname, 'example', 'noTypeDefinitions');
const filename = path.join(directory, 'entrypoint.ts');

const list = dependencyTree.toList({filename, directory, noTypeDefinitions: true});

assert(list.includes(path.join(directory, 'required.js')));
assert(!list.includes(path.join(directory, 'required.d.ts')));
});
});
});

describe('Config', function() {
describe('when given a path to a typescript config', function() {
it('pre-parses the config for performance', function() {
Expand Down