| 'use strict'; | ||
| const MODULE_REQUIRE = 1 | ||
| /* built-in */ | ||
| , fs = require('fs') | ||
| , path = require('path') | ||
| /* NPM */ | ||
| /* in-package */ | ||
| ; | ||
| function depth_first(cwd, pathname, depth) { | ||
| if (!depth) depth = Number.POSITIVE_INFINITY; | ||
| let realPathname = null; | ||
| let p = path.join(cwd, pathname); | ||
| if (fs.existsSync(p)) { | ||
| realPathname = p | ||
| } | ||
| else if (--depth > 0) { | ||
| let names = fs.readdirSync(cwd); | ||
| for (let i = 0, p; !realPathname && i < names.length; i++) { | ||
| p = path.join(cwd, names[i]); | ||
| if (fs.statSync(p).isDirectory()) { | ||
| realPathname = depth_first(p, pathname, depth); | ||
| } | ||
| } | ||
| } | ||
| return realPathname; | ||
| } | ||
| function breadth_first(cwd, pathname, depth) { | ||
| if (!depth) depth = Number.POSITIVE_INFINITY; | ||
| let realPathname = null; | ||
| let dirnames = null, subdirnames = [ cwd ]; | ||
| do { | ||
| dirnames = subdirnames; | ||
| subdirnames = []; | ||
| for (let i = 0; !realPathname && i < dirnames.length; i++) { | ||
| let dirname = dirnames[i]; | ||
| let p = path.join(dirname, pathname); | ||
| if (fs.existsSync(p)) { | ||
| realPathname = p; | ||
| } | ||
| else { | ||
| let names = fs.readdirSync(dirname); | ||
| names.forEach(name => { | ||
| p = path.join(dirname, name); | ||
| if (fs.statSync(p).isDirectory()) { | ||
| subdirnames.push(p); | ||
| } | ||
| }); | ||
| } | ||
| } | ||
| } while(--depth > 0 && !realPathname && subdirnames.length > 0) | ||
| return realPathname; | ||
| } | ||
| module.exports = { depth_first, breadth_first }; |
+5
-0
@@ -5,2 +5,7 @@ # noda Change Log | ||
| ## [0.2.0] - Feb 1st, 2018 | ||
| * `noda.upResolve()` added. | ||
| * `noda.downResolve()` added. | ||
| ## [0.1.2] - 2017-11-20 | ||
@@ -7,0 +12,0 @@ |
+83
-23
@@ -14,11 +14,13 @@ /** | ||
| , util = require('util') | ||
| /* NPM */ | ||
| /* in-package */ | ||
| , findInDirectory = require('./lib/findInDirectory') | ||
| , getCallerFileName = require('./lib/getCallerFileName') | ||
| , getCallerPackageDir = require('./lib/getCallerPackageDir') | ||
| , getCallerDir = () => path.dirname(getCallerFileName(1)) | ||
| ; | ||
| /** | ||
@@ -49,9 +51,9 @@ * Return the package.json object of the package in which the caller is located. | ||
| let dirname = getCallerPackageDir(); | ||
| let pathname = path.join(dirname, subpath); | ||
| let pathname = path.join(dirname, subpath); | ||
| let ret; | ||
| if (resolveAsModule) { | ||
| ret = fs.existsSync(pathname) | ||
| || fs.existsSync(`${pathname}.js`) | ||
| ret = fs.existsSync(pathname) | ||
| || fs.existsSync(`${pathname}.js`) | ||
| || fs.existsSync(`${pathname}.json`) | ||
@@ -71,4 +73,4 @@ || fs.existsSync(path.join(pathname, 'index.js')) | ||
| * @param {string} subpath path relative to the homedir of current package | ||
| * @param {string} [encoding] | ||
| * @param {boolean} [nullIfNotFound] | ||
| * @param {string} [encoding] | ||
| * @param {boolean} [nullIfNotFound] | ||
| * @return {string|Buffer} | ||
@@ -96,4 +98,4 @@ */ | ||
| let dirname = getCallerPackageDir(); | ||
| let pathname = path.join(dirname, subpath); | ||
| let pathname = path.join(dirname, subpath); | ||
| let ret = null; | ||
@@ -114,12 +116,12 @@ if (!fs.existsSync(pathname)) { | ||
| * To require some sub module in same package with fixed subpath wherever the caller is located. | ||
| * | ||
| * | ||
| * @example | ||
| * // PACKAGE_HOMEDIR/lib/index.js | ||
| * | ||
| * | ||
| * // PACKAGE_HOMEDIR/foo.js | ||
| * noda.inRequire('lib'); | ||
| * | ||
| * | ||
| * // PACKAGE_HOMEDIR/foo/bar.js | ||
| * noda.inRequire('lib'); | ||
| * | ||
| * | ||
| * @param {string} subpath sub module's path relative to the home directory of the package in which the caller is located. | ||
@@ -147,3 +149,3 @@ */ | ||
| /** | ||
| * Resolve the subpath into an absolute path. | ||
| * Resolve the subpath into an absolute path. | ||
| * The subpath is relative to the home directory of the package in which the caller is located. | ||
@@ -161,7 +163,7 @@ * @param {string} subpath subpath relative to the home directory of the package in which the caller is located. | ||
| * Require module whose name is same with the name of current platform. | ||
| * @param {string} dirname | ||
| * @param {string} dirname | ||
| */ | ||
| let osRequire = (dirname) => { | ||
| if (!path.isAbsolute(dirname)) { | ||
| dirname = path.resolve(path.dirname(getCallerFileName()), dirname); | ||
| dirname = path.resolve(getCallerDir(), dirname); | ||
| } | ||
@@ -192,5 +194,5 @@ | ||
| if (!path.isAbsolute(dirname)) { | ||
| dirname = path.resolve(path.dirname(getCallerFileName()), dirname); | ||
| dirname = path.resolve(getCallerDir(), dirname); | ||
| } | ||
| // Uniform the argument "excludes". | ||
@@ -210,7 +212,7 @@ if (util.isUndefined(excludes)) { | ||
| let modname = null; | ||
| if (!excludes.includes['*'] && path.extname(name) === '.js') { | ||
| modname = name.replace(/\.js$/, ''); | ||
| } | ||
| else if (fs.statSync(pathname).isDirectory() | ||
| else if (fs.statSync(pathname).isDirectory() | ||
| && !excludes.includes('*/') | ||
@@ -236,2 +238,58 @@ && fs.existsSync(path.join(pathname, 'index.js'))) { | ||
| /** | ||
| * Find sub-directory or file in ascent directory and return the full path. | ||
| * @param {string} pathname relative pathname of sub-directory or file | ||
| * @return {string} | ||
| */ | ||
| let upResolve = (pathname) => { | ||
| let cwd = getCallerDir(); | ||
| let realPathname = null; | ||
| for (let d = null; d != cwd && !realPathname; cwd = path.dirname(cwd)) { | ||
| let p = path.join(cwd, pathname); | ||
| if (fs.existsSync(p)) realPathname = p; | ||
| else d = cwd; | ||
| } | ||
| return realPathname; | ||
| }; | ||
| /** | ||
| * Find sub-directory or file in descent directory and return the full path. | ||
| * @param {string} pathname - relative pathname of sub-directory or file | ||
| * @param {number} [depth=9] - max depth to search | ||
| * @param {string} [order=bfs] - DFS (Depth-First Search) or BFS (Breadth-First Search) | ||
| * @return {string} | ||
| */ | ||
| let downResolve = function(pathname) { | ||
| let depth = null, order = null; | ||
| for (let i = 1, arg; i < arguments.length; i++) { | ||
| switch (typeof arguments[i]) { | ||
| case 'number': | ||
| if (depth === null) depth = arguments[i]; | ||
| else throw new Error(`duplicated arguments: {number} depth`); | ||
| break; | ||
| case 'string': | ||
| if (order === null) order = arguments[i]; | ||
| else throw new Error(`duplicated arguments: {string} order`); | ||
| break; | ||
| default: | ||
| if (!util.isUndefined(arguments[i]) && arguments[i] !== null) { | ||
| throw new Error(`unrecognized argument: ${arguments[i]}`); | ||
| } | ||
| } | ||
| } | ||
| if (depth === null) depth = 9; | ||
| if (order === null) order = 'bfs'; | ||
| order = order.toLowerCase(); | ||
| let cwd = getCallerDir(); | ||
| if (order == 'dfs') { | ||
| return findInDirectory.depth_first(cwd, pathname, depth); | ||
| } | ||
| if (order == 'bfs') { | ||
| return findInDirectory.breadth_first(cwd, pathname, depth); | ||
| } | ||
| throw new Error(`invalid order: ${order}`); | ||
| }; | ||
| module.exports = { | ||
@@ -246,2 +304,4 @@ currentPackage, | ||
| requireDir, | ||
| upResolve, | ||
| downResolve, | ||
| 'existsInPackage': inExists, | ||
@@ -248,0 +308,0 @@ 'readInPackage': inRead, |
+4
-1
| { | ||
| "name": "noda", | ||
| "version": "0.1.2", | ||
| "version": "0.2.0", | ||
| "description": "NOde Developing Assistant", | ||
@@ -19,2 +19,5 @@ "main": "index.js", | ||
| }, | ||
| "engines": { | ||
| "node": ">=6" | ||
| }, | ||
| "license": "ISC", | ||
@@ -21,0 +24,0 @@ "bin": {}, |
+24
-28
| # noda | ||
| __NOde Developing Assistant__ | ||
| __noda__ is a very lower-level package which will help you easily accessing files and directories in your package. | ||
| ## Table of contents | ||
@@ -9,6 +11,2 @@ | ||
| * [Examples](#examples) | ||
| * [Why noda](#why-noda) | ||
| * [Honorable Dependents](#honorable-dependents) | ||
| * [About](#about) | ||
| * [References](#references) | ||
@@ -39,3 +37,3 @@ ## Links | ||
| Before read APIs, please understand that | ||
| Before read APIs, please understand that | ||
| 1. The phrase "current package" refers to the NPM package which contains the nodejs file where code `noda.*` located. | ||
@@ -47,40 +45,46 @@ 2. Parameter `subpath` refers to pathname relative to the basepath of "current package". | ||
| * __noda.inExists__(*string* subpath, *boolean* resolveAsModule) | ||
| Judge whether file or directory exists. If __resolveAsModule__ set `true`, __subpath__ will be tentatively regarded as JS/JSON module path in the current package when the exact file not exists. | ||
| * __noda.inExists__(string *subpath*, boolean *resolveAsModule*) | ||
| Judge whether file or directory exists. If __resolveAsModule__ set `true`, __subpath__ will be tentatively regarded as JS/JSON module path in the current package when the exact file not exists. | ||
| This method is __synchronuous__. | ||
| * __noda.inRead__(*string* subpath [, *string* encoding, *boolean* nullIfNotFound ]) | ||
| * __noda.inRead__(string *subpath* [, string *encoding*, boolean *nullIfNotFound* ]) | ||
| Read content of file. | ||
| * __noda.inRequire__(*string* subpath) | ||
| * __noda.inRequire__(string *subpath*) | ||
| Require js or json. | ||
| * __noda.inRequireDir__(*string* dirname, *Array* | *string* ignores) | ||
| Based on requireDir(), but the dirname is regarded as relative path to home directory of the package in which the caller is located. | ||
| * __noda.inRequireDir__(string *dirname*, Array | string *ignores*) | ||
| Based on requireDir(), but the dirname is regarded as relative path to home directory of the package in which the caller is located. | ||
| __ignores__ includes those that SHOULD NOT be required. If `'*/'` contained in __ignores__, all sub directories will not be required whether or not *index.js* exists in the sub directories. If `'*'` contained in __ignores__, all .js files will not be required. | ||
| * __noda.inResolve__(*string* subpath) | ||
| * __noda.inResolve__(string *subpath*) | ||
| Resolve the subpath into an absolute path. | ||
| * __noda.osRequire__(*string* dirname) | ||
| * __noda.osRequire__(string *dirname*) | ||
| Require module whose name is same with the name of current platform. Relative __dirname__ is acceptable. | ||
| * __noda.requireDir__(*string* dirname, *Array* | *string* ignores) | ||
| * __noda.requireDir__(string *dirname*, Array | string *ignores*) | ||
| Read the directory and require all javascript modules except those excluded, and returned them in an object with keys equal to modules' name. Relative __dirname__ is acceptable. | ||
| ATTENTION:__Directory "node_modules" is always ignored whether or not it is explictly added in `ignores`.__ | ||
| * __noda.upResolve__(string *pathname*) | ||
| Find sub-directory or file in ascent directory and return the full path. | ||
| * __noda.existsInPackage__ | ||
| * __noda.downResolve__(string *pathname* [, number *depth*, string *order* ]) | ||
| Find sub-directory or file in descent directory and return the full path. | ||
| The value of *order* may be `DFS` (means depth-first search) or `BFS` (means breadth-first search). | ||
| * __noda.existsInPackage__ | ||
| Alias of `noda.inExists`. | ||
| * __noda.readInPackage__ | ||
| * __noda.readInPackage__ | ||
| Alias of `noda.inRead`. | ||
| * __noda.requireInPackage__ | ||
| * __noda.requireInPackage__ | ||
| Alias of `noda.inRequire`. | ||
| * __noda.requireDirInPackage__ | ||
| * __noda.requireDirInPackage__ | ||
| Alias of `noda.inRequireDir`. | ||
| * __noda.resolveInPackage__ | ||
| * __noda.resolveInPackage__ | ||
| Alias of `noda.inResolve`. | ||
@@ -118,9 +122,1 @@ | ||
| ``` | ||
| ## Why *noda* | ||
| ## Honorable Dependents | ||
| ## About | ||
| ## References |
AI-detected possible typosquat
Supply chain riskAI has identified this package as a potential typosquat of a more popular package. This suggests that the package may be intentionally mimicking another package's name, description, or other metadata.
17255
28.46%8
14.29%361
42.69%0
-100%119
-3.25%7
16.67%