From dc28262d2e3389b4fa66f2238dbb1a8703f3bc88 Mon Sep 17 00:00:00 2001 From: Choro Abdymanapov Date: Mon, 18 Jan 2021 23:52:08 +0300 Subject: [PATCH] feat: add `get` action (#16) --- .../src/main/ts/executors/deprecate.ts | 4 +- packages/cli-api/src/main/ts/executors/get.ts | 68 +++++++++ .../cli-api/src/main/ts/executors/index.ts | 2 + .../cli-api/src/main/ts/executors/publish.ts | 2 +- packages/cli-api/src/main/ts/interfaces.ts | 7 +- packages/cli-api/src/main/ts/runner.ts | 15 +- packages/cli-api/src/main/ts/utils/misc.ts | 18 ++- .../cli-api/src/main/ts/utils/validators.ts | 15 +- .../src/test/ts/executors/deprecate.ts | 5 +- packages/cli-api/src/test/ts/executors/get.ts | 130 +++++++++++++++++ .../cli-api/src/test/ts/executors/publish.ts | 10 +- packages/cli-api/src/test/ts/misc.ts | 5 +- packages/cli-api/src/test/ts/runner.ts | 10 ++ .../cli-api/src/test/ts/utils/validators.ts | 68 ++++++++- packages/cli/README.md | 137 +++++++++++++++++- packages/client/src/main/ts/interfaces.ts | 4 + packages/client/src/main/ts/wrapper.ts | 11 +- yarn.lock | 78 +++++----- 18 files changed, 518 insertions(+), 71 deletions(-) create mode 100644 packages/cli-api/src/main/ts/executors/get.ts create mode 100644 packages/cli-api/src/test/ts/executors/get.ts diff --git a/packages/cli-api/src/main/ts/executors/deprecate.ts b/packages/cli-api/src/main/ts/executors/deprecate.ts index df3ee94..490ccd8 100644 --- a/packages/cli-api/src/main/ts/executors/deprecate.ts +++ b/packages/cli-api/src/main/ts/executors/deprecate.ts @@ -22,10 +22,10 @@ export const processResults = (results: THandledValue[], config: TDeprecationCon const failedResults = getFailedResults(enrichedResults) if (config.batch?.jsonOutput) { - printResultsJson( + printResultsJson({ successfulResults, failedResults - ) + }) return } diff --git a/packages/cli-api/src/main/ts/executors/get.ts b/packages/cli-api/src/main/ts/executors/get.ts new file mode 100644 index 0000000..be650b6 --- /dev/null +++ b/packages/cli-api/src/main/ts/executors/get.ts @@ -0,0 +1,68 @@ +import { INpmRegClientWrapper, Packument, RegClient, TBatchResult } from '@qiwi/npm-batch-client' + +import { TGetConfig } from '../interfaces' +import { npmRegClientWrapperFactory, printResults, printResultsJson, writeToFile } from '../utils' + +export const performGet = ( + config: TGetConfig, + customBatchClient?: INpmRegClientWrapper +): Promise => { + const batchClient = customBatchClient || npmRegClientWrapperFactory(config, ['get'], new RegClient()) + + return batchClient.getBatch(config.data, config.batch?.skipErrors) + .then(results => processGetResults(results, config)) +} + +export const isResultSuccessful = ( + item: PromiseSettledResult +): item is PromiseFulfilledResult & { name: string } => + item.status === 'fulfilled' && + typeof item.value === 'object' && + item.value !== null && + !(item.value as any).error + +export const isResultFailed = (item: PromiseSettledResult): boolean => + item.status === 'rejected' || + typeof item.value !== 'object' || + !item.value || + (item.value as any).error + +export const getErrorMessage = (item: PromiseSettledResult): string => + item.status === 'rejected' + ? item.reason?.message ?? item.reason + : `got ${typeof item.value === 'object' ? JSON.stringify(item.value) : item.value} instead of Packument` + + +export const processGetResults = ( + results: TBatchResult[], + config: TGetConfig +): void => { + const enrichedResults = results.map((item, i) => ({ ...item, name: config.data[i] })) + const packuments = enrichedResults + .filter(isResultSuccessful) + .map(({ name, value }) => ({ name, value })) + const successfulPackages = packuments.map(({ name }) => ({ name })) + const failedPackages = enrichedResults + .filter(isResultFailed) + .map(item => ({ name: item.name, error: getErrorMessage(item) })) + + if (config.batch?.jsonOutput) { + printResultsJson({ + successfulPackages, + failedPackages, + packuments + }) + return + } + + writeToFile(config.batch?.path as string, packuments) + + printResults( + successfulPackages, + failedPackages, + ['name'], + ['name', 'error'], + `Packuments of following packages have been written to ${config.batch?.path}:`, + 'Packuments of following packages have not been downloaded because of errors:' + ) +} diff --git a/packages/cli-api/src/main/ts/executors/index.ts b/packages/cli-api/src/main/ts/executors/index.ts index 2871cb8..e305b4a 100644 --- a/packages/cli-api/src/main/ts/executors/index.ts +++ b/packages/cli-api/src/main/ts/executors/index.ts @@ -1 +1,3 @@ export * from './deprecate' +export * from './publish' +export * from './get' diff --git a/packages/cli-api/src/main/ts/executors/publish.ts b/packages/cli-api/src/main/ts/executors/publish.ts index 49ef819..1d61e18 100644 --- a/packages/cli-api/src/main/ts/executors/publish.ts +++ b/packages/cli-api/src/main/ts/executors/publish.ts @@ -41,7 +41,7 @@ export const processPublishResults = (results: TBatchResult[], c })) if (config.batch?.jsonOutput) { - printResultsJson(successfulPackages, failedPackages) + printResultsJson({ successfulPackages, failedPackages }) return } diff --git a/packages/cli-api/src/main/ts/interfaces.ts b/packages/cli-api/src/main/ts/interfaces.ts index d2d6cf4..6ce2ca2 100644 --- a/packages/cli-api/src/main/ts/interfaces.ts +++ b/packages/cli-api/src/main/ts/interfaces.ts @@ -1,7 +1,7 @@ import { IDeprecatePackageParams, TNpmRegClientAuth, TTarballOpts } from '@qiwi/npm-batch-client' import { IComplexDelay } from 'push-it-to-the-limit' -export type TNpmAction = 'deprecate' | 'un-deprecate' | 'publish' +export type TNpmAction = 'deprecate' | 'un-deprecate' | 'publish' | 'get' export type TRateLimit = IComplexDelay | IComplexDelay[] @@ -12,7 +12,8 @@ export interface IBaseConfig { batch?: { ratelimit?: TRateLimit, skipErrors?: boolean, - jsonOutput?: boolean + jsonOutput?: boolean, + path?: string }, data: T, } @@ -21,6 +22,8 @@ export type TPublishConfig = IBaseConfig> export type TDeprecationConfig = IBaseConfig> +export type TGetConfig = IBaseConfig + export interface ICliArgs { config: string } diff --git a/packages/cli-api/src/main/ts/runner.ts b/packages/cli-api/src/main/ts/runner.ts index f7595c8..54b7dd4 100644 --- a/packages/cli-api/src/main/ts/runner.ts +++ b/packages/cli-api/src/main/ts/runner.ts @@ -1,7 +1,12 @@ -import { performDeprecation } from './executors' -import { performPublish } from './executors/publish' +import { performDeprecation, performGet,performPublish } from './executors' import { ICliArgs } from './interfaces' -import { readFileToString, validateBaseConfig, validateDeprecationConfig, validatePublishConfig } from './utils' +import { + readFileToString, + validateBaseConfig, + validateDeprecationConfig, + validateGetConfig, + validatePublishConfig +} from './utils' export const run = (configString: string): Promise => { const rawConfig = JSON.parse(configString) @@ -16,6 +21,10 @@ export const run = (configString: string): Promise => { const publishConfig = validatePublishConfig(validatedConfig) return performPublish(publishConfig) } + case 'get': { + const getConfig = validateGetConfig(validatedConfig) + return performGet(getConfig) + } default: throw new Error(`Action ${validatedConfig.action} is not supported`) } diff --git a/packages/cli-api/src/main/ts/utils/misc.ts b/packages/cli-api/src/main/ts/utils/misc.ts index 9e49302..5ae5258 100644 --- a/packages/cli-api/src/main/ts/utils/misc.ts +++ b/packages/cli-api/src/main/ts/utils/misc.ts @@ -1,6 +1,6 @@ import { NpmRegClientWrapper, RegClient } from '@qiwi/npm-batch-client' import assert from 'assert' -import { readFileSync } from 'fs' +import { readFileSync, writeFileSync } from 'fs' import { defaultRateLimit } from '../default' import { IBaseConfig } from '../interfaces' @@ -15,16 +15,12 @@ export const assertString = (value: any, name: string): void => { } export const printResultsJson = ( - successfulPackages: Array, - failedPackages: Array, + results: Record, logger = console ): void => { logger.log( JSON.stringify( - { - successfulPackages, - failedPackages - }, + results, null, // eslint-disable-line unicorn/no-null '\t' ) @@ -60,3 +56,11 @@ export const npmRegClientWrapperFactory = ( config.auth, withRateLimit(regClient, config.batch?.ratelimit || defaultRateLimit, limitedMethods) ) + +export const writeToFile = ( + path: string, + body: Record +): void => writeFileSync( + path, + JSON.stringify(body, null, '\t') // eslint-disable-line unicorn/no-null +) diff --git a/packages/cli-api/src/main/ts/utils/validators.ts b/packages/cli-api/src/main/ts/utils/validators.ts index 572adba..92ea61b 100644 --- a/packages/cli-api/src/main/ts/utils/validators.ts +++ b/packages/cli-api/src/main/ts/utils/validators.ts @@ -1,6 +1,6 @@ import assert from 'assert' -import { IBaseConfig, TDeprecationConfig, TPublishConfig } from '../interfaces' +import { IBaseConfig, TDeprecationConfig, TGetConfig, TPublishConfig } from '../interfaces' import { assertString } from './misc' const isObject = (data: any) => typeof data === 'object' && data !== null @@ -23,7 +23,7 @@ export const validateBaseConfig = (config: any): IBaseConfig => { // eslint-disa } export const validateDeprecationConfig = (config: IBaseConfig): TDeprecationConfig => { - assert.ok(Array.isArray(config.data), 'Data in config file should be an array') + assert.ok(Array.isArray(config.data), 'Data in config file should be an array') // eslint-disable-line sonarjs/no-duplicate-string config.data.forEach(({ packageName, version, message }) => { assertString(packageName, 'packageName') assertString(version, 'version') @@ -33,7 +33,7 @@ export const validateDeprecationConfig = (config: IBaseConfig): TDeprecationConf } export const validatePublishConfig = (config: IBaseConfig): TPublishConfig => { - assert.ok(Array.isArray(config.data), 'Data in config file should be an array') + assert.ok(Array.isArray(config.data), 'Data in config file should be an array') // eslint-disable-line sonarjs/no-duplicate-string config.data.forEach(({ name, version, filePath, access }) => { assertString(name, 'name') assertString(version, 'version') @@ -42,3 +42,12 @@ export const validatePublishConfig = (config: IBaseConfig): TPublishConfig => { }) return config } + +export const validateGetConfig = (config: IBaseConfig): TGetConfig => { + assert.ok(Array.isArray(config.data), 'Data in config file should be an array') // eslint-disable-line sonarjs/no-duplicate-string + if (!config.batch?.jsonOutput) { + assertString(config.batch?.path, 'batch.path') + } + config.data.forEach(name => assertString(name, 'name')) + return config +} diff --git a/packages/cli-api/src/test/ts/executors/deprecate.ts b/packages/cli-api/src/test/ts/executors/deprecate.ts index b92dd6e..5ec0bae 100644 --- a/packages/cli-api/src/test/ts/executors/deprecate.ts +++ b/packages/cli-api/src/test/ts/executors/deprecate.ts @@ -97,7 +97,10 @@ describe('processResults', () => { await performDeprecation({ ...config, batch: { jsonOutput: true }}, npmClientMock as any) - expect(printResultsJsonSpy).toHaveBeenCalledWith([], []) + expect(printResultsJsonSpy).toHaveBeenCalledWith({ + successfulResults: [], + failedResults: [] + }) }) }) diff --git a/packages/cli-api/src/test/ts/executors/get.ts b/packages/cli-api/src/test/ts/executors/get.ts new file mode 100644 index 0000000..9ac391a --- /dev/null +++ b/packages/cli-api/src/test/ts/executors/get.ts @@ -0,0 +1,130 @@ +import { Packument, TBatchResult } from '@qiwi/npm-batch-client' + +import { TGetConfig } from '../../../main/ts' +import { performGet, processGetResults } from '../../../main/ts/executors/get' +import * as misc from '../../../main/ts/utils/misc' + +const registryUrl = 'http://localhost' + +const config: TGetConfig = { + registryUrl, + auth: { + username: 'username', + password: 'password', + email: 'email@email.email' + }, + batch: { + jsonOutput: true, + skipErrors: true + }, + action: 'get', + data: [] +} + +beforeEach(jest.restoreAllMocks) + +describe('performGet', () => { + it('calls getBatch', async () => { + const npmClientMock = { + getBatch: jest.fn(() => Promise.resolve([])) + } + const printResultsJsonSpy = jest.spyOn(misc, 'printResultsJson') + .mockImplementation(() => { /* noop */ + }) + + await performGet(config, npmClientMock as any) + + expect(npmClientMock.getBatch).toHaveBeenCalledWith(config.data, true) + expect(printResultsJsonSpy).toHaveBeenCalledWith({ + failedPackages: [], + successfulPackages: [], + packuments: [] + }) + }) +}) + +describe('processGetResults', () => { + const results: TBatchResult[] = [ + { + status: 'fulfilled', + value: {} as Packument + }, + { + status: 'fulfilled', + value: undefined as any + }, + { + status: 'rejected', + reason: 'error' + }, + { + status: 'rejected', + reason: new Error('error') + }, + { + status: 'rejected', + reason: undefined + } + ] + + it('handles results and writes them to a file', () => { + const customConfig = { + ...config, + batch: { path: 'foo' }, + data: ['foo', 'bar', 'baz', 'bat', 'qux'] + } + const printResults = jest.spyOn(misc, 'printResults') + .mockImplementation(() => { /* noop */ + }) + const writeFileSyncSpy = jest.spyOn(misc, 'writeToFile') + .mockImplementation(() => { /* noop */ + }) + const printResultsJsonSpy = jest.spyOn(misc, 'printResultsJson') + .mockImplementation(() => { /* noop */ + }) + + processGetResults(results, customConfig) + + expect(printResultsJsonSpy).not.toHaveBeenCalled() + expect(writeFileSyncSpy).toHaveBeenCalledWith( + 'foo', + [{ name: 'foo', value: {} }], + ) + expect(printResults).toHaveBeenCalled() + }) + + it('prints results in json', () => { + const customConfig = { + ...config, + batch: { jsonOutput: true }, + data: ['foo', 'bar', 'baz', 'bat', 'qux'] + } + + const printResults = jest.spyOn(misc, 'printResults') + .mockImplementation(() => { /* noop */ + }) + const writeFileSyncSpy = jest.spyOn(misc, 'writeToFile') + .mockImplementation(() => { /* noop */ + }) + const printResultsJsonSpy = jest.spyOn(misc, 'printResultsJson') + .mockImplementation(() => { /* noop */ + }) + + processGetResults(results, customConfig) + + expect(printResults).not.toHaveBeenCalled() + expect(writeFileSyncSpy).not.toHaveBeenCalled() + expect(printResultsJsonSpy).toHaveBeenCalledWith({ + successfulPackages: [ + { name: 'foo' }, + ], + failedPackages: [ + { name: 'bar', error: 'got undefined instead of Packument' }, + { name: 'baz', error: 'error' }, + { name: 'bat', error: 'error' }, + { name: 'qux', error: undefined }, + ], + packuments: [{ name: 'foo', value: {} }] + }) + }) +}) diff --git a/packages/cli-api/src/test/ts/executors/publish.ts b/packages/cli-api/src/test/ts/executors/publish.ts index f074740..3383c4f 100644 --- a/packages/cli-api/src/test/ts/executors/publish.ts +++ b/packages/cli-api/src/test/ts/executors/publish.ts @@ -33,7 +33,7 @@ describe('performPublish', () => { await performPublish(config, npmClientMock as any) expect(npmClientMock.publishBatch).toHaveBeenCalledWith(config.data) - expect(printResultsJsonSpy).toHaveBeenCalledWith([], []) + expect(printResultsJsonSpy).toHaveBeenCalledWith({ successfulPackages: [], failedPackages: [] }) }) }) @@ -85,9 +85,9 @@ describe('processPublishResults', () => { processPublishResults(results, nonEmptyConfig) - expect(printResultsJsonSpy).toHaveBeenCalledWith( - [nonEmptyConfig.data[0]], - [ + expect(printResultsJsonSpy).toHaveBeenCalledWith({ + successfulPackages: [nonEmptyConfig.data[0]], + failedPackages: [ { ...nonEmptyConfig.data[1], error: 'no data', @@ -97,7 +97,7 @@ describe('processPublishResults', () => { error: 'foo' } ] - ) + }) }) it('calls printResults when jsonOutput flag is not set', () => { diff --git a/packages/cli-api/src/test/ts/misc.ts b/packages/cli-api/src/test/ts/misc.ts index bb26a3a..c46f456 100644 --- a/packages/cli-api/src/test/ts/misc.ts +++ b/packages/cli-api/src/test/ts/misc.ts @@ -62,7 +62,10 @@ describe('printResultsJson', () => { } const stringifySpy = jest.spyOn(JSON, 'stringify') .mockImplementation(() => '') - printResultsJson([], [], consoleMock as any) + printResultsJson( + { successfulPackages: [], failedPackages: [] }, + consoleMock as any + ) expect(stringifySpy).toHaveBeenCalled() expect(consoleMock.log).toHaveBeenCalled() }) diff --git a/packages/cli-api/src/test/ts/runner.ts b/packages/cli-api/src/test/ts/runner.ts index 4eee2b4..4741f2b 100644 --- a/packages/cli-api/src/test/ts/runner.ts +++ b/packages/cli-api/src/test/ts/runner.ts @@ -1,5 +1,6 @@ import { IBaseConfig, readConfigAndRun } from '../../main/ts' import * as deprecation from '../../main/ts/executors/deprecate' +import * as get from '../../main/ts/executors/get' import * as publish from '../../main/ts/executors/publish' import * as utils from '../../main/ts/utils/misc' import * as validators from '../../main/ts/utils/validators' @@ -47,6 +48,15 @@ describe('readConfigAndRun', () => { expect(spy).toHaveBeenCalled() }) + it('calls performGet for get', () => { + mockOutput() + jest.spyOn(utils, 'readFileToString') + .mockImplementation(() => JSON.stringify({ ...config, action: 'get', batch: { path: '' } })) + const spy = jest.spyOn(get, 'performGet') + readConfigAndRun({ config: 'foo' }) + expect(spy).toHaveBeenCalled() + }) + it('calls performDeprecation for un-deprecate', () => { mockOutput() diff --git a/packages/cli-api/src/test/ts/utils/validators.ts b/packages/cli-api/src/test/ts/utils/validators.ts index 5a23ec1..be2c79f 100644 --- a/packages/cli-api/src/test/ts/utils/validators.ts +++ b/packages/cli-api/src/test/ts/utils/validators.ts @@ -1,4 +1,9 @@ -import { validateBaseConfig, validateDeprecationConfig, validatePublishConfig } from '../../../main/ts' +import { + validateBaseConfig, + validateDeprecationConfig, + validateGetConfig, + validatePublishConfig +} from '../../../main/ts' type TTestCase = { description: string @@ -216,3 +221,64 @@ describe('validatePublishConfig', () => { testCases.forEach(validatorTestFactory(validatePublishConfig)) }) + +describe('validateGetConfig', () => { + const testCases: TTestCase[] = [ + ...commonTestCases.map(testCase => ({ + ...testCase, + input: { + ...testCase.input, + batch: { path: 'foo' } + } + })), + { + description: 'allows string data', + input: { + auth, + action: 'get', + batch: { + jsonOutput: true, + }, + data: [ + 'foo', + 'bar' + ] + }, + success: true, + }, + { + description: 'does not allow mixed wrong and correct data typees', + input: { + auth, + action: 'get', + batch: { + path: 'foo' + }, + data: [ + 'foo', + undefined, + 'bar', + ] + }, + success: false, + }, + { + description: 'does not allow config without path', + input: { + auth, + action: 'get', + batch: { + path: 'foo' + }, + data: [ + 'foo', + undefined, + 'bar', + ] + }, + success: false, + } + ] + + testCases.forEach(validatorTestFactory(validateGetConfig)) +}) diff --git a/packages/cli/README.md b/packages/cli/README.md index 1f9932f..4bf6b78 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -100,6 +100,135 @@ Following packages are published successfully: │ 2 │ '@test/package-15-01-21-3' │ '1.0.0' │ 'test-package-15-01-21-2.tar.gz' │ 'public' │ └─────────┴────────────────────────────┴─────────┴──────────────────────────────────┴──────────┘ ``` +## Getting +Packuments (json files with meta from NPM-registry) of given packages will be written to a file, specified by `batch.path`. +```json +{ + "registryUrl": "https://registry.npmjs.org", + "auth": { + "username": "username", + "password": "password", + "email": "email@email.com" + }, + "batch": { + "path": "results.json", + "skipErrors": true + }, + "action": "get", + "data": [ + "gen-tree-lib", + "react-dom", + "@qiwi/foo" + ] +} +``` +Output in console: +```text +Packuments of following packages have been written to results.json: +┌─────────┬────────────────┐ +│ (index) │ name │ +├─────────┼────────────────┤ +│ 0 │ 'gen-tree-lib' │ +│ 1 │ 'react-dom' │ +└─────────┴────────────────┘ +Packuments of following packages have not been downloaded because of errors: +┌─────────┬─────────────┬─────────────────────────┐ +│ (index) │ name │ error │ +├─────────┼─────────────┼─────────────────────────┤ +│ 0 │ '@qiwi/foo' │ 'Not found : @qiwi/foo' │ +└─────────┴─────────────┴─────────────────────────┘ + +``` +results.json: +```text +[ + { + "name": "gen-tree-lib", + "value": { + "_id": "gen-tree-lib", + "_rev": "48-583faf615cd38b2ad8c28e6c47bac7ec", + "name": "gen-tree-lib", + "dist-tags": { + "latest": "1.8.0" + }, + ... + } + }, + { + "name": "react-dom", + "value": { + "_id": "react-dom", + "_rev": "619-c672e11f0a03532f37e89a9ea3a57551", + "name": "react-dom", + "description": "React package for working with the DOM.", + "dist-tags": { + "latest": "17.0.1", + "next": "0.0.0-8e5adfbd7", + "experimental": "0.0.0-experimental-27659559e", + "untagged": "16.14.0" + }, + ... + } + } +] +``` +If `batch.jsonOutput` is `true` then utility will log all output in JSON format. +```json +{ + "registryUrl": "https://registry.npmjs.org", + "auth": { + "username": "username", + "password": "password", + "email": "email@email.com" + }, + "batch": { + "jsonOutput": true, + "skipErrors": true + }, + "action": "get", + "data": [ + "gen-tree-lib", + "react-dom", + "@qiwi/foo" + ] +} +``` +Output: +```text +{ + "successfulPackages": [ + { + "name": "gen-tree-lib" + }, + { + "name": "react-dom" + } + ], + "failedPackages": [ + { + "name": "@qiwi/foo", + "error": "Not found : @qiwi/foo" + } + ], + "packuments": [ + { + "name": "gen-tree-lib", + "value": { + "_id": "gen-tree-lib", + "_rev": "48-583faf615cd38b2ad8c28e6c47bac7ec", + "name": "gen-tree-lib", + "dist-tags": { + "latest": "1.8.0" + }, + "versions": { + ... + } + } + }, + ... + ] +} +``` # Authorization You can use authorization via token as in example of [deprecation](#deprecationun-deprecation), or username/password and email as in example of [publishing](#publishing) # Configuration @@ -108,7 +237,7 @@ You can specify configuration options in `batch` root field of config object. Utility limits request rate to registry. By default, utility makes maximum 10 requests per second. You can specify your own rate limit. In this example maximum 2 requests per 500 ms will be made. -```json +```text { "registryUrl": "https://registry.npmjs.org", "auth": { @@ -126,7 +255,7 @@ In this example maximum 2 requests per 500 ms will be made. } ``` You can specify several rate limits: -```json +```text { "registryUrl": "https://registry.npmjs.org", "auth": { @@ -153,7 +282,7 @@ You can specify several rate limits: ``` ## Other settings Flag `skipErrors` allows utility to continue on errors. -```json +```text { ... "batch": { @@ -163,7 +292,7 @@ Flag `skipErrors` allows utility to continue on errors. } ``` Flag `jsonOutput` prints result in JSON format. -```json +```text { ... "batch": { diff --git a/packages/client/src/main/ts/interfaces.ts b/packages/client/src/main/ts/interfaces.ts index 25c1719..59db551 100644 --- a/packages/client/src/main/ts/interfaces.ts +++ b/packages/client/src/main/ts/interfaces.ts @@ -74,3 +74,7 @@ export type TNpmRegClientAuth = { token: string, alwaysAuth?: boolean } + +export { + Packument +} diff --git a/packages/client/src/main/ts/wrapper.ts b/packages/client/src/main/ts/wrapper.ts index 413d87e..6ab0e79 100644 --- a/packages/client/src/main/ts/wrapper.ts +++ b/packages/client/src/main/ts/wrapper.ts @@ -75,10 +75,15 @@ export class NpmRegClientWrapper implements INpmRegClientWrapper { get(packageName: string): Promise { return new Promise( (resolve, reject) => { + const callback = NpmRegClientWrapper.callbackFactory(resolve, reject) try { - this.client.get(this.getPackageUrl(packageName), {}, (_, data) => resolve(data)) + this.client.get( + this.getPackageUrl(packageName), + { auth: this.auth }, + callback + ) } catch (e) { - reject(e) + callback(e) } } ) @@ -140,7 +145,7 @@ export class NpmRegClientWrapper implements INpmRegClientWrapper { ) { return ( err: any, // eslint-disable-line @typescript-eslint/explicit-module-boundary-types - data: any, // eslint-disable-line @typescript-eslint/explicit-module-boundary-types + data?: any, // eslint-disable-line @typescript-eslint/explicit-module-boundary-types ): void => { if (err) { reject(err) diff --git a/yarn.lock b/yarn.lock index 9e40b3a..6170521 100644 --- a/yarn.lock +++ b/yarn.lock @@ -316,10 +316,10 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@eslint/eslintrc@^0.2.2": - version "0.2.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.2.2.tgz#d01fc791e2fc33e88a29d6f3dc7e93d0cd784b76" - integrity sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ== +"@eslint/eslintrc@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.3.0.tgz#d736d6963d7003b6514e6324bec9c602ac340318" + integrity sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg== dependencies: ajv "^6.12.4" debug "^4.1.1" @@ -328,7 +328,7 @@ ignore "^4.0.6" import-fresh "^3.2.1" js-yaml "^3.13.1" - lodash "^4.17.19" + lodash "^4.17.20" minimatch "^3.0.4" strip-json-comments "^3.1.1" @@ -1679,9 +1679,9 @@ integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= "@types/lodash@^4.14.163": - version "4.14.167" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.167.tgz#ce7d78553e3c886d4ea643c37ec7edc20f16765e" - integrity sha512-w7tQPjARrvdeBkX/Rwg95S592JwxqOjmms3zWQ0XZgSyxSLdzWaYH3vErBhdVS/lRBX7F8aBYcYJYTr5TMGOzw== + version "4.14.168" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008" + integrity sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q== "@types/meow@^5.0.0": version "5.0.0" @@ -3308,22 +3308,24 @@ es-abstract@^1.17.0-next.1: string.prototype.trimstart "^1.0.1" es-abstract@^1.18.0-next.1: - version "1.18.0-next.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68" - integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA== + version "1.18.0-next.2" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.2.tgz#088101a55f0541f595e7e057199e27ddc8f3a5c2" + integrity sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw== dependencies: + call-bind "^1.0.2" es-to-primitive "^1.2.1" function-bind "^1.1.1" + get-intrinsic "^1.0.2" has "^1.0.3" has-symbols "^1.0.1" is-callable "^1.2.2" - is-negative-zero "^2.0.0" + is-negative-zero "^2.0.1" is-regex "^1.1.1" - object-inspect "^1.8.0" + object-inspect "^1.9.0" object-keys "^1.1.1" - object.assign "^4.1.1" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.3" + string.prototype.trimstart "^1.0.3" es-to-primitive@^1.2.1: version "1.2.1" @@ -3570,12 +3572,12 @@ eslint-visitor-keys@^2.0.0: integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== eslint@^7.16.0: - version "7.17.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.17.0.tgz#4ccda5bf12572ad3bf760e6f195886f50569adb0" - integrity sha512-zJk08MiBgwuGoxes5sSQhOtibZ75pz0J35XTRlZOk9xMffhpA9BTbQZxoXZzOl5zMbleShbGwtw+1kGferfFwQ== + version "7.18.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.18.0.tgz#7fdcd2f3715a41fe6295a16234bd69aed2c75e67" + integrity sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ== dependencies: "@babel/code-frame" "^7.0.0" - "@eslint/eslintrc" "^0.2.2" + "@eslint/eslintrc" "^0.3.0" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -3599,7 +3601,7 @@ eslint@^7.16.0: js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" - lodash "^4.17.19" + lodash "^4.17.20" minimatch "^3.0.4" natural-compare "^1.4.0" optionator "^0.9.1" @@ -3794,9 +3796,9 @@ fast-glob@^2.2.6: micromatch "^3.1.10" fast-glob@^3.1.1: - version "3.2.4" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" - integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== + version "3.2.5" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" + integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -4754,7 +4756,7 @@ is-glob@^4.0.0, is-glob@^4.0.1: dependencies: is-extglob "^2.1.1" -is-negative-zero@^2.0.0: +is-negative-zero@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== @@ -7251,9 +7253,9 @@ regex-not@^1.0.0, regex-not@^1.0.2: safe-regex "^1.1.0" regexp-tree@^0.1.20, regexp-tree@^0.1.21, regexp-tree@~0.1.1: - version "0.1.21" - resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.21.tgz#55e2246b7f7d36f1b461490942fa780299c400d7" - integrity sha512-kUUXjX4AnqnR8KRTCrayAo9PzYMRKmVoGgaz2tBuz0MF3g1ZbGebmtW0yFHfFK9CmBjQKeYIgoL22pFLBJY7sw== + version "0.1.22" + resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.22.tgz#495bb485bc25422f1967b85d71fac0e9d731aa1b" + integrity sha512-ExKDwSwgv6tAMeaq8RTBQFMHdpnDMx0O07mu6xaLIhC5EDQTQlNlH42ec6uvPNlTAPC3stNVGQcy0WQtXypQKw== regexp.prototype.flags@^1.3.0: version "1.3.1" @@ -7953,7 +7955,7 @@ string.prototype.matchall@^4.0.2: regexp.prototype.flags "^1.3.0" side-channel "^1.0.3" -string.prototype.trimend@^1.0.1: +string.prototype.trimend@^1.0.1, string.prototype.trimend@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz#a22bd53cca5c7cf44d7c9d5c732118873d6cd18b" integrity sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw== @@ -7961,7 +7963,7 @@ string.prototype.trimend@^1.0.1: call-bind "^1.0.0" define-properties "^1.1.3" -string.prototype.trimstart@^1.0.1: +string.prototype.trimstart@^1.0.1, string.prototype.trimstart@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz#9b4cb590e123bb36564401d59824298de50fd5aa" integrity sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg== @@ -8438,15 +8440,15 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typedoc-default-themes@0.12.1: - version "0.12.1" - resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.12.1.tgz#6c4a759f9dc365b4021579587b3773deb6fb6eeb" - integrity sha512-6PEvV+/kWAJeUwEtrKgIsZQSbybW5DGCr6s2mMjHsDplpgN8iBHI52UbA+2C+c2TMCxBNMK9TMS6pdeIdwsLSw== +typedoc-default-themes@^0.12.4: + version "0.12.4" + resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.12.4.tgz#5cbb79c1d6421f1274e86b1b542934eb557abd4f" + integrity sha512-EZiXBUpogsYWe0dLgy47J8yRZCd+HAn9woGzO28XJxxSCSwZRYGKeQiw1KjyIcm3cBtLWUXiPD5+Bgx24GgZjg== typedoc@^0.20.0: - version "0.20.14" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.20.14.tgz#894ff71841a4abbe8f46cf52f3cc96c9d68328dc" - integrity sha512-9bsZp5/qkl+gDSv9DRvHbfbY8Sr0tD8fKx7hNIvcluxeAFzBCEo9o0qDCdLUZw+/axbfd9TaqHvSuCVRu+YH6Q== + version "0.20.16" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.20.16.tgz#c845d32883af905439607ba03c9667b81cdbeb22" + integrity sha512-xqIL8lT6ZE3QpP0GN30ckeTR05NSEkrP2pXQlNhC0OFkbvnjqJtDUcWSmCO15BuYyu4qsEbZT+tKYFEAt9Jxew== dependencies: colors "^1.4.0" fs-extra "^9.0.1" @@ -8458,7 +8460,7 @@ typedoc@^0.20.0: progress "^2.0.3" shelljs "^0.8.4" shiki "^0.2.7" - typedoc-default-themes "0.12.1" + typedoc-default-themes "^0.12.4" typescript-compiler@^1.4.1-2: version "1.4.1-2"