diff --git a/CHANGELOG.md b/CHANGELOG.md index fb6cfb0ad..bc8ef6a14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,12 +3,19 @@ CHANGELOG ## HEAD (Unreleased) +### Improvements + - [sdk/dotnet] C# Automation API. [#5761](https://github.com/pulumi/pulumi/pull/5761) - [sdk/dotnet] F# API to specify stack options. [#5077](https://github.com/pulumi/pulumi/pull/5077) - + +### Bug Fixes + +- [sdk/nodejs] Don't error when loading multiple copies of the same version of a Node.js + component package. [#6387](https://github.com/pulumi/pulumi/pull/6387) + ## 2.21.1 (2021-02-18) ### Bug Fixes @@ -16,6 +23,8 @@ CHANGELOG - [sdk/python] Fixed a change to `Output.all()` that raised an error if no inputs are passed in. [#6381](https://github.com/pulumi/pulumi/pull/6381) +### Bug Fixes + ## 2.21.0 (2021-02-17) ### Improvements diff --git a/sdk/nodejs/runtime/rpc.ts b/sdk/nodejs/runtime/rpc.ts index c704017cf..8bb636e03 100644 --- a/sdk/nodejs/runtime/rpc.ts +++ b/sdk/nodejs/runtime/rpc.ts @@ -599,12 +599,17 @@ function checkVersion(want?: semver.SemVer, have?: semver.SemVer): boolean { } /** @internal */ -export function register(source: Map, registrationType: string, key: string, item: T): void { +export function register(source: Map, registrationType: string, key: string, item: T): boolean { let items = source.get(key); if (items) { for (const existing of items) { if (sameVersion(existing.version, item.version)) { - throw new Error(`Cannot re-register ${registrationType} ${key}@${item.version}. Previous registration was ${existing}, new registration was ${item}.`); + // It is possible for the same version of the same provider SDK to be loaded multiple times in Node.js. + // In this case, we might legitimately get mutliple registrations of the same resource. It should not + // matter which we use, so we can just skip re-registering. De-serialized resources will always be + // instances of classes from the first registered package. + log.debug(`skip re-registering already registered ${registrationType} ${key}@${item.version}.`); + return false; } } } else { @@ -614,6 +619,7 @@ export function register(source: Map { describe("register", () => { const tests = [ { name: "wildcard version", version: undefined }, - { name: "blank version", version: "" }, { name: "version", version: "1.2.3" }, { name: "alpha version", version: "1.0.0-alpha1" }, ]; for (const { name, version } of tests) { - it(`throws on same ${name}`, () => { + it(`ignores registration on same ${name}`, () => { const source = new Map(); - runtime.register(source, rt, "test", { version, construct }); - assert.throws(() => runtime.register(source, rt, "test", { version, construct })); + assert.strictEqual(runtime.register(source, rt, "test", { version, construct }), true); + assert.strictEqual(runtime.register(source, rt, "test", { version, construct }), false); }); } });