Comparing version 0.4.4 to 1.0.0
286
index.js
'use strict'; | ||
var path = require('path'); | ||
var fs = require('fs'); | ||
var rimraf = require('rimraf'); | ||
var mkdirp = require('mkdirp'); | ||
var assign = require('object-assign'); | ||
var forEach = require('each-async'); | ||
var series = require('array-series'); | ||
var pathIsAbsolute = require('path-is-absolute'); | ||
const path = require('path'); | ||
const arrify = require('arrify'); | ||
const rimraf = require('rimraf'); | ||
const mkdirp = require('mkdirp'); | ||
const pathIsAbsolute = require('path-is-absolute'); | ||
const pify = require('pify'); | ||
var link = require('./link'); | ||
const link = require('./link'); | ||
var defaults = { | ||
cwd: undefined, | ||
type: 'default', // 'hard', 'symbolic', 'dir', 'junction' or 'default' | ||
parents: false, | ||
force: false, | ||
log: function noop() {}, | ||
var fsStatP = pify(fs.stat); | ||
const rimrafP = pify(rimraf); | ||
const mkdirpP = pify(mkdirp); | ||
const defaults = { | ||
cwd: undefined, | ||
type: 'default', // 'hard', 'symbolic', 'dir', 'junction' or 'default' | ||
parents: false, | ||
force: false, | ||
log: () => {} | ||
}; | ||
function preprocessTarget(target, opts) { | ||
// NB symlinks: do not use path.resolve here | ||
if (!pathIsAbsolute(target) && opts.cwd) { | ||
target = path.join(opts.cwd, target); | ||
} | ||
return target; | ||
} | ||
const preprocessTarget = (target, opts) => { | ||
// NB symlinks: do not use path.resolve here | ||
if (opts.cwd && !pathIsAbsolute(target)) { | ||
target = path.join(opts.cwd, target); | ||
} | ||
return target; | ||
}; | ||
function generateLinkPath(target, directory, opts) { | ||
var basename = path.basename(target); | ||
var dirname = path.dirname(target); | ||
const generateLinkPath = (target, directory, opts) => { | ||
const basename = path.basename(target); | ||
const dirname = path.dirname(target); | ||
if (opts.cwd) { | ||
directory = path.resolve(opts.cwd, directory); | ||
} | ||
if (opts.cwd) { | ||
directory = path.resolve(opts.cwd, directory); | ||
} | ||
if (opts.parents) { | ||
return path.join(directory, dirname, basename); | ||
} else { | ||
return path.join(directory, basename); | ||
} | ||
} | ||
if (opts.parents) { | ||
return path.join(directory, dirname, basename); | ||
} | ||
function assertSaveOverwrite(target, directory, cb) { | ||
fs.stat(target, function targetStatCb(targetErr, targetStat) { | ||
if (targetErr) { | ||
if (targetErr.code === 'ENOENT' || targetErr.code === 'ELOOP') { | ||
// target and directory cannot be same file | ||
return cb(); | ||
} | ||
return cb(targetErr); | ||
} | ||
fs.stat(directory, function directoryStatCb(dirErr, linkStat) { | ||
if (dirErr) { | ||
if (dirErr.code === 'ENOENT' || dirErr.code === 'ELOOP') { | ||
return cb(); | ||
} | ||
return cb(dirErr); | ||
} | ||
if (targetStat.ino === linkStat.ino && | ||
targetStat.dev === linkStat.dev) { | ||
cb(new Error('`' + target + '` and `' + directory + '` are the same')); | ||
} else { | ||
cb(); | ||
} | ||
}); | ||
}); | ||
} | ||
return path.join(directory, basename); | ||
}; | ||
function assertSaveOverwriteSync(target, directory) { | ||
var targetStat; | ||
var linkStat; | ||
try { | ||
targetStat = fs.statSync(target); | ||
} catch (err) { | ||
if (err.code === 'ENOENT' || err.code === 'ELOOP') { | ||
// target and directory cannot be same file | ||
return; | ||
} | ||
throw err; | ||
} | ||
try { | ||
linkStat = fs.statSync(directory); | ||
} catch (err) { | ||
if (err.code === 'ENOENT' || err.code === 'ELOOP') { | ||
return; | ||
} | ||
throw err; | ||
} | ||
if (targetStat.ino === linkStat.ino && | ||
targetStat.dev === linkStat.dev) { | ||
throw new Error('`' + target + '` and `' + directory + '` are the same'); | ||
} | ||
} | ||
const assertSaveOverwrite = (target, linkPath) => Promise | ||
.all([fsStatP(target), fsStatP(linkPath)]) | ||
.then(stats => { | ||
const targetStat = stats[0]; | ||
const linkStat = stats[1]; | ||
function assertArgument(arg, argName) { | ||
if (!arg) { | ||
throw new Error(argName + ' required'); | ||
} | ||
} | ||
if (targetStat.ino === linkStat.ino && targetStat.dev === linkStat.dev) { | ||
throw new Error(`${target} and ${linkPath} are the same`); | ||
} | ||
}) | ||
.catch(err => { | ||
if (err.code === 'ENOENT' || err.code === 'ELOOP') { | ||
// target and linkPath cannot be same file | ||
return; | ||
} | ||
module.exports = function lnk(targets, directory, opts, cb) { | ||
var linkFn; | ||
if (typeof opts === 'function') { | ||
cb = opts; | ||
opts = {}; | ||
} | ||
throw err; | ||
}); | ||
assertArgument(targets, 'targets'); | ||
assertArgument(directory, 'directory'); | ||
assertArgument(cb, 'cb'); | ||
const assertSaveOverwriteSync = (target, linkPath) => { | ||
try { | ||
const targetStat = fs.statSync(target); | ||
const linkStat = fs.statSync(linkPath); | ||
targets = Array.isArray(targets) ? targets : [targets]; | ||
opts = assign({}, defaults, opts); | ||
linkFn = link.get(opts.type); | ||
if (targetStat.ino === linkStat.ino && targetStat.dev === linkStat.dev) { | ||
throw new Error(`${target} and ${linkPath} are the same`); | ||
} | ||
} catch (err) { | ||
if (err.code === 'ENOENT' || err.code === 'ELOOP') { | ||
// target and linkPath cannot be same file | ||
return; | ||
} | ||
function logLnk(level, linkPath, targetPath, done) { | ||
opts.log(level, 'lnk', '%j => %j', linkPath, targetPath); | ||
done(); | ||
} | ||
throw err; | ||
} | ||
}; | ||
function linkTarget(target, i, done) { | ||
var targetPath = preprocessTarget(target, opts); | ||
var linkPath = generateLinkPath(target, directory, opts); | ||
const assertArgument = (arg, argName) => { | ||
if (!arg) { | ||
throw new Error(argName + ' required'); | ||
} | ||
}; | ||
series([ | ||
mkdirp.bind(mkdirp, path.dirname(linkPath)), | ||
logLnk.bind(null, 'verbose', linkPath, targetPath), | ||
function(next) { | ||
linkFn(targetPath, linkPath, function(err) { | ||
if (err && err.code === 'EEXIST' && opts.force) { | ||
opts.log('silly', 'lnk', 'try to rm -rf %s', linkPath); | ||
series([ | ||
assertSaveOverwrite.bind(null, targetPath, linkPath), | ||
rimraf.bind(rimraf, linkPath), | ||
logLnk.bind(null, 'silly', linkPath, targetPath), | ||
linkFn.bind(linkFn, targetPath, linkPath), | ||
], next); | ||
} else { | ||
next(err); | ||
} | ||
}); | ||
}, | ||
], done); | ||
} | ||
const lnk = (targets, directory, opts) => { | ||
opts = Object.assign({}, defaults, opts); | ||
logLnk('silly', targets, directory, function() {}); | ||
forEach(targets, linkTarget, cb); | ||
const linkTarget = target => { | ||
const linkFn = link.get(opts.type); | ||
const targetPath = preprocessTarget(target, opts); | ||
const linkPath = generateLinkPath(target, directory, opts); | ||
return mkdirpP(path.dirname(linkPath)) | ||
.then(() => opts.log('verbose', 'lnk', '%j => %j', linkPath, targetPath)) | ||
.then(() => linkFn(targetPath, linkPath) | ||
.catch(err => { | ||
if (err.code !== 'EEXIST' || !opts.force) { | ||
throw err; | ||
} | ||
return Promise.resolve() | ||
.then(() => opts.log('silly', 'lnk', 'try to rm -rf %s', linkPath)) | ||
.then(() => assertSaveOverwrite(targetPath, linkPath)) | ||
.then(() => rimrafP(linkPath)) | ||
.then(() => opts.log('silly', 'lnk', '%j => %j', linkPath, targetPath)) | ||
.then(() => linkFn(targetPath, linkPath)); | ||
})); | ||
}; | ||
return Promise.resolve() | ||
.then(() => assertArgument(targets, 'targets')) | ||
.then(() => assertArgument(directory, 'directory')) | ||
.then(() => opts.log('silly', 'lnk', '%j => %j', targets, directory)) | ||
.then(() => Promise.all(arrify(targets).map(linkTarget))); | ||
}; | ||
module.exports.sync = function lnkSync(targets, directory, opts) { | ||
var linkFn; | ||
const lnkSync = (targets, directory, opts) => { | ||
opts = Object.assign({}, defaults, opts); | ||
assertArgument(targets, 'targets'); | ||
assertArgument(directory, 'directory'); | ||
const linkTarget = target => { | ||
const linkFn = link.getSync(opts.type); | ||
const targetPath = preprocessTarget(target, opts); | ||
const linkPath = generateLinkPath(target, directory, opts); | ||
targets = Array.isArray(targets) ? targets : [targets]; | ||
opts = assign({}, defaults, opts); | ||
linkFn = link.getSync(opts.type); | ||
mkdirp.sync(path.dirname(linkPath)); | ||
function linkTarget(target) { | ||
var targetPath = preprocessTarget(target, opts); | ||
var linkPath = generateLinkPath(target, directory, opts); | ||
try { | ||
opts.log('verbose', 'lnk', '%j => %j', linkPath, targetPath); | ||
linkFn(targetPath, linkPath); | ||
} catch (err) { | ||
if (err.code !== 'EEXIST' || !opts.force) { | ||
throw err; | ||
} | ||
mkdirp.sync(path.dirname(linkPath)); | ||
try { | ||
opts.log('verbose', 'lnk', '%j => %j', linkPath, targetPath); | ||
linkFn(targetPath, linkPath); | ||
} catch (err) { | ||
if (err.code === 'EEXIST' && opts.force) { | ||
opts.log('silly', 'lnk', 'try to rm -rf %s', linkPath); | ||
assertSaveOverwriteSync(targetPath, linkPath); | ||
rimraf.sync(linkPath); | ||
opts.log('silly', 'lnk', '%j => %j', linkPath, targetPath); | ||
linkFn(targetPath, linkPath); | ||
} else { | ||
throw err; | ||
} | ||
} | ||
} | ||
opts.log('silly', 'lnk', 'try to rm -rf %s', linkPath); | ||
assertSaveOverwriteSync(targetPath, linkPath); | ||
rimraf.sync(linkPath); | ||
opts.log('silly', 'lnk', '%j => %j', linkPath, targetPath); | ||
linkFn(targetPath, linkPath); | ||
} | ||
}; | ||
opts.log('silly', 'lnk', '%j => %j', targets, directory); | ||
targets.forEach(linkTarget); | ||
assertArgument(targets, 'targets'); | ||
assertArgument(directory, 'directory'); | ||
opts.log('silly', 'lnk', '%j => %j', targets, directory); | ||
arrify(targets).forEach(linkTarget); | ||
}; | ||
module.exports = lnk; | ||
module.exports.sync = lnkSync; | ||
module.exports.getTypes = () => link.getTypes(); |
142
link.js
'use strict'; | ||
var isWin = process.platform === 'win32'; | ||
var fs = require('fs'); | ||
var pathLib = require('path'); | ||
const pathLib = require('path'); | ||
function relative(from, to) { | ||
return pathLib.relative(pathLib.dirname(from), pathLib.resolve(to)); | ||
} | ||
const pify = require('pify'); | ||
exports.hard = function(target, path, cb) { | ||
fs.link(target, path, cb); | ||
}; | ||
const relative = (from, to) => pathLib.relative(pathLib.dirname(from), pathLib.resolve(to)); | ||
exports.hardSync = function(target, path) { | ||
return fs.linkSync(target, path); | ||
}; | ||
exports.hard = pify(fs.link); | ||
exports.symbolic = function(target, path, cb) { | ||
target = relative(path, target); | ||
fs.symlink(target, path, cb); | ||
}; | ||
exports.hardSync = fs.linkSync; | ||
exports.symbolicSync = function(target, path) { | ||
target = relative(path, target); | ||
return fs.symlinkSync(target, path); | ||
}; | ||
exports.symbolic = pify((target, path, cb) => { | ||
target = relative(path, target); | ||
fs.symlink(target, path, cb); | ||
}); | ||
exports.directory = function(target, path, cb) { | ||
target = relative(path, target); | ||
fs.symlink(target, path, 'dir', cb); | ||
}; | ||
exports.symbolicSync = (target, path) => { | ||
target = relative(path, target); | ||
exports.directorySync = function(target, path) { | ||
target = relative(path, target); | ||
return fs.symlinkSync(target, path, 'dir'); | ||
return fs.symlinkSync(target, path); | ||
}; | ||
exports.junction = function(target, path, cb) { | ||
// junction paths are always absolute | ||
if (!isWin) { | ||
target = relative(path, target); | ||
} | ||
fs.symlink(target, path, 'junction', cb); | ||
exports.directory = pify((target, path, cb) => { | ||
target = relative(path, target); | ||
fs.symlink(target, path, 'dir', cb); | ||
}); | ||
exports.directorySync = (target, path) => { | ||
target = relative(path, target); | ||
return fs.symlinkSync(target, path, 'dir'); | ||
}; | ||
exports.junctionSync = function(target, path) { | ||
// junction paths are always absolute | ||
if (!isWin) { | ||
target = relative(path, target); | ||
} | ||
return fs.symlinkSync(target, path, 'junction'); | ||
exports.junction = pify((target, path, cb) => { | ||
target = relative(path, target); | ||
fs.symlink(target, path, 'junction', cb); | ||
}); | ||
exports.junctionSync = (target, path) => { | ||
target = relative(path, target); | ||
return fs.symlinkSync(target, path, 'junction'); | ||
}; | ||
exports.default = function(target, path, cb) { | ||
exports.hard(target, path, function(err) { | ||
if (!err || err.code !== 'EPERM') { | ||
return cb(err); | ||
} | ||
exports.junction(target, path, cb); | ||
}); | ||
exports.default = (target, path) => { | ||
return exports.hard(target, path).catch(err => { | ||
if (err.code === 'EPERM') { | ||
return exports.junction(target, path); | ||
} | ||
throw err; | ||
}); | ||
}; | ||
exports.defaultSync = function(target, path) { | ||
try { | ||
return exports.hardSync(target, path); | ||
} catch (err) { | ||
if (err.code === 'EPERM') { | ||
return exports.junctionSync(target, path); | ||
} | ||
throw err; | ||
} | ||
exports.defaultSync = (target, path) => { | ||
try { | ||
return exports.hardSync(target, path); | ||
} catch (err) { | ||
if (err.code === 'EPERM') { | ||
return exports.junctionSync(target, path); | ||
} | ||
throw err; | ||
} | ||
}; | ||
Object.defineProperty(exports, 'get', { | ||
value: function(type) { | ||
var linkFn = exports[type]; | ||
value: type => { | ||
var linkFn = exports[type]; | ||
if (linkFn) { | ||
return linkFn.bind(exports); | ||
} | ||
if (linkFn) { | ||
return linkFn.bind(exports); | ||
} | ||
throw new Error('unknown link type: `' + type + '`'); | ||
}, | ||
throw new Error('unknown link type: `' + type + '`'); | ||
} | ||
}); | ||
Object.defineProperty(exports, 'getSync', { | ||
value: function(type) { | ||
return exports.get(type + 'Sync'); | ||
}, | ||
value: type => exports.get(type + 'Sync') | ||
}); | ||
Object.defineProperty(exports, 'getTypes', { | ||
value: function() { | ||
var suffix = 'Sync'; | ||
var types = []; | ||
var name; | ||
value: () => { | ||
const suffix = 'Sync'; | ||
const types = []; | ||
for (name in exports) { | ||
if (typeof exports[name] === 'function' && | ||
name.slice(-suffix.length) !== suffix) { | ||
for (let name in exports) { | ||
if (typeof exports[name] === 'function' && name.slice(-suffix.length) !== suffix) { | ||
types.push(name); | ||
} | ||
} | ||
types.push(name); | ||
} | ||
} | ||
return types; | ||
}, | ||
return types; | ||
} | ||
}); |
{ | ||
"name": "lnk", | ||
"version": "0.4.4", | ||
"description": "Create links between files", | ||
"version": "1.0.0", | ||
"description": "Create links between files cross-platform", | ||
"license": "MIT", | ||
"repository": "schnittstabil/lnk", | ||
"keywords": [ | ||
"link", | ||
"cross-platform", | ||
"windows", | ||
"symlink", | ||
@@ -20,69 +24,42 @@ "linkSync", | ||
"ln", | ||
"mklink", | ||
"cli" | ||
"mklink" | ||
], | ||
"license": "MIT", | ||
"homepage": "https://github.com/schnittstabil/lnk", | ||
"author": { | ||
"name": "Michael Mayer", | ||
"email": "michael@schnittstabil.de" | ||
"email": "michael@schnittstabil.de", | ||
"url": "schnittstabil.de" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/schnittstabil/lnk.git" | ||
"engines": { | ||
"node": ">=4" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/schnittstabil/lnk/issues" | ||
"dependencies": { | ||
"arrify": "^1.0.1", | ||
"mkdirp": "^0.5.0", | ||
"path-is-absolute": "^1.0.0", | ||
"pify": "^2.3", | ||
"rimraf": "^2.5.4" | ||
}, | ||
"devDependencies": { | ||
"ava": "^0.16", | ||
"coveralls": "^2.11", | ||
"execa": "^0.4.0", | ||
"nyc": "^8.3.0", | ||
"rewire": "^2.3", | ||
"uuid": "^2.0", | ||
"xo": "^0.16.0" | ||
}, | ||
"main": "index.js", | ||
"bin": { | ||
"lnk": "./cli.js" | ||
"lnk": "./index.js" | ||
}, | ||
"config": { | ||
"ghooks": { | ||
"pre-commit": "npm run -s lint", | ||
"pre-push": "npm run pre-push" | ||
} | ||
}, | ||
"files": [ | ||
"cli.js", | ||
"index.js", | ||
"link.js" | ||
], | ||
"scripts": { | ||
"test": "mocha", | ||
"travis": "npm run pre-push && npm run upload-coveralls", | ||
"pre-push": "npm run cover && istanbul check-coverage && npm run lint", | ||
"cover": "npm run clean-cover && istanbul cover node_modules/mocha/bin/_mocha -- -R spec", | ||
"upload-coveralls": "cat coverage/lcov.info | coveralls", | ||
"lint": "npm -s run lint-js && npm -s run jscs && npm -s run lint-ec", | ||
"lint-js": "globstar -n -- eslint \"*.js\" \"test/**/*.js\"", | ||
"jscs": "jscs .", | ||
"lint-ec": "globstar -n -- editorconfig-tools check \"*.js\" \"test/**/*.js\" \"*.json\" \"*.md\" \".*.yml\"", | ||
"watch-tasks": "npm -s run test && npm -s run lint", | ||
"watch": "gazer-color -p \"*.*\" -p \"test/**/*\" -- npm -s run watch-tasks", | ||
"watch-lint": "gazer-color -p \"*.*\" -p \"test/**/*\" -- npm -s run lint", | ||
"clean-temp": "rimraf temp", | ||
"clean-cover": "rimraf coverage" | ||
}, | ||
"devDependencies": { | ||
"coveralls": "^2.11.2", | ||
"del": "^1.1.1", | ||
"eslint": "^0.17.1", | ||
"editorconfig-tools": "^0.1.1", | ||
"gazer-color": "0.0.3", | ||
"ghooks": "^0.3.0", | ||
"globstar": "^1.0.0", | ||
"istanbul": "^0.3.6", | ||
"jscs": "^1.11.3", | ||
"mocha": "^2.1.0", | ||
"mocha-lcov-reporter": "0.0.2", | ||
"rewire": "^2.3.1", | ||
"uuid": "^2.0.1" | ||
}, | ||
"dependencies": { | ||
"array-series": "^0.1.5", | ||
"each-async": "^1.1.1", | ||
"mkdirp": "^0.5.0", | ||
"npmlog": "^1.1.0", | ||
"object-assign": "^2.0.0", | ||
"path-is-absolute": "^1.0.0", | ||
"rimraf": "^2.2.8", | ||
"yargs": "^3.4.5" | ||
"test": "xo && nyc ava", | ||
"clean": "rimraf .nyc_output/ coverage/", | ||
"coverage-html": "nyc ava && nyc report --reporter=html" | ||
} | ||
} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
5
7
3
12035
5
202
2
147
+ Addedarrify@^1.0.1
+ Addedpify@^2.3
+ Addedarrify@1.0.1(transitive)
+ Addedpify@2.3.0(transitive)
- Removedarray-series@^0.1.5
- Removedeach-async@^1.1.1
- Removednpmlog@^1.1.0
- Removedobject-assign@^2.0.0
- Removedyargs@^3.4.5
- Removedansi@0.3.1(transitive)
- Removedansi-regex@2.1.1(transitive)
- Removedare-we-there-yet@1.0.6(transitive)
- Removedarray-series@0.1.5(transitive)
- Removedcamelcase@2.1.1(transitive)
- Removedcliui@3.2.0(transitive)
- Removedcode-point-at@1.1.0(transitive)
- Removedcore-util-is@1.0.3(transitive)
- Removeddecamelize@1.2.0(transitive)
- Removeddelegates@1.0.0(transitive)
- Removedeach-async@1.1.1(transitive)
- Removedgauge@1.2.7(transitive)
- Removedhas-unicode@2.0.1(transitive)
- Removedinvert-kv@1.0.0(transitive)
- Removedis-fullwidth-code-point@1.0.0(transitive)
- Removedisarray@1.0.0(transitive)
- Removedlcid@1.0.0(transitive)
- Removedlodash.pad@4.5.1(transitive)
- Removedlodash.padend@4.6.1(transitive)
- Removedlodash.padstart@4.6.1(transitive)
- Removednpmlog@1.2.1(transitive)
- Removednumber-is-nan@1.0.1(transitive)
- Removedobject-assign@2.1.1(transitive)
- Removedonetime@1.1.0(transitive)
- Removedos-locale@1.4.0(transitive)
- Removedprocess-nextick-args@2.0.1(transitive)
- Removedreadable-stream@2.3.8(transitive)
- Removedsafe-buffer@5.1.2(transitive)
- Removedset-immediate-shim@1.0.1(transitive)
- Removedstring-width@1.0.2(transitive)
- Removedstring_decoder@1.1.1(transitive)
- Removedstrip-ansi@3.0.1(transitive)
- Removedutil-deprecate@1.0.2(transitive)
- Removedwindow-size@0.1.4(transitive)
- Removedwrap-ansi@2.1.0(transitive)
- Removedy18n@3.2.2(transitive)
- Removedyargs@3.32.0(transitive)
Updatedrimraf@^2.5.4