From 681f1d1241b678e6d0562311b3e8a735f2c18bc5 Mon Sep 17 00:00:00 2001 From: Nathanael Anderson Date: Fri, 26 Jul 2019 16:16:45 -0500 Subject: [PATCH 1/6] Fix TNS to be able to use alternate registries --- lib/definitions/libnpmconfig.d.ts | 3 +++ lib/services/pacote-service.ts | 14 +++++++++++++- package.json | 5 +++-- 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 lib/definitions/libnpmconfig.d.ts diff --git a/lib/definitions/libnpmconfig.d.ts b/lib/definitions/libnpmconfig.d.ts new file mode 100644 index 0000000000..63d2ea0313 --- /dev/null +++ b/lib/definitions/libnpmconfig.d.ts @@ -0,0 +1,3 @@ +declare module "libnpmconfig" { + export function read(options?: Object): Object; +} diff --git a/lib/services/pacote-service.ts b/lib/services/pacote-service.ts index 212bb706b4..26ffb69b3e 100644 --- a/lib/services/pacote-service.ts +++ b/lib/services/pacote-service.ts @@ -2,12 +2,20 @@ import * as pacote from "pacote"; import * as tar from "tar"; import * as path from "path"; import { cache } from "../common/decorators"; +import * as npmconfig from "libnpmconfig"; export class PacoteService implements IPacoteService { + private npmConfig: { [index: string]: any } = {}; + constructor(private $fs: IFileSystem, private $injector: IInjector, private $logger: ILogger, - private $proxyService: IProxyService) { } + private $proxyService: IProxyService) { + npmconfig.read().forEach((value: any, key: string) => { + // replace env ${VARS} in strings with the process.env value + this.npmConfig[key] = typeof value !== 'string' ? value : value.replace(/\${([^}]+)}/, (_, envVar) => process.env[envVar] ); + }); + } @cache() public get $packageManager(): INodePackageManager { @@ -18,6 +26,10 @@ export class PacoteService implements IPacoteService { public async manifest(packageName: string, options?: IPacoteManifestOptions): Promise { this.$logger.trace(`Calling pacoteService.manifest for packageName: '${packageName}' and options: ${options}`); const manifestOptions: IPacoteBaseOptions = await this.getPacoteBaseOptions(); + + // Add NPM Configuration to our Manifest options + _.extend(manifestOptions, this.npmConfig); + if (options) { _.extend(manifestOptions, options); } diff --git a/package.json b/package.json index 9b934c7cfb..c0aef722cf 100644 --- a/package.json +++ b/package.json @@ -61,10 +61,11 @@ "nativescript-dev-xcode": "0.2.0", "nativescript-doctor": "1.10.0", "nativescript-preview-sdk": "0.3.4", + "libnpmconfig": "1.2.1", "open": "0.0.5", "ora": "2.0.0", "osenv": "0.1.3", - "pacote": "8.1.6", + "pacote": "9.5.4", "pako": "1.0.6", "pbxproj-dom": "1.2.0", "plist": "1.1.0", @@ -139,4 +140,4 @@ "engines": { "node": ">=10.0.0 <13.0.0" } -} \ No newline at end of file +} From 246f905283cb22464d8a98b5af6a66d6279d5090 Mon Sep 17 00:00:00 2001 From: Nathanael Anderson Date: Fri, 26 Jul 2019 16:41:45 -0500 Subject: [PATCH 2/6] Fix lint issues --- lib/services/pacote-service.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/services/pacote-service.ts b/lib/services/pacote-service.ts index 26ffb69b3e..8885898577 100644 --- a/lib/services/pacote-service.ts +++ b/lib/services/pacote-service.ts @@ -10,12 +10,12 @@ export class PacoteService implements IPacoteService { constructor(private $fs: IFileSystem, private $injector: IInjector, private $logger: ILogger, - private $proxyService: IProxyService) { - npmconfig.read().forEach((value: any, key: string) => { - // replace env ${VARS} in strings with the process.env value - this.npmConfig[key] = typeof value !== 'string' ? value : value.replace(/\${([^}]+)}/, (_, envVar) => process.env[envVar] ); - }); - } + private $proxyService: IProxyService) { + npmconfig.read().forEach((value: any, key: string) => { + // replace env ${VARS} in strings with the process.env value + this.npmConfig[key] = typeof value !== 'string' ? value : value.replace(/\${([^}]+)}/, (_, envVar) => process.env[envVar] ); + }); + } @cache() public get $packageManager(): INodePackageManager { From 72c65ee056bbc19e6ea31b1a6ba8bedd7d55733d Mon Sep 17 00:00:00 2001 From: Nathanael Anderson Date: Fri, 26 Jul 2019 16:44:17 -0500 Subject: [PATCH 3/6] Fix final tslint issue --- lib/services/pacote-service.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/services/pacote-service.ts b/lib/services/pacote-service.ts index 8885898577..69130e5608 100644 --- a/lib/services/pacote-service.ts +++ b/lib/services/pacote-service.ts @@ -11,10 +11,10 @@ export class PacoteService implements IPacoteService { private $injector: IInjector, private $logger: ILogger, private $proxyService: IProxyService) { - npmconfig.read().forEach((value: any, key: string) => { - // replace env ${VARS} in strings with the process.env value - this.npmConfig[key] = typeof value !== 'string' ? value : value.replace(/\${([^}]+)}/, (_, envVar) => process.env[envVar] ); - }); + npmconfig.read().forEach((value: any, key: string) => { + // replace env ${VARS} in strings with the process.env value + this.npmConfig[key] = typeof value !== 'string' ? value : value.replace(/\${([^}]+)}/, (_, envVar) => process.env[envVar] ); + }); } @cache() From c8c550e7a6633d42153a7dd895f498761a110747 Mon Sep 17 00:00:00 2001 From: Nathanael Anderson Date: Fri, 26 Jul 2019 17:52:53 -0500 Subject: [PATCH 4/6] Update Test to use npm config --- test/services/pacote-service.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/services/pacote-service.ts b/test/services/pacote-service.ts index acdbaa96b4..ba31215aad 100644 --- a/test/services/pacote-service.ts +++ b/test/services/pacote-service.ts @@ -4,6 +4,8 @@ import { PacoteService } from '../../lib/services/pacote-service'; import { LoggerStub } from "../stubs"; import { sandbox, SinonSandbox, SinonStub } from "sinon"; import { EventEmitter } from "events"; + +const npmconfig = require("libnpmconfig"); const pacote = require("pacote"); const tar = require("tar"); const path = require("path"); @@ -12,7 +14,7 @@ const npmCachePath = "npmCachePath"; const packageName = "testPackage"; const fullPath = `/Users/username/${packageName}`; const destinationDir = "destinationDir"; -const defaultPacoteOpts: IPacoteBaseOptions = { cache: npmCachePath }; +const defaultPacoteOpts: IPacoteBaseOptions = createPacoteOptions({ cache: npmCachePath }); const errorMessage = "error message"; const proxySettings: IProxySettings = { hostname: "hostname", @@ -36,6 +38,14 @@ interface ITestCase extends ITestSetup { expectedArgs: any[]; } +function createPacoteOptions(options: Object): Object { + npmconfig.read().forEach((value: any, key: string) => { + // replace env ${VARS} in strings with the process.env value + options[key] = typeof value !== 'string' ? value : value.replace(/\${([^}]+)}/, (_, envVar) => process.env[envVar] ); + }); + return options; +} + const createTestInjector = (opts?: ITestSetup): IInjector => { opts = opts || {}; From 12d9281d3ab5c2a0fe4861c01e82177022b07a23 Mon Sep 17 00:00:00 2001 From: Nathanael Anderson Date: Fri, 26 Jul 2019 20:09:03 -0500 Subject: [PATCH 5/6] Fixed Pacote test, broken path.resolve stub breaking things --- lib/services/pacote-service.ts | 6 +++--- test/services/pacote-service.ts | 25 +++++++++++++++++++------ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/lib/services/pacote-service.ts b/lib/services/pacote-service.ts index 69130e5608..17f11eb4b4 100644 --- a/lib/services/pacote-service.ts +++ b/lib/services/pacote-service.ts @@ -27,8 +27,6 @@ export class PacoteService implements IPacoteService { this.$logger.trace(`Calling pacoteService.manifest for packageName: '${packageName}' and options: ${options}`); const manifestOptions: IPacoteBaseOptions = await this.getPacoteBaseOptions(); - // Add NPM Configuration to our Manifest options - _.extend(manifestOptions, this.npmConfig); if (options) { _.extend(manifestOptions, options); @@ -79,7 +77,9 @@ export class PacoteService implements IPacoteService { private async getPacoteBaseOptions(): Promise { // In case `tns create myapp --template https://github.com/NativeScript/template-hello-world.git` command is executed, pacote module throws an error if cache option is not provided. const cachePath = await this.$packageManager.getCachePath(); - const pacoteOptions = { cache: cachePath }; + + // Add NPM Configuration to our Manifest options + const pacoteOptions = _.extend( this.npmConfig, {cache: cachePath }); const proxySettings = await this.$proxyService.getCache(); if (proxySettings) { _.extend(pacoteOptions, proxySettings); diff --git a/test/services/pacote-service.ts b/test/services/pacote-service.ts index ba31215aad..cda9f767ce 100644 --- a/test/services/pacote-service.ts +++ b/test/services/pacote-service.ts @@ -10,11 +10,11 @@ const pacote = require("pacote"); const tar = require("tar"); const path = require("path"); -const npmCachePath = "npmCachePath"; +const defaultPacoteOpts: IPacoteBaseOptions = createPacoteOptions({}); +const npmCachePath = defaultPacoteOpts['cache']; const packageName = "testPackage"; const fullPath = `/Users/username/${packageName}`; const destinationDir = "destinationDir"; -const defaultPacoteOpts: IPacoteBaseOptions = createPacoteOptions({ cache: npmCachePath }); const errorMessage = "error message"; const proxySettings: IProxySettings = { hostname: "hostname", @@ -38,11 +38,17 @@ interface ITestCase extends ITestSetup { expectedArgs: any[]; } -function createPacoteOptions(options: Object): Object { +function createPacoteOptions(source: Object): Object { + let options: { [index: string]: any } = {}; npmconfig.read().forEach((value: any, key: string) => { // replace env ${VARS} in strings with the process.env value options[key] = typeof value !== 'string' ? value : value.replace(/\${([^}]+)}/, (_, envVar) => process.env[envVar] ); }); + + // Copy any original source keys over our defaults + for (let key in source) { + options[key] = source[key]; + } return options; } @@ -113,8 +119,15 @@ describe("pacoteService", () => { const setupTest = (opts?: ITestSetup): IPacoteService => { opts = opts || {}; const testInjector = createTestInjector(opts); + if (opts.isLocalPackage) { - sandboxInstance.stub(path, "resolve").withArgs(packageName).returns(fullPath); + const oldPath = path.resolve; + sandboxInstance.stub(path, "resolve").callsFake((value:string) => { + if (value === packageName) { + return fullPath; + } + return oldPath(value); + }); } return testInjector.resolve("pacoteService"); @@ -126,7 +139,7 @@ describe("pacoteService", () => { const testData: ITestCase[] = [ { name: "with 'cache' only when no opts are passed", - expectedArgs: [packageName, defaultPacoteOpts] + expectedArgs: [packageName, _.extend({}, defaultPacoteOpts)] }, { name: "with 'cache' and passed options", @@ -147,7 +160,7 @@ describe("pacoteService", () => { { name: "with full path to file when it is local one", isLocalPackage: true, - expectedArgs: [fullPath, defaultPacoteOpts] + expectedArgs: [fullPath, _.extend({}, defaultPacoteOpts)] }, { name: "with full path to file, 'cache' and passed options when local path is passed", From 79ea14381b9744f23d210f83188b558c281ef011 Mon Sep 17 00:00:00 2001 From: Nathanael Anderson Date: Fri, 26 Jul 2019 20:16:05 -0500 Subject: [PATCH 6/6] TSLint fixes --- lib/services/pacote-service.ts | 1 - test/services/pacote-service.ts | 20 ++++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/services/pacote-service.ts b/lib/services/pacote-service.ts index 17f11eb4b4..290a598034 100644 --- a/lib/services/pacote-service.ts +++ b/lib/services/pacote-service.ts @@ -27,7 +27,6 @@ export class PacoteService implements IPacoteService { this.$logger.trace(`Calling pacoteService.manifest for packageName: '${packageName}' and options: ${options}`); const manifestOptions: IPacoteBaseOptions = await this.getPacoteBaseOptions(); - if (options) { _.extend(manifestOptions, options); } diff --git a/test/services/pacote-service.ts b/test/services/pacote-service.ts index cda9f767ce..e5280f9ab3 100644 --- a/test/services/pacote-service.ts +++ b/test/services/pacote-service.ts @@ -39,15 +39,15 @@ interface ITestCase extends ITestSetup { } function createPacoteOptions(source: Object): Object { - let options: { [index: string]: any } = {}; + const options: { [index: string]: any } = {}; npmconfig.read().forEach((value: any, key: string) => { // replace env ${VARS} in strings with the process.env value options[key] = typeof value !== 'string' ? value : value.replace(/\${([^}]+)}/, (_, envVar) => process.env[envVar] ); }); // Copy any original source keys over our defaults - for (let key in source) { - options[key] = source[key]; + for (const key in source) { + options[key] = source[key]; } return options; } @@ -121,13 +121,13 @@ describe("pacoteService", () => { const testInjector = createTestInjector(opts); if (opts.isLocalPackage) { - const oldPath = path.resolve; - sandboxInstance.stub(path, "resolve").callsFake((value:string) => { - if (value === packageName) { - return fullPath; - } - return oldPath(value); - }); + const oldPath = path.resolve; + sandboxInstance.stub(path, "resolve").callsFake((value:string) => { + if (value === packageName) { + return fullPath; + } + return oldPath(value); + }); } return testInjector.resolve("pacoteService");