diff --git a/README.md b/README.md index 09837da..db057d8 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,17 @@ lodash └── 3.10.1 ``` +## Usage in node +Each function can also receive optional CWD and optional Options (deps, match) +```js +import * as qnm from 'qnm' +qnm.match('module') +qnm.get('module') +qnm.list() +qnm.search() +``` + + Which means you have 3 occurrences of lodash in your `node_modules`: 1. `./node_module/lodash` @@ -132,7 +143,7 @@ eslint-plugin-react ``` ### homepage -Opens package "homepage" property in your browser. +Opens package "homepage" property in your browser. ### install-completions diff --git a/package.json b/package.json index f664451..119b2c8 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,8 @@ "name": "qnm", "version": "1.8.1", "description": "cli utility for querying the node_modules directory", + "main": "build/main.js", + "module": "src/main.ts", "bin": "bin/qnm.js", "repository": "ranyitz/qnm", "engines": { @@ -24,7 +26,8 @@ "lint": "eslint .", "watch": "newsh --split 'yarn tsc --watch' && yarn pkg --watch", "pkg": "ncc build build/cli.js -o dist --external tabtab", - "build": "yarn tsc && yarn pkg", + "build": "yarn clean && yarn tsc && yarn pkg", + "clean": "rm -rf build/ dist/", "test:watch": "jest --watch", "createVersion": "np" }, diff --git a/src/__tests__/__snapshots__/main.spec.ts.snap b/src/__tests__/__snapshots__/main.spec.ts.snap new file mode 100644 index 0000000..41faad5 --- /dev/null +++ b/src/__tests__/__snapshots__/main.spec.ts.snap @@ -0,0 +1,82 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Node API qnm ] should add dependents information on yarn installed package 1`] = ` +"import-from +└── ]8;;File:/Users/deansh/Projects/qnm/src/__tests__/fixtures/yarn-install/node_modules/import-from/package.json3.0.0]8;; (import-cwd) +" +`; + +exports[`Node API qnm ] should show an indication in case there is a symlink 1`] = ` +"test +└── ]8;;File:/Users/deansh/Projects/qnm/src/__tests__/fixtures/symlink/node_modules/test/package.json1.0.0]8;; -> ../../symlink-origin/node_modules/test (devDependencies, npm install test) +" +`; + +exports[`Node API qnm ] should show get matches when using the match command 1`] = ` +"test +└── ]8;;File:/Users/deansh/Projects/qnm/src/__tests__/fixtures/single-module/node_modules/test/package.json1.0.0]8;; (devDependencies, npm install test) +" +`; + +exports[`Node API qnm ] should show the version and dependents info on a single module when called with a string 1`] = ` +"test +└── ]8;;File:/Users/deansh/Projects/qnm/src/__tests__/fixtures/single-module/node_modules/test/package.json1.0.0]8;; (devDependencies, npm install test) +" +`; + +exports[`Node API qnm ] should work in monorepo and print subpackages modules 1`] = ` +"package-foo +└── ]8;;File:/Users/deansh/Projects/qnm/src/__tests__/fixtures/monorepo/node_modules/package-foo/package.json1.0.0]8;; +" +`; + +exports[`Node API qnm ] should work in monorepo with yarn workspaces 1`] = ` +"package-foo +└── ]8;;File:/Users/deansh/Projects/qnm/src/__tests__/fixtures/monorepo-with-workspaces/node_modules/package-foo/package.json1.0.0]8;; +" +`; + +exports[`Node API qnm list should list a monorepo 1`] = `""`; + +exports[`Node API qnm list should list dependencies in a yarn installed package and show "why" information 1`] = `""`; + +exports[`Node API qnm list should show all modules in node_modules directory 1`] = ` +"@scope/test +└── ]8;;File:/Users/deansh/Projects/qnm/src/__tests__/fixtures/mix-modules/node_modules/@scope/test/package.json1.0.0]8;; + +another +└── ]8;;File:/Users/deansh/Projects/qnm/src/__tests__/fixtures/mix-modules/node_modules/another/package.json1.0.0]8;; + +test +├── ]8;;File:/Users/deansh/Projects/qnm/src/__tests__/fixtures/mix-modules/node_modules/test/package.json1.0.0]8;; +└─┬ another + └── ]8;;File:/Users/deansh/Projects/qnm/src/__tests__/fixtures/mix-modules/node_modules/another/node_modules/test/package.json1.0.0]8;; +" +`; + +exports[`Node API qnm list should show modules mentioned in package.json 1`] = ` +"dependency1 +└── ]8;;File:/Users/deansh/Projects/qnm/src/__tests__/fixtures/indirect-dependencies/node_modules/dependency1/package.json1.0.0]8;; + +dependency2 +└── ]8;;File:/Users/deansh/Projects/qnm/src/__tests__/fixtures/indirect-dependencies/node_modules/dependency2/package.json1.0.0]8;; + +devDependency1 +└── ]8;;File:/Users/deansh/Projects/qnm/src/__tests__/fixtures/indirect-dependencies/node_modules/devDependency1/package.json1.0.0]8;; + +devDependency2 +└── ]8;;File:/Users/deansh/Projects/qnm/src/__tests__/fixtures/indirect-dependencies/node_modules/devDependency2/package.json1.0.0]8;; +" +`; + +exports[`Node API qnm match should match in monorepo and print subpackages modules 1`] = ` +"package-bar +└── ]8;;File:/Users/deansh/Projects/qnm/src/__tests__/fixtures/monorepo/node_modules/package-bar/package.json1.0.0]8;; + +package-baz +└── ]8;;File:/Users/deansh/Projects/qnm/src/__tests__/fixtures/monorepo/node_modules/package-baz/package.json1.0.0]8;; + +package-foo +└── ]8;;File:/Users/deansh/Projects/qnm/src/__tests__/fixtures/monorepo/node_modules/package-foo/package.json1.0.0]8;; +" +`; diff --git a/src/__tests__/main.spec.ts b/src/__tests__/main.spec.ts new file mode 100644 index 0000000..4264af3 --- /dev/null +++ b/src/__tests__/main.spec.ts @@ -0,0 +1,97 @@ +import * as qnm from '../main'; +import { resolveFixture } from './utils'; + +describe('Node API', () => { + describe('qnm ]', () => { + it('should show the version and dependents info on a single module when called with a string', () => { + const cwd = resolveFixture('single-module'); + const output = qnm.match('test', cwd); + + expect(output).toMatchSnapshot(); + }); + + it('should show get matches when using the match command', () => { + const cwd = resolveFixture('single-module'); + const output = qnm.match('te', cwd); + + expect(output).toMatchSnapshot(); + }); + + it('should add dependents information on yarn installed package', () => { + const cwd = resolveFixture('yarn-install'); + const output = qnm.match('import-from', cwd); + + expect(output).toMatchSnapshot(); + }); + + it('should show an indication in case there is a symlink', () => { + const cwd = resolveFixture('symlink'); + const output = qnm.match('test', cwd); + + expect(output).toMatchSnapshot(); + }); + + it('should work in monorepo and print subpackages modules', () => { + const cwd = resolveFixture('monorepo'); + const output = qnm.match('package-foo', cwd); + + expect(output).toMatchSnapshot(); + }); + + it('should work in monorepo with yarn workspaces', () => { + const cwd = resolveFixture('monorepo-with-workspaces'); + const output = qnm.match('package-foo', cwd); + + expect(output).toMatchSnapshot(); + }); + + it('should provide suggestion for scoped package with the same name', () => { + const cwd = resolveFixture('scoped-package'); + + try { + qnm.match('test', cwd); + } catch (error) { + expect(error.message).toMatch('Did you mean "@scope/test"'); + } + }); + }); + + describe('qnm list', () => { + it('should show all modules in node_modules directory', () => { + const cwd = resolveFixture('mix-modules'); + const output = qnm.list(cwd); + + expect(output).toMatchSnapshot(); + }); + + it('should show modules mentioned in package.json', () => { + const cwd = resolveFixture('indirect-dependencies'); + const output = qnm.list(cwd, { deps: true }); + + expect(output).toMatchSnapshot(); + }); + + it('should list dependencies in a yarn installed package and show "why" information', () => { + const cwd = resolveFixture('yarn-install'); + const output = qnm.list(cwd); + + expect(output).toMatchSnapshot(); + }); + + it('should list a monorepo', () => { + const cwd = resolveFixture('monorepo'); + const output = qnm.list(cwd); + + expect(output).toMatchSnapshot(); + }); + }); + + describe('qnm match', () => { + it('should match in monorepo and print subpackages modules', () => { + const cwd = resolveFixture('monorepo'); + const output = qnm.match('packa', cwd); + + expect(output).toMatchSnapshot(); + }); + }); +}); diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..a378397 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,38 @@ +import merge from 'lodash/merge'; +import Workspace from './workspace/workspace'; +import { CliOptions } from './cli'; + +import matchAction from './actions/match'; +import getAction from './actions/get'; +import listAction from './actions/list'; +import fuzzySearchAction from './actions/fuzzy-search'; + +type Options = Pick; + +const defaultOptions = { + noColor: true, +}; + +export function match(matchPattern: string, cwd?: string, options?: Options) { + const workspace = Workspace.loadSync(cwd); + + return matchAction(workspace, matchPattern, merge(defaultOptions, options)); +} + +export function get(name: string, cwd?: string, options?: Options) { + const workspace = Workspace.loadSync(cwd); + + return getAction(workspace, name, merge(defaultOptions, options)); +} + +export function list(cwd?: string, options?: Options) { + const workspace = Workspace.loadSync(cwd); + + return listAction(workspace, merge(defaultOptions, options)); +} + +export function search(cwd?: string, options: Options = {}) { + const workspace = Workspace.loadSync(cwd); + + return fuzzySearchAction(workspace, merge(defaultOptions, options)); +} diff --git a/tsconfig.json b/tsconfig.json index 504eb60..0611ab2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,6 +7,7 @@ "outDir": "build", "sourceMap": true, "strict": true, + "declaration": true, /* Additional Checks */ "noUnusedLocals": false,