diff --git a/lib/cmd-add.js b/lib/cmd-add.js index 4673f1cc..6f93ccb1 100644 --- a/lib/cmd-add.js +++ b/lib/cmd-add.js @@ -14,7 +14,8 @@ const { const add = async function(pkgs, options) { if (!Array.isArray(pkgs)) pkgs = [pkgs]; // parse env - if (!parseEnv(options, { checkPath: true })) return 1; + const envOk = await parseEnv(options, { checkPath: true }); + if (!envOk) return 1; // add const results = []; for (const pkg of pkgs) diff --git a/lib/cmd-deps.js b/lib/cmd-deps.js index 5e19eee6..20197a3a 100644 --- a/lib/cmd-deps.js +++ b/lib/cmd-deps.js @@ -3,7 +3,8 @@ const { fetchPackageDependencies, parseEnv, parseName } = require("./core"); const deps = async function(pkg, options) { // parse env - if (!parseEnv(options, { checkPath: false })) return 1; + const envOk = await parseEnv(options, { checkPath: false }); + if (!envOk) return 1; // parse name let { name, version } = parseName(pkg); // deps diff --git a/lib/cmd-login.js b/lib/cmd-login.js index 133dfe24..1dd0913c 100644 --- a/lib/cmd-login.js +++ b/lib/cmd-login.js @@ -3,7 +3,6 @@ const path = require("path"); const _ = require("lodash"); const promptly = require("promptly"); -const TOML = require("@iarna/toml"); const { getNpmClient } = require("./client"); const { log } = require("./logger"); @@ -16,7 +15,8 @@ const { const login = async function(options) { // parse env - if (!parseEnv(options, { checkPath: false })) return 1; + const envOk = await parseEnv(options, { checkPath: false }); + if (!envOk) return 1; // query parameters if (!options.username) options.username = await promptly.prompt("Username: "); if (!options.password) diff --git a/lib/cmd-remove.js b/lib/cmd-remove.js index d594d6d6..451bbebf 100644 --- a/lib/cmd-remove.js +++ b/lib/cmd-remove.js @@ -10,7 +10,8 @@ const { const remove = async function(pkgs, options) { if (!Array.isArray(pkgs)) pkgs = [pkgs]; // parse env - if (!parseEnv(options, { checkPath: true })) return 1; + const envOk = await parseEnv(options, { checkPath: true }); + if (!envOk) return 1; // remove const results = []; for (const pkg of pkgs) results.push(await _remove(pkg)); diff --git a/lib/cmd-search.js b/lib/cmd-search.js index c03a75da..1c971758 100644 --- a/lib/cmd-search.js +++ b/lib/cmd-search.js @@ -115,7 +115,8 @@ const getTable = function() { module.exports = async function(keyword, options) { // parse env - if (!parseEnv(options, { checkPath: false })) return 1; + const envOk = await parseEnv(options, { checkPath: false }); + if (!envOk) return 1; let table = getTable(); // search endpoint let results = await searchEndpoint(keyword); diff --git a/lib/cmd-view.js b/lib/cmd-view.js index 35f797b2..11d30e37 100644 --- a/lib/cmd-view.js +++ b/lib/cmd-view.js @@ -11,7 +11,8 @@ const { const view = async function(pkg, options) { // parse env - if (!parseEnv(options, { checkPath: false })) return 1; + const envOk = await parseEnv(options, { checkPath: false }); + if (!envOk) return 1; // parse name let { name, version } = parseName(pkg); if (version) { diff --git a/lib/core.js b/lib/core.js index 6a5c8300..c287fca6 100644 --- a/lib/core.js +++ b/lib/core.js @@ -21,7 +21,7 @@ const { log } = require("./logger"); const env = {}; // Parse env -const parseEnv = function(options, { checkPath }) { +const parseEnv = async function(options, { checkPath }) { // set defaults env.registry = "https://package.openupm.com"; env.namespace = "com.openupm"; @@ -32,6 +32,10 @@ const parseEnv = function(options, { checkPath }) { env.upstreamRegistry = "https://packages.unity.com"; env.systemUser = false; env.wsl = false; + // the npmAuth field of .upmconfig.toml + env.npmAuth = {}; + // the dict of auth param for npm registry API + env.auth = {}; // log level log.level = options.parent.verbose ? "verbose" : "notice"; // color @@ -62,6 +66,39 @@ const parseEnv = function(options, { checkPath }) { // auth if (options.parent.systemUser) env.systemUser = true; if (options.parent.wsl) env.wsl = true; + const upmConfig = await loadUpmConfig(); + if (upmConfig) { + env.npmAuth = upmConfig.npmAuth; + if (env.npmAuth) { + for (const reg in env.npmAuth) { + const regAuth = env.npmAuth[reg]; + if (regAuth.token) { + env.auth[reg] = { + token: regAuth.token, + alwaysAuth: regAuth.alwaysAuth || false + }; + } else if (regAuth._auth) { + const buf = Buffer.from(regAuth._auth, "base64"); + const text = buf.toString("utf-8"); + const [username, password] = text.split(":", 2); + env.auth[reg] = { + username, + password, + email: regAuth.email, + alwaysAuth: regAuth.alwaysAuth || false + }; + } else { + log.warn( + "env.auth", + `failed to parse auth info for ${reg} in .upmconfig.toml: missing token or _auth fields` + ); + log.warn("env.auth", regAuth); + } + } + } + } + // log.verbose("env.npmAuth", env.npmAuth); + // log.verbose("env.auth", env.auth); // return if no need to check path if (!checkPath) return true; // cwd @@ -111,7 +148,7 @@ const fetchPackageInfo = async function(name, registry) { const pkgPath = `${registry}/${name}`; const client = getNpmClient(); try { - return await client.get(pkgPath, {}); + return await client.get(pkgPath, { auth: env.auth[registry] || undefined }); // eslint-disable-next-line no-empty } catch (err) {} }; diff --git a/test/test-core.js b/test/test-core.js index 5d5c8dac..4e6752f1 100644 --- a/test/test-core.js +++ b/test/test-core.js @@ -85,8 +85,8 @@ describe("cmd-core.js", function() { stdoutInspect.restore(); stderrInspect.restore(); }); - it("defaults", function() { - parseEnv({ parent: {} }, { checkPath: false }).should.be.ok(); + it("defaults", async function() { + (await parseEnv({ parent: {} }, { checkPath: false })).should.be.ok(); env.registry.should.equal("https://package.openupm.com"); env.upstream.should.be.ok(); env.upstreamRegistry.should.equal("https://packages.unity.com"); @@ -95,10 +95,12 @@ describe("cmd-core.js", function() { env.manifestPath.should.equal(""); const [stdout, stderr] = getOutputs(stdoutInspect, stderrInspect); }); - it("check path", function() { - parseEnv( - { parent: { chdir: getWorkDir("test-openupm-cli") } }, - { checkPath: true } + it("check path", async function() { + ( + await parseEnv( + { parent: { chdir: getWorkDir("test-openupm-cli") } }, + { checkPath: true } + ) ).should.be.ok(); env.cwd.should.be.equal(getWorkDir("test-openupm-cli")); env.manifestPath.should.be.equal( @@ -106,89 +108,106 @@ describe("cmd-core.js", function() { ); const [stdout, stderr] = getOutputs(stdoutInspect, stderrInspect); }); - it("can not resolve path", function() { - parseEnv( - { parent: { chdir: getWorkDir("path-not-exist") } }, - { checkPath: true } + it("can not resolve path", async function() { + ( + await parseEnv( + { parent: { chdir: getWorkDir("path-not-exist") } }, + { checkPath: true } + ) ).should.not.be.ok(); const [stdout, stderr] = getOutputs(stdoutInspect, stderrInspect); stdout.includes("can not resolve path").should.be.ok(); }); - it("can not locate manifest.json", function() { - parseEnv( - { parent: { chdir: getWorkDir("test-openupm-cli-no-manifest") } }, - { checkPath: true } + it("can not locate manifest.json", async function() { + ( + await parseEnv( + { parent: { chdir: getWorkDir("test-openupm-cli-no-manifest") } }, + { checkPath: true } + ) ).should.not.be.ok(); const [stdout, stderr] = getOutputs(stdoutInspect, stderrInspect); stdout.includes("can not locate manifest.json").should.be.ok(); }); - it("custom registry", function() { - parseEnv( - { parent: { registry: "https://registry.npmjs.org" } }, - { checkPath: false } + it("custom registry", async function() { + ( + await parseEnv( + { parent: { registry: "https://registry.npmjs.org" } }, + { checkPath: false } + ) ).should.be.ok(); env.registry.should.be.equal("https://registry.npmjs.org"); env.namespace.should.be.equal("org.npmjs"); const [stdout, stderr] = getOutputs(stdoutInspect, stderrInspect); }); - it("custom registry with splash", function() { - parseEnv( - { parent: { registry: "https://registry.npmjs.org/" } }, - { checkPath: false } + it("custom registry with splash", async function() { + ( + await parseEnv( + { parent: { registry: "https://registry.npmjs.org/" } }, + { checkPath: false } + ) ).should.be.ok(); env.registry.should.be.equal("https://registry.npmjs.org"); env.namespace.should.be.equal("org.npmjs"); const [stdout, stderr] = getOutputs(stdoutInspect, stderrInspect); }); - it("custom registry with extra path", function() { - parseEnv( - { parent: { registry: "https://registry.npmjs.org/some" } }, - { checkPath: false } + it("custom registry with extra path", async function() { + ( + await parseEnv( + { parent: { registry: "https://registry.npmjs.org/some" } }, + { checkPath: false } + ) ).should.be.ok(); env.registry.should.be.equal("https://registry.npmjs.org/some"); env.namespace.should.be.equal("org.npmjs"); const [stdout, stderr] = getOutputs(stdoutInspect, stderrInspect); }); - it("custom registry with extra path and splash", function() { - parseEnv( - { parent: { registry: "https://registry.npmjs.org/some/" } }, - { checkPath: false } + it("custom registry with extra path and splash", async function() { + ( + await parseEnv( + { parent: { registry: "https://registry.npmjs.org/some/" } }, + { checkPath: false } + ) ).should.be.ok(); env.registry.should.be.equal("https://registry.npmjs.org/some"); env.namespace.should.be.equal("org.npmjs"); const [stdout, stderr] = getOutputs(stdoutInspect, stderrInspect); }); - it("custom registry without http", function() { - parseEnv( - { parent: { registry: "registry.npmjs.org" } }, - { checkPath: false } + it("custom registry without http", async function() { + ( + await parseEnv( + { parent: { registry: "registry.npmjs.org" } }, + { checkPath: false } + ) ).should.be.ok(); env.registry.should.be.equal("http://registry.npmjs.org"); env.namespace.should.be.equal("org.npmjs"); const [stdout, stderr] = getOutputs(stdoutInspect, stderrInspect); }); - it("custom registry with ipv4+port", function() { - parseEnv( - { parent: { registry: "http://127.0.0.1:4873" } }, - { checkPath: false } + it("custom registry with ipv4+port", async function() { + ( + await parseEnv( + { parent: { registry: "http://127.0.0.1:4873" } }, + { checkPath: false } + ) ).should.be.ok(); env.registry.should.be.equal("http://127.0.0.1:4873"); env.namespace.should.be.equal("127.0.0.1"); const [stdout, stderr] = getOutputs(stdoutInspect, stderrInspect); }); - it("custom registry with ipv6+port", function() { - parseEnv( - { parent: { registry: "http://[1:2:3:4:5:6:7:8]:4873" } }, - { checkPath: false } + it("custom registry with ipv6+port", async function() { + ( + await parseEnv( + { parent: { registry: "http://[1:2:3:4:5:6:7:8]:4873" } }, + { checkPath: false } + ) ).should.be.ok(); env.registry.should.be.equal("http://[1:2:3:4:5:6:7:8]:4873"); env.namespace.should.be.equal("1:2:3:4:5:6:7:8"); const [stdout, stderr] = getOutputs(stdoutInspect, stderrInspect); }); - it("upstream", function() { - parseEnv( - { parent: { upstream: false } }, - { checkPath: false } + it("upstream", async function() { + ( + await parseEnv({ parent: { upstream: false } }, { checkPath: false }) ).should.be.ok(); env.upstream.should.not.be.ok(); const [stdout, stderr] = getOutputs(stdoutInspect, stderrInspect); @@ -219,39 +238,47 @@ describe("cmd-core.js", function() { stdoutInspect.restore(); stderrInspect.restore(); }); - it("loadManifest", function() { - parseEnv( - { parent: { chdir: getWorkDir("test-openupm-cli") } }, - { checkPath: true } + it("loadManifest", async function() { + ( + await parseEnv( + { parent: { chdir: getWorkDir("test-openupm-cli") } }, + { checkPath: true } + ) ).should.be.ok(); const manifest = loadManifest(); manifest.should.be.deepEqual({ dependencies: {} }); const [stdout, stderr] = getOutputs(stdoutInspect, stderrInspect); }); - it("no manifest file", function() { - parseEnv( - { parent: { chdir: getWorkDir("path-not-exist") } }, - { checkPath: false } + it("no manifest file", async function() { + ( + await parseEnv( + { parent: { chdir: getWorkDir("path-not-exist") } }, + { checkPath: false } + ) ).should.be.ok(); const manifest = loadManifest(); (manifest === null).should.be.ok(); const [stdout, stderr] = getOutputs(stdoutInspect, stderrInspect); stdout.includes("does not exist").should.be.ok(); }); - it("wrong json content", function() { - parseEnv( - { parent: { chdir: getWorkDir("test-openupm-cli-wrong-json") } }, - { checkPath: true } + it("wrong json content", async function() { + ( + await parseEnv( + { parent: { chdir: getWorkDir("test-openupm-cli-wrong-json") } }, + { checkPath: true } + ) ).should.be.ok(); const manifest = loadManifest(); (manifest === null).should.be.ok(); const [stdout, stderr] = getOutputs(stdoutInspect, stderrInspect); stdout.includes("failed to parse").should.be.ok(); }); - it("saveManifest", function() { - parseEnv( - { parent: { chdir: getWorkDir("test-openupm-cli") } }, - { checkPath: true } + it("saveManifest", async function() { + ( + await parseEnv( + { parent: { chdir: getWorkDir("test-openupm-cli") } }, + { checkPath: true } + ) ).should.be.ok(); const manifest = loadManifest(); manifest.should.be.deepEqual({ dependencies: {} }); @@ -279,9 +306,11 @@ describe("cmd-core.js", function() { nockDown(); }); it("simple", async function() { - parseEnv( - { parent: { registry: "http://example.com" } }, - { checkPath: false } + ( + await parseEnv( + { parent: { registry: "http://example.com" } }, + { checkPath: false } + ) ).should.be.ok(); let pkgInfoRemote = { name: "com.littlebigfun.addressable-importer" }; nock("http://example.com") @@ -291,9 +320,11 @@ describe("cmd-core.js", function() { info.should.deepEqual(pkgInfoRemote); }); it("404", async function() { - parseEnv( - { parent: { registry: "http://example.com" } }, - { checkPath: false } + ( + await parseEnv( + { parent: { registry: "http://example.com" } }, + { checkPath: false } + ) ).should.be.ok(); let pkgInfoRemote = { name: "com.littlebigfun.addressable-importer" }; nock("http://example.com")