From 7a43e19b86bcade66e49a6ec63a6ea7f06e5a411 Mon Sep 17 00:00:00 2001 From: Mark Oswald Date: Thu, 12 Apr 2018 10:12:50 +0200 Subject: [PATCH] feat: Support private packages (#3) * use npm view to get remote package information * fix small typo in README.md * unify name of parameter to packageName * reject with error message --- README.md | 2 +- lib/can-npm-publish.js | 66 ++++++++++++++++++++++++------------------ package.json | 1 - 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 337d0e2..54aa098 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ All check list is passed, exit status will be `0`. - [x] Check that the package's name is valid - [validate-npm-package-name](https://github.com/npm/validate-npm-package-name "validate-npm-package-name") - [x] Check that the package is not `private:true` -- [x] Check that `pacakge@version` is already published in npm registry +- [x] Check that `package@version` is already published in npm registry ## Install diff --git a/lib/can-npm-publish.js b/lib/can-npm-publish.js index b6cad26..a1f492d 100644 --- a/lib/can-npm-publish.js +++ b/lib/can-npm-publish.js @@ -1,6 +1,6 @@ // MIT © 2018 azu "use strict"; -const fetch = require("node-fetch"); +const spawn = require("child_process").spawn; const readPkg = require("read-pkg"); const validatePkgName = require("validate-npm-package-name"); /** @@ -31,6 +31,37 @@ const checkPrivateField = packagePath => { }); }; +/** + * Return Promise which resolves with an array of version numbers for the package + * or rejects if anything failed + * @param packageName + * @returns {Promise} + */ +const viewPackage = packageName => { + return new Promise((resolve, reject) => { + const view = spawn("npm", ["view", packageName, "versions", "--json"]); + let result = ""; + let errorResult = ""; + + view.stdout.on("data", data => { + result += data.toString(); + }); + + view.stderr.on("data", err => { + errorResult += err.toString(); + }); + + view.on("close", code => { + if (code > 0) { + reject(new Error(errorResult)); + return; + } + + resolve(JSON.parse(result)); + }); + }); +}; + const checkAlreadyPublish = packagePath => { return readPkg(packagePath).then(pkg => { const name = pkg["name"]; @@ -41,33 +72,12 @@ const checkAlreadyPublish = packagePath => { if (version === undefined) { return Promise.reject(new Error("This package has not `version`.")); } - // https://github.com/npm/registry/blob/master/docs/REGISTRY-API.md#getpackageversion - // @scope/name => @scope%2Fname - const encodedName = name.replace(/\//g, "%2F"); - return fetch(`https://registry.npmjs.com/${encodedName}`) - .then(response => { - if (response.status === 404) { - // not published yet - return { - versions: [] - }; - } - if (!response.ok) { - return Promise.reject(new Error(response.statusText)); - } - return response.json(); - }) - .then(json => { - if (json.error) { - // {"error":"version not found: 18.0.0"} - return Promise.reject(new Error(json.error)); - } - const versions = json["versions"]; - if (versions[version]) { - return Promise.reject(new Error(`${name}@${version} is already published`)); - } - return; - }); + return viewPackage(name).then(versions => { + if (versions.includes(version)) { + return Promise.reject(new Error(`${name}@${version} is already published`)); + } + return; + }); }); }; const canNpmPublish = packagePath => { diff --git a/package.json b/package.json index 113a2b5..0092d5c 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,6 @@ }, "dependencies": { "meow": "^4.0.0", - "node-fetch": "^1.7.3", "read-pkg": "^3.0.0", "validate-npm-package-name": "^3.0.0" },