diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dbdf60be..f5da2d66c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.1.1-beta.x + +- Update version detection with pathname & version de-dupe + # 2.0.1 - Update w3f/schnorrkel to 0.8.5 (Full Substrate 2.x support, no 1.x support) diff --git a/packages/keyring/src/index.ts b/packages/keyring/src/index.ts index 65a5da072..b726ab316 100644 --- a/packages/keyring/src/index.ts +++ b/packages/keyring/src/index.ts @@ -7,15 +7,22 @@ import { decodeAddress, encodeAddress, setSS58Format } from '@polkadot/util-cryp import Keyring from './keyring'; +let dirname = 'node_modules'; let pkgJson; +try { + dirname = __dirname; +} catch (error) { + // ignore +} + try { pkgJson = require('./package.json'); } catch (error) { pkgJson = require('../package.json'); } -detectPackage(pkgJson); +detectPackage(dirname, pkgJson); export default Keyring; diff --git a/packages/util/src/detectPackage.spec.ts b/packages/util/src/detectPackage.spec.ts index e15cdadfc..09c0fcdae 100644 --- a/packages/util/src/detectPackage.spec.ts +++ b/packages/util/src/detectPackage.spec.ts @@ -5,10 +5,15 @@ import { detectPackage } from '.'; describe('assertSingletonPackage', (): void => { + const PKG = '@polkadot/util'; + const VER1 = '9.8.0-beta.45'; + const VER2 = '9.7.1'; + const PATH = '/Users/jaco/Projects/polkadot-js/api/node_modules/@polkadot/util'; + it('should not log the first time', (): void => { const spy = jest.spyOn(console, 'warn'); - detectPackage({ name: '@polkadot/util', version: 'a.b.c-1st' }); + detectPackage(`${PATH}/01`, { name: PKG, version: VER1 }); expect(spy).not.toHaveBeenCalled(); spy.mockRestore(); }); @@ -16,8 +21,8 @@ describe('assertSingletonPackage', (): void => { it('should log the second time', (): void => { const spy = jest.spyOn(console, 'warn'); - detectPackage({ name: '@polkadot/util', version: 'a.b.c-2nd' }); - expect(spy).toHaveBeenCalledWith('Multiple versions of @polkadot/util detected: a.b.c-1st, a.b.c-2nd. Ensure that there is only one version in your dependency tree'); + detectPackage(`${PATH}/02`, { name: PKG, version: VER2 }); + expect(spy).toHaveBeenCalledWith(`Multiple instances of @polkadot/util detected, ensure that there is only one package in your dependency tree.\n\t${VER1}\t${PATH}/01\n\t${VER2} \t${PATH}/02`); spy.mockRestore(); }); }); diff --git a/packages/util/src/detectPackage.ts b/packages/util/src/detectPackage.ts index 91d9d080a..218f01b35 100644 --- a/packages/util/src/detectPackage.ts +++ b/packages/util/src/detectPackage.ts @@ -3,27 +3,47 @@ // of the Apache-2.0 license. See the LICENSE file for details. import assert from './assert'; +import isString from './is/string'; // eslint-disable-next-line no-undef type This = typeof globalThis; -interface PjsChecks extends This { - __polkadotjs: Record; -} - interface PackageJson { name: string; version: string; } +interface VersionPath { + path: string; + version: string; +} + +interface PjsChecks extends This { + __polkadotjs: Record; +} + type PjsGlobal = NodeJS.Global & PjsChecks; type PjsWindow = Window & PjsChecks; +/** @internal */ +function flattenVersions (_all: (VersionPath | string)[]): string { + const all: VersionPath[] = _all.map((version: VersionPath | string): VersionPath => + isString(version) + ? { path: '', version } + : version + ); + const verLength = all.reduce((max, { version }): number => Math.max(max, version.length), 0); + + return all + .map(({ path, version }): string => `\t${version.padEnd(verLength)}\t${path}`) + .join('\n'); +} + /** * @name detectPackage * @summary Checks that a specific package is only imported once */ -export default function detectPackage ({ name, version }: PackageJson): void { +export default function detectPackage (path: string, { name, version }: PackageJson): void { const _global = typeof window !== 'undefined' ? window as PjsWindow : global as PjsGlobal; @@ -34,9 +54,11 @@ export default function detectPackage ({ name, version }: PackageJson): void { assert(name.startsWith('@polkadot'), `Invalid package descriptor ${name}`); - _global.__polkadotjs[name] = [...(_global.__polkadotjs[name] || []), version]; + _global.__polkadotjs[name] = [...(_global.__polkadotjs[name] || []), { path, version }]; if (_global.__polkadotjs[name].length !== 1) { - console.warn(`Multiple versions of ${name} detected: ${_global.__polkadotjs[name].join(', ')}. Ensure that there is only one version in your dependency tree`); + const versions = flattenVersions(_global.__polkadotjs[name]); + + console.warn(`Multiple instances of ${name} detected, ensure that there is only one package in your dependency tree.\n${versions}`); } }