diff --git a/lib/util/json-writer/__fixtures__/.global_editorconfig b/lib/util/json-writer/__fixtures__/.global_editorconfig new file mode 100644 index 0000000000000000000000000000000000000000..712d48e6c0ceddf677a32154939d52c223008cdd --- /dev/null +++ b/lib/util/json-writer/__fixtures__/.global_editorconfig @@ -0,0 +1,3 @@ +[*] +indent_style = space +indent_size = 6 diff --git a/lib/util/json-writer/__fixtures__/.json_editorconfig b/lib/util/json-writer/__fixtures__/.json_editorconfig new file mode 100644 index 0000000000000000000000000000000000000000..c7a221961de91adb5ec293506dc93d9706b634bd --- /dev/null +++ b/lib/util/json-writer/__fixtures__/.json_editorconfig @@ -0,0 +1,2 @@ +[*.json] +indent_style = tab diff --git a/lib/util/json-writer/__fixtures__/.non_json_editorconfig b/lib/util/json-writer/__fixtures__/.non_json_editorconfig new file mode 100644 index 0000000000000000000000000000000000000000..01c783a597d3d9203014c70965d3c498abd362dd --- /dev/null +++ b/lib/util/json-writer/__fixtures__/.non_json_editorconfig @@ -0,0 +1,3 @@ +[*.py] +indent_style = space +indent_size = 6 diff --git a/lib/util/json-writer/code-format.ts b/lib/util/json-writer/code-format.ts new file mode 100644 index 0000000000000000000000000000000000000000..2e86f0f592268fb91ece3bd131eb7f2836183b83 --- /dev/null +++ b/lib/util/json-writer/code-format.ts @@ -0,0 +1,6 @@ +import type { IndentationType } from './indentation-type'; + +export interface CodeFormat { + indentationSize?: number; + indentationType?: IndentationType; +} diff --git a/lib/util/json-writer/editor-config.spec.ts b/lib/util/json-writer/editor-config.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..b3bbe22780585f76c95075855b11658c10c4f2b2 --- /dev/null +++ b/lib/util/json-writer/editor-config.spec.ts @@ -0,0 +1,66 @@ +import mockFs from 'mock-fs'; +import { loadFixture } from '../../../test/util'; +import { configFileNames } from '../../config/app-strings'; +import { setGlobalConfig } from '../../config/global'; +import { EditorConfig } from './editor-config'; +import { IndentationType } from './indentation-type'; + +const defaultConfigFile = configFileNames[0]; + +const GLOBAL_EDITOR_CONFIG = loadFixture('.global_editorconfig', '.'); +const JSON_FILES_EDITOR_CONFIG = loadFixture('.json_editorconfig', '.'); +const NON_JSON_FILES_EDITOR_CONFIG = loadFixture('.non_json_editorconfig', '.'); + +describe('util/json-writer/editor-config', () => { + beforeAll(() => { + setGlobalConfig({ + localDir: '', + }); + }); + + afterEach(() => { + mockFs.restore(); + }); + + it('should handle empty .editorconfig file', async () => { + expect.assertions(2); + mockFs({ + '.editorconfig': '', + }); + const format = await EditorConfig.getCodeFormat(defaultConfigFile); + + expect(format.indentationSize).toBeUndefined(); + expect(format.indentationType).toBeUndefined(); + }); + + it('should handle global config from .editorconfig', async () => { + expect.assertions(2); + mockFs({ + '.editorconfig': GLOBAL_EDITOR_CONFIG, + }); + const format = await EditorConfig.getCodeFormat(defaultConfigFile); + expect(format.indentationSize).toBe(6); + expect(format.indentationType).toBe(IndentationType.Space); + }); + + it('should not handle non json config from .editorconfig', async () => { + expect.assertions(2); + mockFs({ + '.editorconfig': NON_JSON_FILES_EDITOR_CONFIG, + }); + const format = await EditorConfig.getCodeFormat(defaultConfigFile); + + expect(format.indentationSize).toBeUndefined(); + expect(format.indentationType).toBeUndefined(); + }); + + it('should handle json config from .editorconfig', async () => { + expect.assertions(1); + mockFs({ + '.editorconfig': JSON_FILES_EDITOR_CONFIG, + }); + const format = await EditorConfig.getCodeFormat(defaultConfigFile); + + expect(format.indentationType).toBe(IndentationType.Tab); + }); +}); diff --git a/lib/util/json-writer/editor-config.ts b/lib/util/json-writer/editor-config.ts new file mode 100644 index 0000000000000000000000000000000000000000..33bc638642fb33e03235f4b1c7d49d80d75332b6 --- /dev/null +++ b/lib/util/json-writer/editor-config.ts @@ -0,0 +1,45 @@ +import { KnownProps, parse } from 'editorconfig'; +import { join } from 'upath'; +import { getGlobalConfig } from '../../config/global'; +import type { CodeFormat } from './code-format'; +import { IndentationType } from './indentation-type'; + +export class EditorConfig { + public static async getCodeFormat(fileName: string): Promise<CodeFormat> { + const { localDir } = getGlobalConfig(); + const knownProps = await parse(join(localDir, fileName)); + + return { + indentationSize: EditorConfig.getIndentationSize(knownProps), + indentationType: EditorConfig.getIndentationType(knownProps), + }; + } + + private static getIndentationType( + knownProps: KnownProps + ): IndentationType | undefined { + const { indent_style: indentStyle } = knownProps; + + if (indentStyle === 'tab') { + return IndentationType.Tab; + } + + if (indentStyle === 'space') { + return IndentationType.Space; + } + + return undefined; + } + + private static getIndentationSize( + knownProps: KnownProps + ): number | undefined { + const indentSize = Number(knownProps.indent_size); + + if (!Number.isNaN(indentSize) && Number.isInteger(indentSize)) { + return indentSize; + } + + return undefined; + } +} diff --git a/lib/util/json-writer/indentation-type.ts b/lib/util/json-writer/indentation-type.ts new file mode 100644 index 0000000000000000000000000000000000000000..b8006b6442311668c5ce3a282845d668165c9404 --- /dev/null +++ b/lib/util/json-writer/indentation-type.ts @@ -0,0 +1,4 @@ +export enum IndentationType { + Space = 'space', + Tab = 'tab', +} diff --git a/lib/util/json-writer/index.ts b/lib/util/json-writer/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..596b81eda6afa0de37ad74bea167724839280946 --- /dev/null +++ b/lib/util/json-writer/index.ts @@ -0,0 +1,3 @@ +export * from './json-writer'; +export * from './editor-config'; +export * from './indentation-type'; diff --git a/lib/util/json-writer/json-writer.spec.ts b/lib/util/json-writer/json-writer.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..aa7ea661c65afa048be5d3205f8675632c6bd6ca --- /dev/null +++ b/lib/util/json-writer/json-writer.spec.ts @@ -0,0 +1,44 @@ +import { IndentationType } from './indentation-type'; +import { JSONWriter } from './json-writer'; + +describe('util/json-writer/json-writer', () => { + const DATA = { + value: 1, + }; + + it('should apply 2 spaces indentation by default', () => { + const jsonWriter = new JSONWriter(); + + expect(jsonWriter.write(DATA)).toStrictEqual('{\n "value": 1\n}\n'); + }); + + it('should apply indentation size', () => { + const jsonWriter = new JSONWriter({ + indentationType: IndentationType.Space, + indentationSize: 10, + }); + + expect(jsonWriter.write(DATA)).toStrictEqual( + '{\n "value": 1\n}\n' + ); + }); + + it('should apply indentation type', () => { + const jsonWriter = new JSONWriter({ + indentationType: IndentationType.Tab, + }); + + expect(jsonWriter.write(DATA)).toStrictEqual('{\n\t"value": 1\n}\n'); + }); + + it('new line at the end should be optional', () => { + const jsonWriter = new JSONWriter({ + indentationType: IndentationType.Space, + indentationSize: 10, + }); + + expect(jsonWriter.write(DATA, false)).toStrictEqual( + '{\n "value": 1\n}' + ); + }); +}); diff --git a/lib/util/json-writer/json-writer.ts b/lib/util/json-writer/json-writer.ts new file mode 100644 index 0000000000000000000000000000000000000000..36c239eeba5e6c5e87db4a145c512d31308ff0c2 --- /dev/null +++ b/lib/util/json-writer/json-writer.ts @@ -0,0 +1,31 @@ +import { CodeFormat } from './code-format'; +import { IndentationType } from './indentation-type'; + +export class JSONWriter { + private readonly indentationType: IndentationType; + + private readonly indentationSize: number; + + constructor(codeFormat: CodeFormat = {}) { + this.indentationSize = codeFormat.indentationSize ?? 2; + this.indentationType = codeFormat.indentationType ?? IndentationType.Space; + } + + public write(json: unknown, newLineAtTheEnd = true): string { + let content = JSON.stringify(json, null, this.indentation); + + if (newLineAtTheEnd) { + content = content.concat('\n'); + } + + return content; + } + + private get indentation(): string | number { + if (this.indentationType === IndentationType.Tab) { + return '\t'; + } + + return this.indentationSize; + } +} diff --git a/lib/workers/repository/onboarding/branch/config.spec.ts b/lib/workers/repository/onboarding/branch/config.spec.ts index 28eaacb6d801f3478b327a8e379efd188d887d1b..7c9bc2e3157c8084bb02be7c98ab30254390cab7 100644 --- a/lib/workers/repository/onboarding/branch/config.spec.ts +++ b/lib/workers/repository/onboarding/branch/config.spec.ts @@ -1,4 +1,5 @@ import { RenovateConfig, getConfig } from '../../../../../test/util'; +import { setGlobalConfig } from '../../../../config/global'; import * as presets from '../../../../config/presets/local'; import { PRESET_DEP_NOT_FOUND } from '../../../../config/presets/util'; import { getOnboardingConfig, getOnboardingConfigContents } from './config'; @@ -9,16 +10,24 @@ const mockedPresets = presets as jest.Mocked<typeof presets>; describe('workers/repository/onboarding/branch/config', () => { let config: RenovateConfig; + + beforeAll(() => { + setGlobalConfig({ + localDir: '', + }); + }); + beforeEach(() => { jest.clearAllMocks(); config = getConfig(); config.platform = 'github'; config.repository = 'some/repo'; }); + describe('getOnboardingConfigContents', () => { it('returns the JSON stringified onboarding config', async () => { mockedPresets.getPreset.mockResolvedValueOnce({ enabled: true }); - const contents = await getOnboardingConfigContents(config); + const contents = await getOnboardingConfigContents(config, ''); expect(mockedPresets.getPreset).toHaveBeenCalledTimes(1); expect(contents).toEqual( '{\n' + diff --git a/lib/workers/repository/onboarding/branch/config.ts b/lib/workers/repository/onboarding/branch/config.ts index b96efdc78b735778e069f3f21b36773885fc0456..fa03d6e132a72cccadaaafe9286bff71bf7a74be 100644 --- a/lib/workers/repository/onboarding/branch/config.ts +++ b/lib/workers/repository/onboarding/branch/config.ts @@ -6,6 +6,7 @@ import type { } from '../../../../config/types'; import { logger } from '../../../../logger'; import { clone } from '../../../../util/clone'; +import { EditorConfig, JSONWriter } from '../../../../util/json-writer'; async function getOnboardingConfig( config: RenovateConfig @@ -72,10 +73,13 @@ async function getOnboardingConfig( } async function getOnboardingConfigContents( - config: RenovateConfig + config: RenovateConfig, + fileName: string ): Promise<string> { + const codeFormat = await EditorConfig.getCodeFormat(fileName); + const jsonWriter = new JSONWriter(codeFormat); const onboardingConfig = await getOnboardingConfig(config); - return JSON.stringify(onboardingConfig, null, 2) + '\n'; + return jsonWriter.write(onboardingConfig); } export { getOnboardingConfig, getOnboardingConfigContents }; diff --git a/lib/workers/repository/onboarding/branch/create.ts b/lib/workers/repository/onboarding/branch/create.ts index 972f6b602d06ef8812c41ad491d4313c99b0df40..a449e4d080d5635a17e32dd3401b7edf98e265ce 100644 --- a/lib/workers/repository/onboarding/branch/create.ts +++ b/lib/workers/repository/onboarding/branch/create.ts @@ -11,14 +11,14 @@ const defaultConfigFile = configFileNames[0]; export async function createOnboardingBranch( config: Partial<RenovateConfig> ): Promise<string | null> { - logger.debug('createOnboardingBranch()'); - const contents = await getOnboardingConfigContents(config); - logger.debug('Creating onboarding branch'); - const configFile = configFileNames.includes(config.onboardingConfigFileName) ? config.onboardingConfigFileName : defaultConfigFile; + logger.debug('createOnboardingBranch()'); + const contents = await getOnboardingConfigContents(config, configFile); + logger.debug('Creating onboarding branch'); + const commitMessageFactory = new OnboardingCommitMessageFactory( config, configFile diff --git a/lib/workers/repository/onboarding/branch/index.spec.ts b/lib/workers/repository/onboarding/branch/index.spec.ts index cea792f305188ef28824e4b51c82ffd386f6758e..08e7117d008bcbb729b45b7ce26599885280a0b8 100644 --- a/lib/workers/repository/onboarding/branch/index.spec.ts +++ b/lib/workers/repository/onboarding/branch/index.spec.ts @@ -7,6 +7,7 @@ import { mocked, platform, } from '../../../../../test/util'; +import { configFileNames } from '../../../../config/app-strings'; import { REPOSITORY_FORKED, REPOSITORY_NO_PACKAGE_FILES, @@ -88,12 +89,15 @@ describe('workers/repository/onboarding/branch/index', () => { git.getFileList.mockResolvedValue(['package.json']); fs.readLocalFile.mockResolvedValue('{}'); await checkOnboardingBranch(config); - expect(configModule.getOnboardingConfigContents).toHaveBeenCalledWith({ - ...config, - onboardingBranch: 'test', - renovateJsonPresent: true, - warnings: [], - }); + expect(configModule.getOnboardingConfigContents).toHaveBeenCalledWith( + { + ...config, + onboardingBranch: 'test', + renovateJsonPresent: true, + warnings: [], + }, + configFileNames[0] + ); // FIXME: explicit assert condition expect( git.commitFiles.mock.calls[0][0].files[0].contents diff --git a/lib/workers/repository/onboarding/branch/rebase.spec.ts b/lib/workers/repository/onboarding/branch/rebase.spec.ts index 4d3ea90d7d84a79179601dfa2aa6f1aa52c1c977..c0d6e04898d7506192e37761ec12d3cf40cd438c 100644 --- a/lib/workers/repository/onboarding/branch/rebase.spec.ts +++ b/lib/workers/repository/onboarding/branch/rebase.spec.ts @@ -1,9 +1,16 @@ import { RenovateConfig, defaultConfig, git } from '../../../../../test/util'; +import { setGlobalConfig } from '../../../../config/global'; import { rebaseOnboardingBranch } from './rebase'; jest.mock('../../../../util/git'); describe('workers/repository/onboarding/branch/rebase', () => { + beforeAll(() => { + setGlobalConfig({ + localDir: '', + }); + }); + describe('rebaseOnboardingBranch()', () => { let config: RenovateConfig; beforeEach(() => { diff --git a/lib/workers/repository/onboarding/branch/rebase.ts b/lib/workers/repository/onboarding/branch/rebase.ts index 2b0bcd276a5d3df361ba67bc1e26c250c984ac93..b905ebd9848c3a76cc60b3b5daae0993e5b60ee1 100644 --- a/lib/workers/repository/onboarding/branch/rebase.ts +++ b/lib/workers/repository/onboarding/branch/rebase.ts @@ -26,7 +26,7 @@ export async function rebaseOnboardingBranch( } const configFile = defaultConfigFile(config); const existingContents = await getFile(configFile, config.onboardingBranch); - const contents = await getOnboardingConfigContents(config); + const contents = await getOnboardingConfigContents(config, configFile); if ( contents === existingContents && !(await isBranchStale(config.onboardingBranch)) diff --git a/package.json b/package.json index 21309682bf2ad8c80860cd813f8002a00d6a2bb7..2b1e530575197a0886fac8cbed7e90107af6315c 100644 --- a/package.json +++ b/package.json @@ -144,6 +144,7 @@ "delay": "5.0.0", "dequal": "2.0.2", "detect-indent": "6.1.0", + "editorconfig": "0.15.3", "email-addresses": "5.0.0", "emoji-regex": "9.2.2", "emojibase": "5.2.0", @@ -262,6 +263,7 @@ "jest-mock-extended": "2.0.4", "jest-silent-reporter": "0.5.0", "markdownlint-cli2": "0.3.2", + "mock-fs": "5.1.1", "mockdate": "3.0.5", "nock": "13.1.4", "npm-run-all": "4.1.5", diff --git a/yarn.lock b/yarn.lock index 7ac8504d37af9f5579466e5e0a5dd48ca4066f80..e27199c45abd43ba43d3aab36938a452e0c85ed4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1483,7 +1483,6 @@ "@renovate/eslint-plugin@https://github.com/renovatebot/eslint-plugin#v0.0.3": version "0.0.1" - uid c88253170ce9e9248bc0653197ed2ff1ecf41ac1 resolved "https://github.com/renovatebot/eslint-plugin#c88253170ce9e9248bc0653197ed2ff1ecf41ac1" "@renovate/pep440@1.0.0": @@ -3066,6 +3065,11 @@ commander@8.3.0: resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== +commander@^2.19.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + common-ancestor-path@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz#4f7d2d1394d91b7abdf51871c62f71eadb0182a7" @@ -3578,6 +3582,16 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" +editorconfig@0.15.3: + version "0.15.3" + resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" + integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g== + dependencies: + commander "^2.19.0" + lru-cache "^4.1.5" + semver "^5.6.0" + sigmund "^1.0.1" + electron-to-chromium@^1.3.878: version "1.3.885" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.885.tgz#c8cec32fbc61364127849ae00f2395a1bae7c454" @@ -6156,6 +6170,14 @@ lowercase-keys@^2.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== +lru-cache@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -6556,6 +6578,11 @@ mkdirp@^0.5.1, mkdirp@~0.5.1: dependencies: minimist "^1.2.5" +mock-fs@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-5.1.1.tgz#d4c95e916abf400664197079d7e399d133bb6048" + integrity sha512-p/8oZ3qvfKGPw+4wdVCyjDxa6wn2tP0TCf3WXC1UyUBAevezPn1TtOoxtMYVbZu/S/iExg+Ghed1busItj2CEw== + mockdate@3.0.5: version "3.0.5" resolved "https://registry.yarnpkg.com/mockdate/-/mockdate-3.0.5.tgz#789be686deb3149e7df2b663d2bc4392bc3284fb" @@ -6901,76 +6928,76 @@ npm@^7.0.0: resolved "https://registry.yarnpkg.com/npm/-/npm-7.24.2.tgz#861117af8241bea592289f22407230e5300e59ca" integrity sha512-120p116CE8VMMZ+hk8IAb1inCPk4Dj3VZw29/n2g6UI77urJKVYb7FZUDW8hY+EBnfsjI/2yrobBgFyzo7YpVQ== dependencies: - "@isaacs/string-locale-compare" "*" - "@npmcli/arborist" "*" - "@npmcli/ci-detect" "*" - "@npmcli/config" "*" - "@npmcli/map-workspaces" "*" - "@npmcli/package-json" "*" - "@npmcli/run-script" "*" - abbrev "*" - ansicolors "*" - ansistyles "*" - archy "*" - cacache "*" - chalk "*" - chownr "*" - cli-columns "*" - cli-table3 "*" - columnify "*" - fastest-levenshtein "*" - glob "*" - graceful-fs "*" - hosted-git-info "*" - ini "*" - init-package-json "*" - is-cidr "*" - json-parse-even-better-errors "*" - libnpmaccess "*" - libnpmdiff "*" - libnpmexec "*" - libnpmfund "*" - libnpmhook "*" - libnpmorg "*" - libnpmpack "*" - libnpmpublish "*" - libnpmsearch "*" - libnpmteam "*" - libnpmversion "*" - make-fetch-happen "*" - minipass "*" - minipass-pipeline "*" - mkdirp "*" - mkdirp-infer-owner "*" - ms "*" - node-gyp "*" - nopt "*" - npm-audit-report "*" - npm-install-checks "*" - npm-package-arg "*" - npm-pick-manifest "*" - npm-profile "*" - npm-registry-fetch "*" - npm-user-validate "*" - npmlog "*" - opener "*" - pacote "*" - parse-conflict-json "*" - qrcode-terminal "*" - read "*" - read-package-json "*" - read-package-json-fast "*" - readdir-scoped-modules "*" - rimraf "*" - semver "*" - ssri "*" - tar "*" - text-table "*" - tiny-relative-date "*" - treeverse "*" - validate-npm-package-name "*" - which "*" - write-file-atomic "*" + "@isaacs/string-locale-compare" "^1.1.0" + "@npmcli/arborist" "^2.9.0" + "@npmcli/ci-detect" "^1.2.0" + "@npmcli/config" "^2.3.0" + "@npmcli/map-workspaces" "^1.0.4" + "@npmcli/package-json" "^1.0.1" + "@npmcli/run-script" "^1.8.6" + abbrev "~1.1.1" + ansicolors "~0.3.2" + ansistyles "~0.1.3" + archy "~1.0.0" + cacache "^15.3.0" + chalk "^4.1.2" + chownr "^2.0.0" + cli-columns "^3.1.2" + cli-table3 "^0.6.0" + columnify "~1.5.4" + fastest-levenshtein "^1.0.12" + glob "^7.2.0" + graceful-fs "^4.2.8" + hosted-git-info "^4.0.2" + ini "^2.0.0" + init-package-json "^2.0.5" + is-cidr "^4.0.2" + json-parse-even-better-errors "^2.3.1" + libnpmaccess "^4.0.2" + libnpmdiff "^2.0.4" + libnpmexec "^2.0.1" + libnpmfund "^1.1.0" + libnpmhook "^6.0.2" + libnpmorg "^2.0.2" + libnpmpack "^2.0.1" + libnpmpublish "^4.0.1" + libnpmsearch "^3.1.1" + libnpmteam "^2.0.3" + libnpmversion "^1.2.1" + make-fetch-happen "^9.1.0" + minipass "^3.1.3" + minipass-pipeline "^1.2.4" + mkdirp "^1.0.4" + mkdirp-infer-owner "^2.0.0" + ms "^2.1.2" + node-gyp "^7.1.2" + nopt "^5.0.0" + npm-audit-report "^2.1.5" + npm-install-checks "^4.0.0" + npm-package-arg "^8.1.5" + npm-pick-manifest "^6.1.1" + npm-profile "^5.0.3" + npm-registry-fetch "^11.0.0" + npm-user-validate "^1.0.1" + npmlog "^5.0.1" + opener "^1.5.2" + pacote "^11.3.5" + parse-conflict-json "^1.1.1" + qrcode-terminal "^0.12.0" + read "~1.0.7" + read-package-json "^4.1.1" + read-package-json-fast "^2.0.3" + readdir-scoped-modules "^1.1.0" + rimraf "^3.0.2" + semver "^7.3.5" + ssri "^8.0.1" + tar "^6.1.11" + text-table "~0.2.0" + tiny-relative-date "^1.3.0" + treeverse "^1.0.4" + validate-npm-package-name "~3.0.0" + which "^2.0.2" + write-file-atomic "^3.0.3" npmlog@*: version "5.0.1" @@ -7616,6 +7643,11 @@ protocols@^1.1.0, protocols@^1.4.0: resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.8.tgz#48eea2d8f58d9644a4a32caae5d5db290a075ce8" integrity sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg== +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + psl@^1.1.28, psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" @@ -8126,7 +8158,7 @@ semver@*, semver@7.3.5, semver@7.x, semver@^7.1.1, semver@^7.1.2, semver@^7.1.3, dependencies: lru-cache "^6.0.0" -"semver@2 || 3 || 4 || 5", semver@^5.5.0: +"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -8207,6 +8239,11 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" +sigmund@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= + signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.5" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f" @@ -9337,6 +9374,11 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"