diff --git a/.eslintrc.yml b/.eslintrc.yml index 2fac6aa2d..ed3c658dd 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -42,6 +42,7 @@ rules: no-unreachable-loop: off no-use-before-define: ["error", { "functions": false, "classes": false }] "@typescript-eslint/consistent-type-imports": ["error", { "prefer": "type-imports" }] + overrides: - files: [ '*.spec.ts' ] globals: @@ -49,6 +50,9 @@ overrides: execScript: true initRepo: true writeConfig: true + - files: ['*.ts'] + rules: + no-redeclare: off env: node: true diff --git a/.github/workflows/beta.yml b/.github/workflows/beta.yml new file mode 100644 index 000000000..5ec0dfa5a --- /dev/null +++ b/.github/workflows/beta.yml @@ -0,0 +1,28 @@ +name: 'release' + +on: + push: + branches: + - 'beta' + +env: + PVM_LL: silly + +jobs: + release-beta: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 150 + - uses: ./.github/actions/setup + - run: npm run build + - run: node scripts/remark-readme.js + - run: npm exec pvm publish -- --canary --tag beta -s all --canary-unified --canary-base-version 1.0.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PVM_SLACK_TOKEN: ${{ secrets.PVM_SLACK_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + PVM_MATTERMOST_URL: ${{ secrets.PVM_MATTERMOST_URL }} + PVM_MATTERMOST_TOKEN: ${{ secrets.PVM_MATTERMOST_TOKEN }} + PVM_MATTERMOST_INCOMING_WEBHOOK: ${{ secrets.PVM_MATTERMOST_INCOMING_WEBHOOK }} diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 32bd99021..1253eeec7 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -70,13 +70,14 @@ jobs: - 'packages/**' - 'test/**' - run: npm run build - - run: npm run check-ts-strict - run: npm exec depscheck - run: npm run lint:config-schema - run: npm exec pvm vcs is-branch-actual env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: npm exec pvm lint + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: npm run lint - if: steps.packageChanges.outputs.changes == 'true' run: npm run test -- -w `node -p 'Math.min(os.cpus().length, 2)'` diff --git a/.pvm.toml b/.pvm.toml index 90c4cd763..aa605e3eb 100644 --- a/.pvm.toml +++ b/.pvm.toml @@ -1,5 +1,5 @@ [versioning] -unified = ['/packages/*', '/src/**/*'] +unified = ['/packages/*'] source = 'tag' [changelog] @@ -35,19 +35,12 @@ strip_namespace = false [notifications] target = 'all' -[[notifications.clients]] -name = 'mattermost' -pkg = '@pvm/mattermost' - -[notifications.client_configs.mattermost] -team = 'tinkoff' - -[notifications.clients_common_config] -channel = 'pvm-github' -author = { name = 'pvm minion (github)', avatarEmoji = ':deciduous_tree:' } +[[plugins_v2]] +plugin = '@pvm/plugin-github' -[plugins] -local_plugins = ['packages/pvm-plugin-conventional-changelog'] +[[plugins_v2]] +plugin = '@pvm/plugin-conventional-changelog' [[plugins_v2]] -plugin = '@pvm/plugin-github' +plugin = '@pvm/plugin-mattermost' +options = { team = 'tinkoff', channel = 'pvm-github', author = { name = 'pvm minion (github)', avatarEmoji = ':deciduous_tree:' } } diff --git a/jest.config.js b/jest.config.js index 52b67fd94..035148bbe 100644 --- a/jest.config.js +++ b/jest.config.js @@ -3,8 +3,7 @@ module.exports = { testMatch: [ '/packages/**/__tests__/**/*.spec.ts', '/src/**/__tests__/**/*.spec.ts', - '/src/**/*.spec.js', - '/test/**/*.spec.js', + '/test/**/*.spec.ts', ], setupFiles: [ './test/jest.setup.js', diff --git a/module-to-relative.js b/module-to-relative.js new file mode 100644 index 000000000..97c36832a --- /dev/null +++ b/module-to-relative.js @@ -0,0 +1,17 @@ +module.exports = function(fileInfo, api, options) { + const depth = fileInfo.path.split('\\').length - 3 + + const re = /@pvm\/(types)/ + return api.jscodeshift(fileInfo.source) + .find(api.jscodeshift.ImportDeclaration) + .forEach(path => { + const source = path.value.source + const [f, m] = re.exec(source.value) ?? [] + + if (f) { + const replace = Array(depth).fill('..').join('/') + `/${m}` + source.value = source.value.replace(f, replace) + } + }) + .toSource() +} diff --git a/package-lock.json b/package-lock.json index 18b43b11e..36163a1fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,12 +12,17 @@ "@tinkoff-monorepo/depscheck": "^1.8.21", "@types/cli-table": "^0.3.0", "@types/express": "^4.17.13", + "@types/fs-extra": "^9.0.13", "@types/git-url-parse": "^9.0.0", + "@types/hosted-git-info": "^3.0.2", "@types/jest": "26", + "@types/lodash": "^4.14.191", + "@types/marked": "^4.0.7", "@types/micromatch": "4.0.1", "@types/node": "^14.18.0", "@types/node-fetch": "^3.0.3", "@types/nunjucks": "^3.1.1", + "@types/parse-path": "^4.0.1", "@types/semver": "^7.2.0", "@types/yargs": "^15.0.10", "@typescript-eslint/eslint-plugin": "^4.28.2", @@ -45,7 +50,8 @@ "get-port": "^5.1.1", "glob": "^7.2.0", "got": "^11.8.5", - "jest": "26.6.3", + "handlebars": "^4.7.7", + "jest": "^29.3.1", "json": "^9.0.6", "nock": "^13.0.4", "node-fetch": "^3.1.0", @@ -54,11 +60,12 @@ "remark-parse": "^10.0.1", "remark-stringify": "^10.0.2", "sprout-data": "^1.3.0", - "ts-jest": "^26.4.4", + "ts-jest": "^29.0.3", "typescript": "^4.7.4", "typescript-json-schema": "^0.51.0", "unified": "^10.1.2", - "verdaccio": "^5.1.6" + "verdaccio": "^5.1.6", + "yargs": "^15.4.1" }, "engines": { "node": ">=16.0.0" @@ -66,10 +73,6 @@ "workspaces": { "packages": [ "packages/*", - "src/tokens/*", - "src/plugins/*", - "src/libs/*", - "src/types/*", "tools/*" ] } @@ -449,9 +452,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", - "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", "dev": true, "engines": { "node": ">=6.9.0" @@ -481,10 +484,19 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-string-parser": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", + "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "engines": { "node": ">=6.9.0" } @@ -504,11 +516,11 @@ } }, "node_modules/@babel/highlight": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz", - "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -652,6 +664,21 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz", + "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", @@ -739,6 +766,21 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz", + "integrity": "sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/template": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", @@ -846,12 +888,13 @@ } }, "node_modules/@babel/types": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.4.tgz", - "integrity": "sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==", + "version": "7.22.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.4.tgz", + "integrity": "sha512-Tx9x3UBHTTsMSW85WB2kphxYQVvrZ/t1FxD88IpSgIjiUJlCm9z+xWIDwyo1vffTwSqteqyznB8ZE9vYYk16zA==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-string-parser": "^7.21.5", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" }, "engines": { @@ -864,22 +907,6 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "dev": true, - "dependencies": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - }, - "bin": { - "watch": "cli.js" - }, - "engines": { - "node": ">=0.1.95" - } - }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -992,283 +1019,376 @@ } }, "node_modules/@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", + "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", "slash": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/core": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", - "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.5.0.tgz", + "integrity": "sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==", "dev": true, "dependencies": { - "@jest/console": "^26.6.2", - "@jest/reporters": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^29.5.0", + "@jest/reporters": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", + "ci-info": "^3.2.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.6.2", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-resolve-dependencies": "^26.6.3", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "jest-watcher": "^26.6.2", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "rimraf": "^3.0.0", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.5.0", + "jest-config": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-resolve-dependencies": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "jest-watcher": "^29.5.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/@jest/core/node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, "node_modules/@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", + "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-mock": "^26.6.2" + "jest-mock": "^29.5.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", + "dev": true, + "dependencies": { + "expect": "^29.5.0", + "jest-snapshot": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", + "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", + "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", + "@jest/types": "^29.5.0", + "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/globals": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", - "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", + "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", "dev": true, "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/types": "^26.6.2", - "expect": "^26.6.2" + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/types": "^29.5.0", + "jest-mock": "^29.5.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/reporters": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", - "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.5.0.tgz", + "integrity": "sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", + "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-instrument": "^5.1.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", "slash": "^3.0.0", - "source-map": "^0.6.0", "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^7.0.0" + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "optionalDependencies": { - "node-notifier": "^8.0.0" + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/@jest/reporters/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/@jest/schemas": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.25.16" + }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/source-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", - "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", + "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", "dev": true, "dependencies": { + "@jridgewell/trace-mapping": "^0.3.15", "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" + "graceful-fs": "^4.2.9" }, "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/source-map/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", + "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", "dev": true, "dependencies": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^29.5.0", + "@jest/types": "^29.5.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/test-sequencer": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", - "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz", + "integrity": "sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==", "dev": true, "dependencies": { - "@jest/test-result": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3" + "@jest/test-result": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "slash": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/transform": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", - "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", + "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", "dev": true, "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.6.2", - "babel-plugin-istanbul": "^6.0.0", + "@babel/core": "^7.11.6", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.6.2", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" + "write-file-atomic": "^4.0.2" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "node_modules/@jest/transform/node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, - "node_modules/@jest/transform/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/@jest/transform/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, "engines": { - "node": ">=0.10.0" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "dependencies": { + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "@types/yargs": "^15.0.0", + "@types/yargs": "^17.0.8", "chalk": "^4.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types/node_modules/@types/yargs": { + "version": "17.0.15", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.15.tgz", + "integrity": "sha512-ZHc4W2dnEQPfhn06TBEdWaiUHEZAocYaiVMfwOipY5jcJt/251wVrKCBWBetGZWO5CF8tdb7L3DmdxVlZ2BOIg==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" } }, "node_modules/@jridgewell/gen-mapping": { @@ -1286,9 +1406,9 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true, "engines": { "node": ">=6.0.0" @@ -1304,19 +1424,19 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "node_modules/@nodelib/fs.scandir": { @@ -1703,128 +1823,44 @@ "integrity": "sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw==", "dev": true }, - "node_modules/@pvm/add-tag": { - "resolved": "packages/pvm-add-tag", - "link": true - }, - "node_modules/@pvm/artifacts": { - "resolved": "packages/pvm-artifacts", - "link": true - }, - "node_modules/@pvm/changelog": { - "resolved": "packages/pvm-changelog", - "link": true - }, "node_modules/@pvm/cli-inline-remark-plugin": { "resolved": "tools/cli-inline-remark-plugin", "link": true }, - "node_modules/@pvm/core": { - "resolved": "packages/pvm-core", - "link": true - }, "node_modules/@pvm/cowners": { - "resolved": "packages/pvm-cowners", - "link": true - }, - "node_modules/@pvm/di": { - "resolved": "src/libs/di", - "link": true - }, - "node_modules/@pvm/files": { - "resolved": "packages/pvm-files", - "link": true - }, - "node_modules/@pvm/gitlab": { - "resolved": "packages/pvm-gitlab", - "link": true - }, - "node_modules/@pvm/mattermost": { - "resolved": "packages/pvm-mattermost", - "link": true - }, - "node_modules/@pvm/notifications": { - "resolved": "packages/pvm-notifications", - "link": true - }, - "node_modules/@pvm/pkgset": { - "resolved": "packages/pvm-pkgset", - "link": true - }, - "node_modules/@pvm/plugin-common-plugins": { - "resolved": "src/plugins/common-plugins", + "resolved": "packages/cowners", "link": true }, "node_modules/@pvm/plugin-conventional-changelog": { - "resolved": "packages/pvm-plugin-conventional-changelog", + "resolved": "packages/plugin-conventional-changelog", "link": true }, "node_modules/@pvm/plugin-conventional-semantic-release": { - "resolved": "packages/pvm-plugin-conventional-semantic-release", - "link": true - }, - "node_modules/@pvm/plugin-core": { - "resolved": "src/plugins/core", + "resolved": "packages/plugin-conventional-semantic-release", "link": true }, "node_modules/@pvm/plugin-github": { - "resolved": "src/plugins/github", - "link": true - }, - "node_modules/@pvm/plugin-http-proxy": { - "resolved": "packages/pvm-plugin-http-proxy", - "link": true - }, - "node_modules/@pvm/pvm": { - "resolved": "packages/pvm", - "link": true - }, - "node_modules/@pvm/releases": { - "resolved": "packages/pvm-releases", - "link": true - }, - "node_modules/@pvm/repository": { - "resolved": "packages/pvm-repository", - "link": true - }, - "node_modules/@pvm/slack": { - "resolved": "packages/pvm-slack", - "link": true - }, - "node_modules/@pvm/suffixes": { - "resolved": "packages/pvm-suffixes", - "link": true - }, - "node_modules/@pvm/template": { - "resolved": "packages/pvm-template", - "link": true - }, - "node_modules/@pvm/tokens-core": { - "resolved": "src/tokens/core", - "link": true - }, - "node_modules/@pvm/types": { - "resolved": "packages/pvm-types", + "resolved": "packages/plugin-github", "link": true }, - "node_modules/@pvm/update": { - "resolved": "packages/pvm-update", + "node_modules/@pvm/plugin-gitlab": { + "resolved": "packages/plugin-gitlab", "link": true }, - "node_modules/@pvm/vcs": { - "resolved": "packages/pvm-vcs", + "node_modules/@pvm/plugin-http-proxy": { + "resolved": "packages/plugin-http-proxy", "link": true }, - "node_modules/@pvm/vcs-fs": { - "resolved": "packages/pvm-vcs-fs", + "node_modules/@pvm/plugin-mattermost": { + "resolved": "packages/plugin-mattermost", "link": true }, - "node_modules/@pvm/vcs-git": { - "resolved": "packages/pvm-vcs-git", + "node_modules/@pvm/plugin-slack": { + "resolved": "packages/plugin-slack", "link": true }, - "node_modules/@pvm/viz": { - "resolved": "packages/pvm-viz", + "node_modules/@pvm/pvm": { + "resolved": "packages/pvm", "link": true }, "node_modules/@semantic-release/commit-analyzer": { @@ -2227,6 +2263,12 @@ "node": ">=8" } }, + "node_modules/@sinclair/typebox": { + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", + "dev": true + }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", @@ -2240,21 +2282,21 @@ } }, "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", "dev": true, "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.2.0.tgz", + "integrity": "sha512-OPwQlEdg40HAj5KNF8WW6q2KG4Z+cBCZb3m4ninfTZKaBmbIJodviQsDBoYMPHkOyJJMHnOJo5j2+LKDOhOACg==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.7.0" + "@sinonjs/commons": "^3.0.0" } }, "node_modules/@szmarczak/http-timer": { @@ -2355,6 +2397,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "peer": true, "engines": { "node": ">= 6" } @@ -2389,31 +2432,43 @@ "integrity": "sha512-cMRXVxb+NMb6EekKel1fPBfz2ZqE5cGhIS14G7FVUM4Bqilx0lHKnZbsDLWLSeckDpkvlp5six2F7UWyEEJSoQ==" }, "node_modules/@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", + "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, + "node_modules/@types/babel__core/node_modules/@babel/parser": { + "version": "7.22.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.4.tgz", + "integrity": "sha512-VLLsx06XkEYqBtE5YGPwfSGwfrjnyPP5oiGty3S8pQLFDFLaS8VwWSIxkTXpcvr5zeYLE6+MBNl2npl/YnfofA==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@types/babel__generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", - "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, "dependencies": { "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", - "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -2421,9 +2476,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.17.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.17.1.tgz", - "integrity": "sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", "dev": true, "dependencies": { "@babel/types": "^7.3.0" @@ -2450,12 +2505,6 @@ "resolved": "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.0.tgz", "integrity": "sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg==" }, - "node_modules/@types/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-5YG1AiIC8HPPXRvYAIa7ehK3YMAwd0DWiPCtpuL9sgKceWLyWsVtLRA+lT4NkoanDNF9slwQ66lPizWDpgRlWA==", - "dev": true - }, "node_modules/@types/cacheable-request": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", @@ -2530,9 +2579,9 @@ } }, "node_modules/@types/fs-extra": { - "version": "9.0.11", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.11.tgz", - "integrity": "sha512-mZsifGG4QeQ7hlkhO56u7zt/ycBgGxSVsFI/6lGTU34VtwkiqrrSDgw0+ygs8kFGWcXnFQWMrzF2h7TtDFNixA==", + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", "dev": true, "dependencies": { "@types/node": "*" @@ -2545,14 +2594,20 @@ "dev": true }, "node_modules/@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", "dev": true, "dependencies": { "@types/node": "*" } }, + "node_modules/@types/hosted-git-info": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/hosted-git-info/-/hosted-git-info-3.0.2.tgz", + "integrity": "sha512-RURNTeEFUwF+ifnp7kK3WLLlTmBSlRynLNS9jeAsI6RHtSrupV0l0nO6kmpaz75EUJVexy348bR452SvmH98vQ==", + "dev": true + }, "node_modules/@types/http-cache-semantics": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", @@ -2628,11 +2683,23 @@ "@types/node": "*" } }, + "node_modules/@types/lodash": { + "version": "4.14.191", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", + "dev": true + }, "node_modules/@types/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==" }, + "node_modules/@types/marked": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.7.tgz", + "integrity": "sha512-eEAhnz21CwvKVW+YvRvcTuFKNU9CV1qH+opcgVK3pIMI6YZzDm6gc8o2vHjldFk6MGKt5pueSB7IOpvpx5Qekw==", + "dev": true + }, "node_modules/@types/mdast": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz", @@ -2703,10 +2770,19 @@ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, + "node_modules/@types/parse-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/parse-path/-/parse-path-4.0.1.tgz", + "integrity": "sha512-ZQffgFDaKTpSeO/NcBVPbJ21VvIuKAEcVMLapL6ltfrfIZyxNMjoQA+LB6af0E3C8dNVj+L76gjR6KzjKOA/9A==", + "dev": true, + "dependencies": { + "query-string": "^6.13.8" + } + }, "node_modules/@types/prettier": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz", - "integrity": "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", "dev": true }, "node_modules/@types/qs": { @@ -2753,9 +2829,9 @@ } }, "node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, "node_modules/@types/unist": { @@ -3568,16 +3644,6 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, "node_modules/acorn-jsx": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", @@ -3697,9 +3763,9 @@ } }, "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } @@ -3951,7 +4017,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, "engines": { "node": ">= 4.0.0" } @@ -4000,25 +4065,24 @@ "dev": true }, "node_modules/babel-jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", - "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", + "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", "dev": true, "dependencies": { - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.6.2", + "@jest/transform": "^29.5.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.5.0", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "slash": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.8.0" } }, "node_modules/babel-plugin-istanbul": { @@ -4037,56 +4101,19 @@ "node": ">=8" } }, - "node_modules/babel-plugin-istanbul/node_modules/@babel/parser": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz", - "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/babel-plugin-jest-hoist": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", - "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", + "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", "dev": true, "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", + "@types/babel__core": "^7.1.14", "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/babel-polyfill": { @@ -4124,16 +4151,16 @@ } }, "node_modules/babel-preset-jest": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", - "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", + "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^26.6.2", + "babel-plugin-jest-hoist": "^29.5.0", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -4608,18 +4635,6 @@ "node": ">=8" } }, - "node_modules/capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "dev": true, - "dependencies": { - "rsvp": "^4.8.4" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, "node_modules/cardinal": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", @@ -4736,15 +4751,18 @@ } }, "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", + "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==", + "dev": true, + "engines": { + "node": ">=8" + } }, "node_modules/cjs-module-lexer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", - "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, "node_modules/class-utils": { @@ -4946,7 +4964,7 @@ "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, "engines": { "iojs": ">= 1.0.0", @@ -5821,20 +5839,6 @@ "node": ">= 12" } }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/date-fns": { "version": "2.22.1", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.22.1.tgz", @@ -5912,12 +5916,6 @@ "node": ">=0.10.0" } }, - "node_modules/decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", - "dev": true - }, "node_modules/decode-named-character-reference": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.1.tgz", @@ -5987,9 +5985,9 @@ "dev": true }, "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, "engines": { "node": ">=0.10.0" @@ -6547,27 +6545,6 @@ "node": ">=4" } }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "dependencies": { - "webidl-conversions": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/dompurify": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.3.tgz", @@ -6698,12 +6675,12 @@ "dev": true }, "node_modules/emittery": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", - "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sindresorhus/emittery?sponsor=1" @@ -6988,98 +6965,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/eslint": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.29.0.tgz", @@ -7612,12 +7497,6 @@ "es5-ext": "~0.10.14" } }, - "node_modules/exec-sh": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", - "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==", - "dev": true - }, "node_modules/execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", @@ -7699,7 +7578,7 @@ "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true, "engines": { "node": ">= 0.8.0" @@ -7836,20 +7715,28 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" + "@jest/expect-utils": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/expect/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/express": { @@ -8082,9 +7969,9 @@ } }, "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, "dependencies": { "bser": "2.1.1" @@ -8411,20 +8298,6 @@ "node": "*" } }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/formdata-polyfill": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", @@ -8519,7 +8392,6 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -9167,6 +9039,18 @@ "integrity": "sha512-qpPnUKkWnz8NESjrCvnlGklsgiQzlq+rcCxoG5uNQ+dNA7cFMCmn231slLAwS2N/PlkzZ3COL8CcS10jXmLHqg==", "dev": true }, + "node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globalthis": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz", @@ -9226,16 +9110,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" - }, - "node_modules/growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==", - "dev": true, - "optional": true + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "node_modules/handlebars": { "version": "4.7.7", @@ -9481,18 +9358,6 @@ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "dependencies": { - "whatwg-encoding": "^1.0.5" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -9547,6 +9412,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "peer": true, "dependencies": { "@tootallnate/once": "1", "agent-base": "6", @@ -9594,6 +9460,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "peer": true, "dependencies": { "agent-base": "6", "debug": "4" @@ -9689,9 +9556,9 @@ } }, "node_modules/import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, "dependencies": { "pkg-dir": "^4.2.0", @@ -9702,6 +9569,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/import-local/node_modules/find-up": { @@ -9945,18 +9815,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "dependencies": { - "ci-info": "^2.0.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, "node_modules/is-core-module": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", @@ -10013,22 +9871,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "optional": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-empty": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-empty/-/is-empty-1.2.0.tgz", @@ -10205,12 +10047,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, "node_modules/is-promise": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", @@ -10359,19 +10195,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "optional": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -10422,20 +10245,33 @@ } }, "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "dependencies": { - "@babel/core": "^7.7.5", + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" }, "engines": { "node": ">=8" } }, + "node_modules/istanbul-lib-instrument/node_modules/@babel/parser": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/istanbul-lib-instrument/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -10460,9 +10296,9 @@ } }, "node_modules/istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "dependencies": { "debug": "^4.1.1", @@ -10470,7 +10306,7 @@ "source-map": "^0.6.1" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-lib-source-maps/node_modules/source-map": { @@ -10483,9 +10319,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", - "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -10505,50 +10341,58 @@ } }, "node_modules/jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", - "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", + "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", "dev": true, "dependencies": { - "@jest/core": "^26.6.3", + "@jest/core": "^29.5.0", + "@jest/types": "^29.5.0", "import-local": "^3.0.2", - "jest-cli": "^26.6.3" + "jest-cli": "^29.5.0" }, "bin": { "jest": "bin/jest.js" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, "node_modules/jest-changed-files": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", - "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", + "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "execa": "^4.0.0", - "throat": "^5.0.0" + "execa": "^5.0.0", + "p-limit": "^3.1.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-changed-files/node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" }, "engines": { @@ -10559,36 +10403,27 @@ } }, "node_modules/jest-changed-files/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-changed-files/node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true, - "engines": { - "node": ">=8.12.0" - } - }, "node_modules/jest-changed-files/node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-changed-files/node_modules/npm-run-path": { @@ -10603,83 +10438,299 @@ "node": ">=8" } }, + "node_modules/jest-changed-files/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-circus": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", + "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.5.0", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.5.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-circus/node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, "node_modules/jest-cli": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", - "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.5.0.tgz", + "integrity": "sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==", "dev": true, "dependencies": { - "@jest/core": "^26.6.3", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/core": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", "chalk": "^4.0.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.6.3", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", + "jest-config": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", "prompts": "^2.0.1", - "yargs": "^15.4.1" + "yargs": "^17.3.1" }, "bin": { "jest": "bin/jest.js" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-cli/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-cli/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-cli/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-cli/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" } }, "node_modules/jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.5.0.tgz", + "integrity": "sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==", "dev": true, "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.5.0", + "@jest/types": "^29.5.0", + "babel-jest": "^29.5.0", "chalk": "^4.0.0", + "ci-info": "^3.2.0", "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.5.0", + "jest-environment-node": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { + "@types/node": "*", "ts-node": ">=9.0.0" }, "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, "ts-node": { "optional": true } } }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/jest-config/node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, + "node_modules/jest-config/node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-config/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, "node_modules/jest-diff": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", @@ -10696,66 +10747,89 @@ } }, "node_modules/jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", + "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", "dev": true, "dependencies": { "detect-newline": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", + "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", + "@jest/types": "^29.5.0", "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" + "jest-get-type": "^29.4.3", + "jest-util": "^29.5.0", + "pretty-format": "^29.5.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-environment-jsdom": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", - "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2", - "jsdom": "^16.4.0" + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-each/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, "node_modules/jest-environment-node": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", - "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.5.0.tgz", + "integrity": "sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==", "dev": true, "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-get-type": { @@ -10768,152 +10842,272 @@ } }, "node_modules/jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", + "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/graceful-fs": "^4.1.2", + "@jest/types": "^29.5.0", + "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7" + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "optionalDependencies": { - "fsevents": "^2.1.2" + "fsevents": "^2.3.2" } }, "node_modules/jest-haste-map/node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, - "node_modules/jest-jasmine2": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", - "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", + "node_modules/jest-leak-detector": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz", + "integrity": "sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==", "dev": true, "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^26.6.2", - "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2", - "throat": "^5.0.0" + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-leak-detector": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", - "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "node_modules/jest-leak-detector/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-leak-detector/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "dependencies": { - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, "node_modules/jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/jest-diff": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-matcher-utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, "node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.5.0", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "stack-utils": "^2.0.3" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/@babel/code-frame": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-message-util/node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, "node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", + "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-util": "^29.5.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "engines": { "node": ">=6" @@ -10928,332 +11122,360 @@ } }, "node_modules/jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", "dev": true, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", + "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", "slash": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve-dependencies": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", - "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz", + "integrity": "sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.6.2" + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.5.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-resolve/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/jest-runner": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.5.0.tgz", + "integrity": "sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==", "dev": true, "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "@jest/console": "^29.5.0", + "@jest/environment": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-leak-detector": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-resolve": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-util": "^29.5.0", + "jest-watcher": "^29.5.0", + "jest-worker": "^29.5.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-resolve/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "node_modules/jest-runtime": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", + "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/globals": "^29.5.0", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-resolve/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/jest-snapshot": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", + "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", "dev": true, "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.5.0", + "semver": "^7.3.5" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-resolve/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-resolve/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "node_modules/jest-snapshot/node_modules/diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", "dev": true, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-resolve/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "node_modules/jest-snapshot/node_modules/jest-diff": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", "dev": true, - "bin": { - "semver": "bin/semver" + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-resolve/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "node_modules/jest-snapshot/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", "dev": true, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runner": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", - "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.7.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.6.2", - "jest-leak-detector": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runtime": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", - "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", - "dev": true, - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/globals": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/yargs": "^15.0.0", + "node_modules/jest-snapshot/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-util": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.5.0", + "@types/node": "*", "chalk": "^4.0.0", - "cjs-module-lexer": "^0.6.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.4.1" - }, - "bin": { - "jest-runtime": "bin/jest-runtime.js" + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "node_modules/jest-validate": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", + "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", "dev": true, "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.4" + "@jest/types": "^29.5.0", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "leven": "^3.1.0", + "pretty-format": "^29.5.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-util/node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "node_modules/jest-validate/node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, "engines": { - "node": ">=8.6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-validate": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", - "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "node_modules/jest-validate/node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "camelcase": "^6.0.0", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "leven": "^3.1.0", - "pretty-format": "^26.6.2" + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "node_modules/jest-validate/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true }, "node_modules/jest-watcher": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", - "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.5.0.tgz", + "integrity": "sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==", "dev": true, "dependencies": { - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^26.6.2", + "emittery": "^0.13.1", + "jest-util": "^29.5.0", "string-length": "^4.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", + "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", "dev": true, "dependencies": { "@types/node": "*", + "jest-util": "^29.5.0", "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" + "supports-color": "^8.0.0" }, "engines": { - "node": ">= 10.13.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/js-tokens": { @@ -11279,64 +11501,6 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM= sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "dev": true }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsdom/node_modules/acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -11409,9 +11573,9 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "bin": { "json5": "lib/cli.js" }, @@ -11751,11 +11915,6 @@ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", "dev": true }, - "node_modules/lodash.defaultsdeep": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz", - "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==" - }, "node_modules/lodash.escaperegexp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", @@ -11797,17 +11956,18 @@ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "node_modules/lodash.omitby": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.omitby/-/lodash.omitby-4.6.0.tgz", - "integrity": "sha1-XBX/R1StVVAWtTwEExHo8HkgR5E= sha512-5OrRcIVR75M288p4nbI2WLAf3ndw2GD9fyNv3Bc15+WCxJDdZ4lYndSxGd7hnG6PVjiJTeJE2dHEGhIuKGicIQ==" - }, "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", @@ -13673,24 +13833,9 @@ "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, - "node_modules/node-notifier": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", - "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", - "dev": true, - "optional": true, - "dependencies": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.2", - "shellwords": "^0.1.1", - "uuid": "^8.3.0", - "which": "^2.0.2" - } - }, "node_modules/normalize-package-data": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", @@ -14156,8 +14301,6 @@ }, "node_modules/npm/node_modules/@tootallnate/once": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "inBundle": true, "license": "MIT", "peer": true, @@ -14173,8 +14316,6 @@ }, "node_modules/npm/node_modules/agent-base": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "inBundle": true, "license": "MIT", "peer": true, @@ -14201,8 +14342,6 @@ }, "node_modules/npm/node_modules/aggregate-error": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "inBundle": true, "license": "MIT", "peer": true, @@ -14216,8 +14355,6 @@ }, "node_modules/npm/node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "inBundle": true, "license": "MIT", "peer": true, @@ -14243,8 +14380,6 @@ }, "node_modules/npm/node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "inBundle": true, "license": "MIT", "peer": true, @@ -14260,8 +14395,6 @@ }, "node_modules/npm/node_modules/ansicolors": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", "inBundle": true, "license": "MIT", "peer": true @@ -14305,8 +14438,6 @@ }, "node_modules/npm/node_modules/asn1": { "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "inBundle": true, "license": "MIT", "peer": true, @@ -14316,8 +14447,6 @@ }, "node_modules/npm/node_modules/assert-plus": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "inBundle": true, "license": "MIT", "peer": true, @@ -14327,16 +14456,12 @@ }, "node_modules/npm/node_modules/asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "inBundle": true, "license": "MIT", "peer": true }, "node_modules/npm/node_modules/aws-sign2": { "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", "inBundle": true, "license": "Apache-2.0", "peer": true, @@ -14346,24 +14471,18 @@ }, "node_modules/npm/node_modules/aws4": { "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "inBundle": true, "license": "MIT", "peer": true }, "node_modules/npm/node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "inBundle": true, "license": "MIT", "peer": true }, "node_modules/npm/node_modules/bcrypt-pbkdf": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", "inBundle": true, "license": "BSD-3-Clause", "peer": true, @@ -14399,8 +14518,6 @@ }, "node_modules/npm/node_modules/brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "inBundle": true, "license": "MIT", "peer": true, @@ -14446,16 +14563,12 @@ }, "node_modules/npm/node_modules/caseless": { "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "inBundle": true, "license": "Apache-2.0", "peer": true }, "node_modules/npm/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "inBundle": true, "license": "MIT", "peer": true, @@ -14493,8 +14606,6 @@ }, "node_modules/npm/node_modules/clean-stack": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "inBundle": true, "license": "MIT", "peer": true, @@ -14533,8 +14644,6 @@ }, "node_modules/npm/node_modules/cli-table3/node_modules/ansi-regex": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "inBundle": true, "license": "MIT", "peer": true, @@ -14544,8 +14653,6 @@ }, "node_modules/npm/node_modules/cli-table3/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "inBundle": true, "license": "MIT", "peer": true, @@ -14555,8 +14662,6 @@ }, "node_modules/npm/node_modules/cli-table3/node_modules/string-width": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "inBundle": true, "license": "MIT", "peer": true, @@ -14571,8 +14676,6 @@ }, "node_modules/npm/node_modules/cli-table3/node_modules/strip-ansi": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "inBundle": true, "license": "MIT", "peer": true, @@ -14615,8 +14718,6 @@ }, "node_modules/npm/node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "inBundle": true, "license": "MIT", "peer": true, @@ -14629,8 +14730,6 @@ }, "node_modules/npm/node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "inBundle": true, "license": "MIT", "peer": true @@ -14666,8 +14765,6 @@ }, "node_modules/npm/node_modules/combined-stream": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "inBundle": true, "license": "MIT", "peer": true, @@ -14686,8 +14783,6 @@ }, "node_modules/npm/node_modules/concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "inBundle": true, "license": "MIT", "peer": true @@ -14700,16 +14795,12 @@ }, "node_modules/npm/node_modules/core-util-is": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", "inBundle": true, "license": "MIT", "peer": true }, "node_modules/npm/node_modules/dashdash": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "inBundle": true, "license": "MIT", "peer": true, @@ -14722,8 +14813,6 @@ }, "node_modules/npm/node_modules/debug": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "inBundle": true, "license": "MIT", "peer": true, @@ -14741,8 +14830,6 @@ }, "node_modules/npm/node_modules/debug/node_modules/ms": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "inBundle": true, "license": "MIT", "peer": true @@ -14767,8 +14854,6 @@ }, "node_modules/npm/node_modules/delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "inBundle": true, "license": "MIT", "peer": true, @@ -14812,8 +14897,6 @@ }, "node_modules/npm/node_modules/ecc-jsbn": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", "inBundle": true, "license": "MIT", "peer": true, @@ -14824,8 +14907,6 @@ }, "node_modules/npm/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "inBundle": true, "license": "MIT", "peer": true @@ -14857,16 +14938,12 @@ }, "node_modules/npm/node_modules/extend": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "inBundle": true, "license": "MIT", "peer": true }, "node_modules/npm/node_modules/extsprintf": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", "engines": [ "node >=0.6.0" ], @@ -14876,16 +14953,12 @@ }, "node_modules/npm/node_modules/fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "inBundle": true, "license": "MIT", "peer": true }, "node_modules/npm/node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "inBundle": true, "license": "MIT", "peer": true @@ -14898,8 +14971,6 @@ }, "node_modules/npm/node_modules/forever-agent": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", "inBundle": true, "license": "Apache-2.0", "peer": true, @@ -14921,16 +14992,12 @@ }, "node_modules/npm/node_modules/fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "inBundle": true, "license": "ISC", "peer": true }, "node_modules/npm/node_modules/function-bind": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "inBundle": true, "license": "MIT", "peer": true @@ -14957,8 +15024,6 @@ }, "node_modules/npm/node_modules/getpass": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "inBundle": true, "license": "MIT", "peer": true, @@ -14988,16 +15053,12 @@ }, "node_modules/npm/node_modules/graceful-fs": { "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", "inBundle": true, "license": "ISC", "peer": true }, "node_modules/npm/node_modules/har-schema": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", "inBundle": true, "license": "ISC", "peer": true, @@ -15007,8 +15068,6 @@ }, "node_modules/npm/node_modules/har-validator": { "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "inBundle": true, "license": "MIT", "peer": true, @@ -15022,8 +15081,6 @@ }, "node_modules/npm/node_modules/has": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "inBundle": true, "license": "MIT", "peer": true, @@ -15036,8 +15093,6 @@ }, "node_modules/npm/node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "inBundle": true, "license": "MIT", "peer": true, @@ -15053,8 +15108,6 @@ }, "node_modules/npm/node_modules/hosted-git-info": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", - "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", "inBundle": true, "license": "ISC", "peer": true, @@ -15073,8 +15126,6 @@ }, "node_modules/npm/node_modules/http-proxy-agent": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "inBundle": true, "license": "MIT", "peer": true, @@ -15089,8 +15140,6 @@ }, "node_modules/npm/node_modules/http-signature": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", "inBundle": true, "license": "MIT", "peer": true, @@ -15150,8 +15199,6 @@ }, "node_modules/npm/node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "inBundle": true, "license": "MIT", "peer": true, @@ -15161,8 +15208,6 @@ }, "node_modules/npm/node_modules/indent-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "inBundle": true, "license": "MIT", "peer": true, @@ -15178,8 +15223,6 @@ }, "node_modules/npm/node_modules/inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "inBundle": true, "license": "ISC", "peer": true, @@ -15190,8 +15233,6 @@ }, "node_modules/npm/node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "inBundle": true, "license": "ISC", "peer": true @@ -15279,55 +15320,41 @@ }, "node_modules/npm/node_modules/is-typedarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "inBundle": true, "license": "MIT", "peer": true }, "node_modules/npm/node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "inBundle": true, "license": "ISC", "peer": true }, "node_modules/npm/node_modules/isstream": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", "inBundle": true, "license": "MIT", "peer": true }, "node_modules/npm/node_modules/jsbn": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "inBundle": true, "license": "MIT", "peer": true }, "node_modules/npm/node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "inBundle": true, "license": "MIT", "peer": true }, "node_modules/npm/node_modules/json-schema": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ==", "inBundle": true, "peer": true }, "node_modules/npm/node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "inBundle": true, "license": "MIT", "peer": true @@ -15343,8 +15370,6 @@ }, "node_modules/npm/node_modules/json-stringify-safe": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "inBundle": true, "license": "ISC", "peer": true @@ -15360,8 +15385,6 @@ }, "node_modules/npm/node_modules/jsprim": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=sha512-4Dj8Rf+fQ+/Pn7C5qeEX02op1WfOss3PKTE9Nsop3Dx+6UPxlm1dr/og7o2cRa5hNN07CACr4NFzRLtj/rjWog==", "engines": [ "node >=0.6.0" ], @@ -15548,8 +15571,6 @@ }, "node_modules/npm/node_modules/lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "inBundle": true, "license": "ISC", "peer": true, @@ -15868,8 +15889,6 @@ }, "node_modules/npm/node_modules/normalize-package-data": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", "inBundle": true, "license": "BSD-2-Clause", "peer": true, @@ -16037,8 +16056,6 @@ }, "node_modules/npm/node_modules/oauth-sign": { "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "inBundle": true, "license": "Apache-2.0", "peer": true, @@ -16048,8 +16065,6 @@ }, "node_modules/npm/node_modules/object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "inBundle": true, "license": "MIT", "peer": true, @@ -16059,8 +16074,6 @@ }, "node_modules/npm/node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "inBundle": true, "license": "ISC", "peer": true, @@ -16079,8 +16092,6 @@ }, "node_modules/npm/node_modules/p-map": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "inBundle": true, "license": "MIT", "peer": true, @@ -16140,8 +16151,6 @@ }, "node_modules/npm/node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "inBundle": true, "license": "MIT", "peer": true, @@ -16151,8 +16160,6 @@ }, "node_modules/npm/node_modules/performance-now": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", "inBundle": true, "license": "MIT", "peer": true @@ -16211,16 +16218,12 @@ }, "node_modules/npm/node_modules/psl": { "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", "inBundle": true, "license": "MIT", "peer": true }, "node_modules/npm/node_modules/punycode": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "inBundle": true, "license": "MIT", "peer": true, @@ -16238,8 +16241,6 @@ }, "node_modules/npm/node_modules/qs": { "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "inBundle": true, "license": "BSD-3-Clause", "peer": true, @@ -16295,8 +16296,6 @@ }, "node_modules/npm/node_modules/readable-stream": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "inBundle": true, "license": "MIT", "peer": true, @@ -16323,8 +16322,6 @@ }, "node_modules/npm/node_modules/request": { "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "inBundle": true, "license": "Apache-2.0", "peer": true, @@ -16356,8 +16353,6 @@ }, "node_modules/npm/node_modules/request/node_modules/form-data": { "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "inBundle": true, "license": "MIT", "peer": true, @@ -16394,8 +16389,6 @@ }, "node_modules/npm/node_modules/rimraf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "inBundle": true, "license": "ISC", "peer": true, @@ -16411,8 +16404,6 @@ }, "node_modules/npm/node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -16433,16 +16424,12 @@ }, "node_modules/npm/node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "inBundle": true, "license": "MIT", "peer": true }, "node_modules/npm/node_modules/semver": { "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "inBundle": true, "license": "ISC", "peer": true, @@ -16458,8 +16445,6 @@ }, "node_modules/npm/node_modules/set-blocking": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "inBundle": true, "license": "ISC", "peer": true @@ -16510,8 +16495,6 @@ }, "node_modules/npm/node_modules/spdx-correct": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "inBundle": true, "license": "Apache-2.0", "peer": true, @@ -16522,16 +16505,12 @@ }, "node_modules/npm/node_modules/spdx-exceptions": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "inBundle": true, "license": "CC-BY-3.0", "peer": true }, "node_modules/npm/node_modules/spdx-expression-parse": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "inBundle": true, "license": "MIT", "peer": true, @@ -16548,8 +16527,6 @@ }, "node_modules/npm/node_modules/sshpk": { "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "inBundle": true, "license": "MIT", "peer": true, @@ -16630,8 +16607,6 @@ }, "node_modules/npm/node_modules/stringify-package": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz", - "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==", "inBundle": true, "license": "ISC", "peer": true @@ -16650,8 +16625,6 @@ }, "node_modules/npm/node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "inBundle": true, "license": "MIT", "peer": true, @@ -16699,8 +16672,6 @@ }, "node_modules/npm/node_modules/tunnel-agent": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "inBundle": true, "license": "Apache-2.0", "peer": true, @@ -16713,16 +16684,12 @@ }, "node_modules/npm/node_modules/tweetnacl": { "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", "inBundle": true, "license": "Unlicense", "peer": true }, "node_modules/npm/node_modules/typedarray-to-buffer": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "inBundle": true, "license": "MIT", "peer": true, @@ -16750,8 +16717,6 @@ }, "node_modules/npm/node_modules/uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "inBundle": true, "license": "BSD-2-Clause", "peer": true, @@ -16761,16 +16726,12 @@ }, "node_modules/npm/node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "inBundle": true, "license": "MIT", "peer": true }, "node_modules/npm/node_modules/uuid": { "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "inBundle": true, "license": "MIT", "peer": true, @@ -16780,8 +16741,6 @@ }, "node_modules/npm/node_modules/validate-npm-package-license": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "inBundle": true, "license": "Apache-2.0", "peer": true, @@ -16801,8 +16760,6 @@ }, "node_modules/npm/node_modules/verror": { "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", "engines": [ "node >=0.6.0" ], @@ -16832,8 +16789,6 @@ }, "node_modules/npm/node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "inBundle": true, "license": "ISC", "peer": true, @@ -16858,8 +16813,6 @@ }, "node_modules/npm/node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "inBundle": true, "license": "ISC", "peer": true @@ -16878,8 +16831,6 @@ }, "node_modules/npm/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "inBundle": true, "license": "ISC", "peer": true @@ -17193,6 +17144,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", + "peer": true, "engines": { "node": ">=8" }, @@ -17381,9 +17333,9 @@ } }, "node_modules/parse-md": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/parse-md/-/parse-md-2.0.4.tgz", - "integrity": "sha512-P45VmpnIo2QGErCa+YnpndzKXcu2v5qpFX31pOyGY+Ub9KuCAm6qKXCbR3sRsoESuy6XeY81hEIVnn6xz+0YcA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/parse-md/-/parse-md-2.0.5.tgz", + "integrity": "sha512-7ZhRqwFRTAXyr/PcXSafJpx3g7ZUs5vPvoYww4H4YJuDFDK5LLvHGhP13Kp5d0tAHHxIBITERToBS90YWN0/VQ==", "dependencies": { "js-yaml": "^3.13.1" } @@ -17398,9 +17350,9 @@ } }, "node_modules/parse-path": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.3.tgz", - "integrity": "sha512-9Cepbp2asKnWTJ9x2kpw6Fe8y9JDbqwahGCTvklzd/cEq5C5JC59x2Xb0Kx+x0QZ8bvNquGO8/BWP0cwBHzSAA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.4.tgz", + "integrity": "sha512-Z2lWUis7jlmXC1jeOG9giRO2+FsuyNipeQ43HAjqAZjwSe3SEf+q/84FGPHoso3kyntbxa4c4i77t3m6fGf8cw==", "dependencies": { "is-ssh": "^1.3.0", "protocols": "^1.4.0", @@ -17441,12 +17393,6 @@ "node": ">=8" } }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -17559,9 +17505,9 @@ "dev": true }, "node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "engines": { "node": ">=8.6" }, @@ -18054,6 +18000,22 @@ "node": ">= 10" } }, + "node_modules/pretty-format/node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, "node_modules/pretty-ms": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", @@ -18114,9 +18076,9 @@ } }, "node_modules/prompts": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", - "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, "dependencies": { "kleur": "^3.0.3", @@ -18222,6 +18184,22 @@ "node": ">=6" } }, + "node_modules/pure-rand": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz", + "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -19149,6 +19127,15 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", "deprecated": "https://github.com/lydell/resolve-url#deprecated" }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/responselike": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", @@ -19232,15 +19219,6 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" }, - "node_modules/rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "dev": true, - "engines": { - "node": "6.* || >= 7.*" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -19299,52 +19277,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "node_modules/sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "deprecated": "some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added", - "dev": true, - "dependencies": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" - }, - "bin": { - "sane": "src/cli.js" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/sane/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/sane/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/sass": { "version": "1.55.0", "resolved": "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz", @@ -19362,18 +19294,6 @@ "node": ">=12.0.0" } }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/scss-parser": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/scss-parser/-/scss-parser-1.0.5.tgz", @@ -19980,13 +19900,6 @@ "node": ">=4" } }, - "node_modules/shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true, - "optional": true - }, "node_modules/shuffle-seed": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/shuffle-seed/-/shuffle-seed-1.1.6.tgz", @@ -20009,9 +19922,9 @@ } }, "node_modules/signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==" + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/signale": { "version": "1.4.0", @@ -20532,9 +20445,9 @@ } }, "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, "dependencies": { "buffer-from": "^1.0.0", @@ -20693,9 +20606,9 @@ } }, "node_modules/stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -21210,13 +21123,13 @@ } }, "node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" @@ -21275,11 +21188,11 @@ "dev": true }, "node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" @@ -21368,6 +21281,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "peer": true, "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" @@ -21565,22 +21479,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -21609,12 +21507,6 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "node_modules/throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", - "dev": true - }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -21781,41 +21673,6 @@ "node": ">=0.6" } }, - "node_modules/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/traverse": { "version": "0.6.6", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", @@ -21882,31 +21739,55 @@ } }, "node_modules/ts-jest": { - "version": "26.5.6", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.6.tgz", - "integrity": "sha512-rua+rCP8DxpA8b4DQD/6X2HQS8Zy/xzViVYfEs2OQu68tkCuKLV0Md8pmX55+W24uRIyAsf/BajRfxOs+R2MKA==", + "version": "29.1.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.0.tgz", + "integrity": "sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==", "dev": true, "dependencies": { "bs-logger": "0.x", - "buffer-from": "1.x", "fast-json-stable-stringify": "2.x", - "jest-util": "^26.1.0", - "json5": "2.x", - "lodash": "4.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", "make-error": "1.x", - "mkdirp": "1.x", "semver": "7.x", - "yargs-parser": "20.x" + "yargs-parser": "^21.0.1" }, "bin": { "ts-jest": "cli.js" }, "engines": { - "node": ">= 10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { - "jest": ">=26 <27", - "typescript": ">=3.8 <5.0" + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" } }, "node_modules/ts-node": { @@ -22085,12 +21966,11 @@ } }, "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.3.0.tgz", + "integrity": "sha512-gezeeOIZyQLGW5uuCeEnXF1aXmtt2afKspXz3YqoOcZ3l/YMJq1pujvgT+cz/Nw1O/7q/kSav5fihJHsC/AOUg==", "engines": { - "node": ">=10" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -22670,16 +22550,6 @@ "node": ">= 0.4.0" } }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "optional": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/uvu": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.3.tgz", @@ -22720,26 +22590,17 @@ "dev": true }, "node_modules/v8-to-istanbul": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", - "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", "dev": true, "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" + "convert-source-map": "^1.6.0" }, "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/v8-to-istanbul/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" + "node": ">=10.12.0" } }, "node_modules/validate-npm-package-license": { @@ -23261,18 +23122,6 @@ "browser-process-hrtime": "^1.0.0" } }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -23291,15 +23140,6 @@ "node": ">= 8" } }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true, - "engines": { - "node": ">=10.4" - } - }, "node_modules/websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", @@ -23338,20 +23178,6 @@ "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", "dev": true }, - "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -23611,12 +23437,227 @@ "url": "https://github.com/sponsors/wooorm" } }, + "packages/cowners": { + "name": "@pvm/cowners", + "version": "0.0.0-stub", + "license": "Apache-2.0", + "dependencies": { + "ignore": "^5.1.2", + "locate-path": "^5.0.0" + } + }, + "packages/plugin-conventional-changelog": { + "name": "@pvm/plugin-conventional-changelog", + "version": "0.0.0-stub", + "license": "Apache-2.0", + "dependencies": { + "conventional-changelog-angular": "^5.0.10", + "conventional-changelog-core": "^4.2.2", + "conventional-changelog-preset-loader": "^2.3.4", + "conventional-changelog-writer": "^5.0.0", + "conventional-commits-filter": "^2.0.7", + "conventional-commits-parser": "^3.2.1", + "stream-from-array": "^1.0.0", + "through2": "^4.0.2" + }, + "devDependencies": { + "@types/conventional-commits-parser": "^3.0.1" + }, + "peerDependencies": { + "@pvm/pvm": "^0.0.0-stub" + } + }, + "packages/plugin-conventional-changelog/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "packages/plugin-conventional-changelog/node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dependencies": { + "readable-stream": "3" + } + }, + "packages/plugin-conventional-semantic-release": { + "name": "@pvm/plugin-conventional-semantic-release", + "version": "0.0.0-stub", + "dependencies": { + "@semantic-release/commit-analyzer": "^8.0.1", + "conventional-commits-parser": "^3.2.1" + }, + "peerDependencies": { + "@pvm/pvm": "^0.0.0-stub", + "semantic-release": ">=16.0.0" + } + }, + "packages/plugin-github": { + "name": "@pvm/plugin-github", + "version": "0.0.0-stub", + "dependencies": { + "@octokit/auth-action": "^1.3.3", + "@octokit/auth-app": "^3.6.1", + "@octokit/openapi-types": "^11.2.0", + "hosted-git-info": "^3.0.2", + "octokit": "^1.7.0", + "parse-md": "^2.0.4" + }, + "peerDependencies": { + "@pvm/pvm": "^0.0.0-stub" + } + }, + "packages/plugin-github/node_modules/hosted-git-info": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz", + "integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "packages/plugin-github/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "packages/plugin-github/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "packages/plugin-gitlab": { + "name": "@pvm/plugin-gitlab", + "version": "0.0.0-stub", + "license": "Apache-2.0", + "dependencies": { + "@iarna/toml": "^2.2.5", + "marked": "^4.2.3", + "p-map": "^4.0.0", + "parse-md": "^2.0.4", + "parse-path": "^4.0.4" + }, + "peerDependencies": { + "@pvm/pvm": "^0.0.0-stub" + } + }, + "packages/plugin-gitlab/node_modules/marked": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.3.tgz", + "integrity": "sha512-slWRdJkbTZ+PjkyJnE30Uid64eHwbwa1Q25INCAYfZlK4o6ylagBy/Le9eWntqJFoFT93ikUKMv47GZ4gTwHkw==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, + "packages/plugin-gitlab/node_modules/parse-path": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.0.0.tgz", + "integrity": "sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog==", + "dependencies": { + "protocols": "^2.0.0" + } + }, + "packages/plugin-gitlab/node_modules/protocols": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz", + "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==" + }, + "packages/plugin-http-proxy": { + "name": "@pvm/plugin-http-proxy", + "version": "0.0.0-stub", + "license": "Apache-2.0", + "dependencies": { + "global-agent": "^2.1.12" + }, + "peerDependencies": { + "@pvm/pvm": "^0.0.0-stub" + } + }, + "packages/plugin-mattermost": { + "name": "@pvm/plugin-mattermost", + "version": "0.0.0-stub", + "license": "Apache-2.0", + "peerDependencies": { + "@pvm/pvm": "^0.0.0-stub" + } + }, + "packages/plugin-slack": { + "name": "@pvm/plugin-slack", + "version": "0.0.0-stub", + "license": "Apache-2.0", + "dependencies": { + "resolve-from": "^5.0.0", + "slackify-markdown": "4.3.1" + }, + "peerDependencies": { + "@pvm/pvm": "^0.0.0-stub" + } + }, "packages/pvm": { "name": "@pvm/pvm", "version": "0.0.0-stub", "license": "Apache-2.0", "dependencies": { - "@pvm/core": "0.0.0-stub" + "@hutson/parse-repository-url": "^5.0.0", + "@iarna/toml": "^2.2.3", + "@tinkoff/dippy": "^0.8.6", + "ajv": "^6.12.2", + "bin-version-check": "^4.0.0", + "bytes": "^3.1.0", + "chalk": "^4.0.0", + "chokidar": "^3.3.0", + "cli-table": "^0.3.6", + "cosmiconfig": "^6.0.0", + "date-fns": "^2.22.1", + "fast-deep-equal": "^3.1.3", + "fast-glob": "^3.1.1", + "front-matter": "^3.2.1", + "fs-extra": "^9.1.0", + "get-stdin": "^7.0.0", + "git-log-parser": "^1.2.0", + "git-url-parse": "^11.4.4", + "ignore": "^5.1.8", + "ini": "^1.3.8", + "json5": "^2.2.1", + "lodash": "^4.17.21", + "micromatch": "^3.1.10", + "mri": "^1.1.4", + "ms": "^2.1.3", + "nunjucks": "^3.2.0", + "p-map": "^4.0.0", + "remarkable": "^2.0.1", + "resolve-from": "^5.0.0", + "rfc6902": "^4.0.2", + "semver": "^7.3.0", + "shuffle-seed": "^1.1.6", + "signales": "^2.0.5", + "string-to-color": "^2.2.2", + "superheroes": "^3.0.0", + "tempy": "^1.0.1", + "through2": "^4.0.2", + "type-fest": "^3.3.0", + "uniq": "^1.0.1", + "viz.js": "^2.1.2", + "yargs": "^16.1.1" }, "bin": { "pvm": "bin/pvm.js" @@ -23625,6 +23666,7 @@ "packages/pvm-add-tag": { "name": "@pvm/add-tag", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@pvm/core": "0.0.0-stub", @@ -23637,6 +23679,7 @@ "packages/pvm-artifacts": { "name": "@pvm/artifacts", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@pvm/core": "0.0.0-stub", @@ -23653,73 +23696,10 @@ "@types/fs-extra": "^9.0.11" } }, - "packages/pvm-artifacts/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "packages/pvm-artifacts/node_modules/fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "packages/pvm-artifacts/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "packages/pvm-artifacts/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "packages/pvm-artifacts/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, "packages/pvm-changelog": { "name": "@pvm/changelog", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@pvm/artifacts": "0.0.0-stub", @@ -23742,57 +23722,6 @@ "@pvm/vcs": "0.0.0-stub" } }, - "packages/pvm-changelog/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "packages/pvm-changelog/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "packages/pvm-changelog/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "packages/pvm-changelog/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, "packages/pvm-config": { "name": "@pvm/config", "version": "0.0.0-stub", @@ -23820,6 +23749,7 @@ "packages/pvm-core": { "name": "@pvm/core", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@hutson/parse-repository-url": "^5.0.0", @@ -23855,30 +23785,10 @@ "@pvm/vcs": "0.0.0-stub" } }, - "packages/pvm-core/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "packages/pvm-core/node_modules/through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dependencies": { - "readable-stream": "3" - } - }, "packages/pvm-cowners": { "name": "@pvm/cowners", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "ignore": "^5.1.2", @@ -23906,6 +23816,7 @@ "packages/pvm-files": { "name": "@pvm/files", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@pvm/core": "0.0.0-stub", @@ -23917,57 +23828,6 @@ "yargs": "^16.1.1" } }, - "packages/pvm-files/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "packages/pvm-files/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "packages/pvm-files/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "packages/pvm-files/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, "packages/pvm-github": { "name": "@pvm/github", "version": "0.0.0-stub", @@ -24000,6 +23860,7 @@ "packages/pvm-gitlab": { "name": "@pvm/gitlab", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@iarna/toml": "^2.2.5", @@ -24025,6 +23886,7 @@ "packages/pvm-mattermost": { "name": "@pvm/mattermost", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@pvm/core": "0.0.0-stub", @@ -24035,6 +23897,7 @@ "packages/pvm-notifications": { "name": "@pvm/notifications", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@pvm/core": "^0.0.0-stub", @@ -24047,60 +23910,10 @@ "yargs": "^16.1.1" } }, - "packages/pvm-notifications/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "packages/pvm-notifications/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "packages/pvm-notifications/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "packages/pvm-notifications/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, "packages/pvm-pkgset": { "name": "@pvm/pkgset", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@pvm/core": "0.0.0-stub", @@ -24115,60 +23928,10 @@ "yargs": "^16.1.1" } }, - "packages/pvm-pkgset/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "packages/pvm-pkgset/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "packages/pvm-pkgset/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "packages/pvm-pkgset/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, "packages/pvm-plugin-conventional-changelog": { "name": "@pvm/plugin-conventional-changelog", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@pvm/core": "0.0.0-stub", @@ -24187,30 +23950,10 @@ "@types/conventional-commits-parser": "^3.0.1" } }, - "packages/pvm-plugin-conventional-changelog/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "packages/pvm-plugin-conventional-changelog/node_modules/through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dependencies": { - "readable-stream": "3" - } - }, "packages/pvm-plugin-conventional-semantic-release": { "name": "@pvm/plugin-conventional-semantic-release", "version": "0.0.0-stub", + "extraneous": true, "dependencies": { "@pvm/core": "0.0.0-stub", "@pvm/types": "0.0.0-stub", @@ -24224,6 +23967,7 @@ "packages/pvm-plugin-http-proxy": { "name": "@pvm/plugin-http-proxy", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "global-agent": "^2.1.12" @@ -24232,6 +23976,7 @@ "packages/pvm-releases": { "name": "@pvm/releases", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@pvm/artifacts": "0.0.0-stub", @@ -24249,65 +23994,10 @@ "@types/ms": "^0.7.31" } }, - "packages/pvm-releases/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "packages/pvm-releases/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "packages/pvm-releases/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "packages/pvm-releases/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "packages/pvm-releases/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, "packages/pvm-repository": { "name": "@pvm/repository", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@pvm/core": "0.0.0-stub", @@ -24320,6 +24010,7 @@ "packages/pvm-slack": { "name": "@pvm/slack", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@pvm/core": "^0.0.0-stub", @@ -24333,6 +24024,7 @@ "packages/pvm-suffixes": { "name": "@pvm/suffixes", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "superheroes": "^3.0.0" @@ -24341,6 +24033,7 @@ "packages/pvm-template": { "name": "@pvm/template", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@pvm/core": "0.0.0-stub", @@ -24361,6 +24054,7 @@ "packages/pvm-types": { "name": "@pvm/types", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@tinkoff/dippy": "^0.8.6" @@ -24369,6 +24063,7 @@ "packages/pvm-update": { "name": "@pvm/update", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@pvm/artifacts": "0.0.0-stub", @@ -24394,60 +24089,10 @@ "yargs": "^16.1.1" } }, - "packages/pvm-update/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "packages/pvm-update/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "packages/pvm-update/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "packages/pvm-update/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, "packages/pvm-vcs": { "name": "@pvm/vcs", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@pvm/core": "0.0.0-stub", @@ -24462,6 +24107,7 @@ "packages/pvm-vcs-fs": { "name": "@pvm/vcs-fs", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@pvm/core": "0.0.0-stub" @@ -24473,6 +24119,7 @@ "packages/pvm-vcs-git": { "name": "@pvm/vcs-git", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@pvm/core": "0.0.0-stub", @@ -24482,60 +24129,10 @@ "@pvm/vcs": "0.0.0-stub" } }, - "packages/pvm-vcs/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "packages/pvm-vcs/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "packages/pvm-vcs/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "packages/pvm-vcs/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, "packages/pvm-viz": { "name": "@pvm/viz", "version": "0.0.0-stub", + "extraneous": true, "license": "Apache-2.0", "dependencies": { "@pvm/di": "0.0.0-stub", @@ -24544,7 +24141,7 @@ "yargs": "^16.1.1" } }, - "packages/pvm-viz/node_modules/cliui": { + "packages/pvm/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", @@ -24554,7 +24151,33 @@ "wrap-ansi": "^7.0.0" } }, - "packages/pvm-viz/node_modules/wrap-ansi": { + "packages/pvm/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "packages/pvm/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "packages/pvm/node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dependencies": { + "readable-stream": "3" + } + }, + "packages/pvm/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", @@ -24570,7 +24193,7 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "packages/pvm-viz/node_modules/y18n": { + "packages/pvm/node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", @@ -24578,7 +24201,7 @@ "node": ">=10" } }, - "packages/pvm-viz/node_modules/yargs": { + "packages/pvm/node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", @@ -24660,6 +24283,7 @@ "src/libs/di": { "name": "@pvm/di", "version": "0.0.0-stub", + "extraneous": true, "dependencies": { "@pvm/types": "0.0.0-stub", "@tinkoff/dippy": "^0.8.6" @@ -24815,6 +24439,7 @@ "src/plugins/common-plugins": { "name": "@pvm/plugin-common-plugins", "version": "0.0.0-stub", + "extraneous": true, "dependencies": { "@pvm/add-tag": "0.0.0-stub", "@pvm/artifacts": "0.0.0-stub", @@ -24833,6 +24458,7 @@ "src/plugins/core": { "name": "@pvm/plugin-core", "version": "0.0.0-stub", + "extraneous": true, "dependencies": { "@iarna/toml": "^2.2.3", "@pvm/changelog": "0.0.0-stub", @@ -24858,60 +24484,10 @@ "yargs": "^16.1.1" } }, - "src/plugins/core/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "src/plugins/core/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "src/plugins/core/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "src/plugins/core/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, "src/plugins/github": { "name": "@pvm/plugin-github", "version": "0.0.0-stub", + "extraneous": true, "dependencies": { "@octokit/auth-action": "^1.3.3", "@octokit/auth-app": "^3.6.1", @@ -24926,33 +24502,6 @@ "parse-md": "^2.0.4" } }, - "src/plugins/github/node_modules/hosted-git-info": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz", - "integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "src/plugins/github/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "src/plugins/github/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "src/plugins/gitlab": { "name": "@pvm/plugin-gitlab", "version": "0.0.0-stub", @@ -24997,63 +24546,13 @@ "src/tokens/core": { "name": "@pvm/tokens-core", "version": "0.0.0-stub", + "extraneous": true, "dependencies": { "@pvm/di": "0.0.0-stub", "@pvm/types": "0.0.0-stub", "yargs": "^16.1.1" } }, - "src/tokens/core/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "src/tokens/core/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "src/tokens/core/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "src/tokens/core/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, "src/tokens/platform": { "name": "@pvm/tokens-platform", "version": "0.0.0-stub", @@ -25431,9 +24930,9 @@ } }, "@babel/helper-plugin-utils": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", - "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", "dev": true }, "@babel/helper-simple-access": { @@ -25454,10 +24953,16 @@ "@babel/types": "^7.16.7" } }, + "@babel/helper-string-parser": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", + "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", + "dev": true + }, "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==" + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" }, "@babel/helpers": { "version": "7.18.2", @@ -25471,11 +24976,11 @@ } }, "@babel/highlight": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz", - "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "requires": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -25582,6 +25087,15 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-jsx": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz", + "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.20.2" + } + }, "@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", @@ -25645,6 +25159,15 @@ "@babel/helper-plugin-utils": "^7.14.5" } }, + "@babel/plugin-syntax-typescript": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz", + "integrity": "sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.20.2" + } + }, "@babel/template": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", @@ -25726,12 +25249,13 @@ } }, "@babel/types": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.4.tgz", - "integrity": "sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==", + "version": "7.22.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.4.tgz", + "integrity": "sha512-Tx9x3UBHTTsMSW85WB2kphxYQVvrZ/t1FxD88IpSgIjiUJlCm9z+xWIDwyo1vffTwSqteqyznB8ZE9vYYk16zA==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-string-parser": "^7.21.5", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" } }, @@ -25741,16 +25265,6 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "dev": true, - "requires": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - } - }, "@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -25840,241 +25354,305 @@ "dev": true }, "@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", + "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", "dev": true, "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", "slash": "^3.0.0" } }, "@jest/core": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", - "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.5.0.tgz", + "integrity": "sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==", "dev": true, "requires": { - "@jest/console": "^26.6.2", - "@jest/reporters": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^29.5.0", + "@jest/reporters": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", + "ci-info": "^3.2.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.6.2", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-resolve-dependencies": "^26.6.3", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "jest-watcher": "^26.6.2", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "rimraf": "^3.0.0", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.5.0", + "jest-config": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-resolve-dependencies": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "jest-watcher": "^29.5.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" } + }, + "pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true } } }, "@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", + "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", "dev": true, "requires": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-mock": "^26.6.2" + "jest-mock": "^29.5.0" + } + }, + "@jest/expect": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", + "dev": true, + "requires": { + "expect": "^29.5.0", + "jest-snapshot": "^29.5.0" + } + }, + "@jest/expect-utils": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", + "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", + "dev": true, + "requires": { + "jest-get-type": "^29.4.3" + }, + "dependencies": { + "jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true + } } }, "@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", + "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", + "@jest/types": "^29.5.0", + "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" } }, "@jest/globals": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", - "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", + "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", "dev": true, "requires": { - "@jest/environment": "^26.6.2", - "@jest/types": "^26.6.2", - "expect": "^26.6.2" + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/types": "^29.5.0", + "jest-mock": "^29.5.0" } }, "@jest/reporters": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", - "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.5.0.tgz", + "integrity": "sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", + "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-instrument": "^5.1.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "node-notifier": "^8.0.0", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^7.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + } + }, + "@jest/schemas": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.25.16" } }, "@jest/source-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", - "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", + "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", "dev": true, "requires": { + "@jridgewell/trace-mapping": "^0.3.15", "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "graceful-fs": "^4.2.9" } }, "@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", + "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", "dev": true, "requires": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^29.5.0", + "@jest/types": "^29.5.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", - "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz", + "integrity": "sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==", "dev": true, "requires": { - "@jest/test-result": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3" + "@jest/test-result": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "slash": "^3.0.0" } }, "@jest/transform": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", - "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", + "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.6.2", - "babel-plugin-istanbul": "^6.0.0", + "@babel/core": "^7.11.6", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.6.2", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" + "write-file-atomic": "^4.0.2" }, "dependencies": { + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } } } }, "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "requires": { + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "@types/yargs": "^15.0.0", + "@types/yargs": "^17.0.8", "chalk": "^4.0.0" + }, + "dependencies": { + "@types/yargs": { + "version": "17.0.15", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.15.tgz", + "integrity": "sha512-ZHc4W2dnEQPfhn06TBEdWaiUHEZAocYaiVMfwOipY5jcJt/251wVrKCBWBetGZWO5CF8tdb7L3DmdxVlZ2BOIg==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + } } }, "@jridgewell/gen-mapping": { @@ -26089,9 +25667,9 @@ } }, "@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true }, "@jridgewell/set-array": { @@ -26101,19 +25679,19 @@ "dev": true }, "@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "@nodelib/fs.scandir": { @@ -26474,143 +26052,6 @@ "integrity": "sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw==", "dev": true }, - "@pvm/add-tag": { - "version": "file:packages/pvm-add-tag", - "requires": { - "@pvm/core": "0.0.0-stub", - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/update": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub" - } - }, - "@pvm/artifacts": { - "version": "file:packages/pvm-artifacts", - "requires": { - "@pvm/core": "0.0.0-stub", - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", - "@pvm/vcs-git": "0.0.0-stub", - "@types/fs-extra": "^9.0.11", - "chalk": "^4.0.0", - "fs-extra": "^10.0.0", - "tempy": "^1.0.1", - "yargs": "^16.1.1" - }, - "dependencies": { - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "@pvm/changelog": { - "version": "file:packages/pvm-changelog", - "requires": { - "@pvm/artifacts": "0.0.0-stub", - "@pvm/core": "0.0.0-stub", - "@pvm/di": "0.0.0-stub", - "@pvm/pkgset": "0.0.0-stub", - "@pvm/releases": "0.0.0-stub", - "@pvm/template": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/update": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", - "chalk": "^4.0.0", - "date-fns": "^2.7.0", - "front-matter": "^3.0.2", - "remarkable": "^2.0.0", - "resolve-from": "^5.0.0", - "yargs": "^16.1.1" - }, - "dependencies": { - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, "@pvm/cli-inline-remark-plugin": { "version": "file:tools/cli-inline-remark-plugin", "requires": { @@ -26644,282 +26085,16 @@ } } }, - "@pvm/core": { - "version": "file:packages/pvm-core", - "requires": { - "@hutson/parse-repository-url": "^5.0.0", - "@iarna/toml": "^2.2.3", - "@pvm/di": "0.0.0-stub", - "@pvm/plugin-common-plugins": "0.0.0-stub", - "@pvm/releases": "0.0.0-stub", - "@pvm/suffixes": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/types": "^0.0.0-stub", - "@pvm/update": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", - "ajv": "^6.12.2", - "bin-version-check": "^4.0.0", - "chalk": "^4.0.0", - "cli-table": "^0.3.6", - "cosmiconfig": "^6.0.0", - "fast-deep-equal": "^3.1.3", - "fast-glob": "^3.1.1", - "git-log-parser": "^1.2.0", - "git-url-parse": "^11.4.4", - "js-yaml": "^3.13.1", - "json5": "^2.2.1", - "micromatch": "^3.1.10", - "mri": "^1.1.4", - "p-each-series": "^2.1.0", - "resolve-from": "^5.0.0", - "rfc6902": "^4.0.2", - "semver": "^7.3.0", - "signales": "^2.0.5", - "through2": "^4.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "requires": { - "readable-stream": "3" - } - } - } - }, "@pvm/cowners": { - "version": "file:packages/pvm-cowners", + "version": "file:packages/cowners", "requires": { "ignore": "^5.1.2", "locate-path": "^5.0.0" } }, - "@pvm/di": { - "version": "file:src/libs/di", - "requires": { - "@pvm/types": "0.0.0-stub", - "@tinkoff/dippy": "^0.8.6" - } - }, - "@pvm/files": { - "version": "file:packages/pvm-files", - "requires": { - "@pvm/core": "0.0.0-stub", - "@pvm/di": "0.0.0-stub", - "@pvm/pkgset": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "chalk": "^4.0.0", - "fast-glob": "^3.1.1", - "yargs": "^16.1.1" - }, - "dependencies": { - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "@pvm/gitlab": { - "version": "file:packages/pvm-gitlab", - "requires": { - "@iarna/toml": "^2.2.5", - "@pvm/core": "0.0.0-stub", - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", - "marked": "^2.1.3", - "p-map": "^4.0.0", - "parse-md": "^2.0.4", - "parse-path": "^4.0.1" - } - }, - "@pvm/mattermost": { - "version": "file:packages/pvm-mattermost", - "requires": { - "@pvm/core": "0.0.0-stub", - "@pvm/notifications": "0.0.0-stub", - "@pvm/types": "0.0.0-stub" - } - }, - "@pvm/notifications": { - "version": "file:packages/pvm-notifications", - "requires": { - "@pvm/core": "^0.0.0-stub", - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/types": "^0.0.0-stub", - "get-stdin": "^7.0.0", - "lodash.defaultsdeep": "4.6.1", - "resolve-from": "^5.0.0", - "yargs": "^16.1.1" - }, - "dependencies": { - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "@pvm/pkgset": { - "version": "file:packages/pvm-pkgset", - "requires": { - "@pvm/core": "0.0.0-stub", - "@pvm/di": "0.0.0-stub", - "@pvm/repository": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/types": "0.0.0-stub", - "chalk": "^4.0.0", - "fast-glob": "^3.1.1", - "micromatch": "^3.1.10", - "semver": "^7.3.0", - "yargs": "^16.1.1" - }, - "dependencies": { - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "@pvm/plugin-common-plugins": { - "version": "file:src/plugins/common-plugins", - "requires": { - "@pvm/add-tag": "0.0.0-stub", - "@pvm/artifacts": "0.0.0-stub", - "@pvm/changelog": "0.0.0-stub", - "@pvm/di": "0.0.0-stub", - "@pvm/files": "0.0.0-stub", - "@pvm/notifications": "0.0.0-stub", - "@pvm/pkgset": "0.0.0-stub", - "@pvm/plugin-core": "0.0.0-stub", - "@pvm/releases": "0.0.0-stub", - "@pvm/update": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", - "@pvm/viz": "0.0.0-stub" - } - }, "@pvm/plugin-conventional-changelog": { - "version": "file:packages/pvm-plugin-conventional-changelog", + "version": "file:packages/plugin-conventional-changelog", "requires": { - "@pvm/core": "0.0.0-stub", - "@pvm/types": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", "@types/conventional-commits-parser": "^3.0.1", "conventional-changelog-angular": "^5.0.10", "conventional-changelog-core": "^4.2.2", @@ -26952,93 +26127,18 @@ } }, "@pvm/plugin-conventional-semantic-release": { - "version": "file:packages/pvm-plugin-conventional-semantic-release", + "version": "file:packages/plugin-conventional-semantic-release", "requires": { - "@pvm/core": "0.0.0-stub", - "@pvm/types": "0.0.0-stub", "@semantic-release/commit-analyzer": "^8.0.1", "conventional-commits-parser": "^3.2.1" } }, - "@pvm/plugin-core": { - "version": "file:src/plugins/core", - "requires": { - "@iarna/toml": "^2.2.3", - "@pvm/changelog": "0.0.0-stub", - "@pvm/core": "0.0.0-stub", - "@pvm/di": "0.0.0-stub", - "@pvm/notifications": "0.0.0-stub", - "@pvm/pkgset": "0.0.0-stub", - "@pvm/repository": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/types": "0.0.0-stub", - "@pvm/update": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", - "@pvm/viz": "0.0.0-stub", - "chalk": "^4.0.0", - "cli-table": "^0.3.6", - "get-stdin": "^7.0.0", - "ini": "^1.3.8", - "lodash": "^4.2.0", - "micromatch": "^3.1.10", - "p-map": "^4.0.0", - "resolve-from": "^5.0.0", - "semver": "^7.3.0", - "yargs": "^16.1.1" - }, - "dependencies": { - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, "@pvm/plugin-github": { - "version": "file:src/plugins/github", + "version": "file:packages/plugin-github", "requires": { "@octokit/auth-action": "^1.3.3", "@octokit/auth-app": "^3.6.1", "@octokit/openapi-types": "^11.2.0", - "@pvm/core": "0.0.0-stub", - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/types": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", "hosted-git-info": "^3.0.2", "octokit": "^1.7.0", "parse-md": "^2.0.4" @@ -27067,194 +26167,95 @@ } } }, - "@pvm/plugin-http-proxy": { - "version": "file:packages/pvm-plugin-http-proxy", - "requires": { - "global-agent": "^2.1.12" - } - }, - "@pvm/pvm": { - "version": "file:packages/pvm", + "@pvm/plugin-gitlab": { + "version": "file:packages/plugin-gitlab", "requires": { - "@pvm/core": "0.0.0-stub" - } - }, - "@pvm/releases": { - "version": "file:packages/pvm-releases", - "requires": { - "@pvm/artifacts": "0.0.0-stub", - "@pvm/core": "0.0.0-stub", - "@pvm/di": "0.0.0-stub", - "@pvm/pkgset": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/update": "0.0.0-stub", - "@types/bytes": "^3.1.0", - "@types/ms": "^0.7.31", - "bytes": "^3.1.0", - "ms": "^2.1.3", - "yargs": "^16.1.1" + "@iarna/toml": "^2.2.5", + "marked": "^4.2.3", + "p-map": "^4.0.0", + "parse-md": "^2.0.4", + "parse-path": "^4.0.4" }, "dependencies": { - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "marked": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.3.tgz", + "integrity": "sha512-slWRdJkbTZ+PjkyJnE30Uid64eHwbwa1Q25INCAYfZlK4o6ylagBy/Le9eWntqJFoFT93ikUKMv47GZ4gTwHkw==" }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "parse-path": { + "version": "https://registry.npmjs.org/parse-path/-/parse-path-7.0.0.tgz", + "integrity": "sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog==", "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "protocols": "^2.0.0" } }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } + "protocols": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz", + "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==" } } }, - "@pvm/repository": { - "version": "file:packages/pvm-repository", + "@pvm/plugin-http-proxy": { + "version": "file:packages/plugin-http-proxy", "requires": { - "@pvm/core": "0.0.0-stub", - "@pvm/pkgset": "0.0.0-stub", - "@pvm/types": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", - "semver": "^7.3.0" + "global-agent": "^2.1.12" } }, - "@pvm/slack": { - "version": "file:packages/pvm-slack", + "@pvm/plugin-mattermost": { + "version": "file:packages/plugin-mattermost", + "requires": {} + }, + "@pvm/plugin-slack": { + "version": "file:packages/plugin-slack", "requires": { - "@pvm/core": "^0.0.0-stub", - "@pvm/notifications": "^0.0.0-stub", - "@pvm/types": "^0.0.0-stub", - "lodash.omitby": "^4.6.0", "resolve-from": "^5.0.0", "slackify-markdown": "4.3.1" } }, - "@pvm/suffixes": { - "version": "file:packages/pvm-suffixes", - "requires": { - "superheroes": "^3.0.0" - } - }, - "@pvm/template": { - "version": "file:packages/pvm-template", - "requires": { - "@pvm/core": "0.0.0-stub", - "chokidar": "^3.3.0", - "nunjucks": "^3.2.0", - "resolve-from": "^5.0.0" - } - }, - "@pvm/tokens-core": { - "version": "file:src/tokens/core", - "requires": { - "@pvm/di": "0.0.0-stub", - "@pvm/types": "0.0.0-stub", - "yargs": "^16.1.1" - }, - "dependencies": { - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "@pvm/types": { - "version": "file:packages/pvm-types", - "requires": { - "@tinkoff/dippy": "^0.8.6" - } - }, - "@pvm/update": { - "version": "file:packages/pvm-update", + "@pvm/pvm": { + "version": "file:packages/pvm", "requires": { - "@pvm/artifacts": "0.0.0-stub", - "@pvm/changelog": "0.0.0-stub", - "@pvm/core": "0.0.0-stub", - "@pvm/di": "0.0.0-stub", - "@pvm/notifications": "0.0.0-stub", - "@pvm/pkgset": "0.0.0-stub", - "@pvm/releases": "0.0.0-stub", - "@pvm/repository": "0.0.0-stub", - "@pvm/template": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/types": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", + "@hutson/parse-repository-url": "^5.0.0", + "@iarna/toml": "^2.2.3", + "@tinkoff/dippy": "^0.8.6", + "ajv": "^6.12.2", + "bin-version-check": "^4.0.0", + "bytes": "^3.1.0", "chalk": "^4.0.0", - "date-fns": "^2.7.0", - "ignore": "^5.1.4", + "chokidar": "^3.3.0", + "cli-table": "^0.3.6", + "cosmiconfig": "^6.0.0", + "date-fns": "^2.22.1", + "fast-deep-equal": "^3.1.3", + "fast-glob": "^3.1.1", + "front-matter": "^3.2.1", + "fs-extra": "^9.1.0", + "get-stdin": "^7.0.0", + "git-log-parser": "^1.2.0", + "git-url-parse": "^11.4.4", + "ignore": "^5.1.8", + "ini": "^1.3.8", + "json5": "^2.2.1", + "lodash": "^4.17.21", "micromatch": "^3.1.10", + "mri": "^1.1.4", + "ms": "^2.1.3", + "nunjucks": "^3.2.0", + "p-map": "^4.0.0", + "remarkable": "^2.0.1", "resolve-from": "^5.0.0", + "rfc6902": "^4.0.2", "semver": "^7.3.0", "shuffle-seed": "^1.1.6", + "signales": "^2.0.5", + "string-to-color": "^2.2.2", + "superheroes": "^3.0.0", + "tempy": "^1.0.1", + "through2": "^4.0.2", + "type-fest": "^3.3.0", "uniq": "^1.0.1", + "viz.js": "^2.1.2", "yargs": "^16.1.1" }, "dependencies": { @@ -27268,122 +26269,27 @@ "wrap-ansi": "^7.0.0" } }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "@pvm/vcs": { - "version": "file:packages/pvm-vcs", - "requires": { - "@pvm/core": "0.0.0-stub", - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/vcs-fs": "0.0.0-stub", - "@pvm/vcs-git": "0.0.0-stub", - "string-to-color": "^2.2.2", - "yargs": "^16.1.1" - }, - "dependencies": { - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "@pvm/vcs-fs": { - "version": "file:packages/pvm-vcs-fs", - "requires": { - "@pvm/core": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub" - } - }, - "@pvm/vcs-git": { - "version": "file:packages/pvm-vcs-git", - "requires": { - "@pvm/core": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", - "semver": "^7.3.0" - } - }, - "@pvm/viz": { - "version": "file:packages/pvm-viz", - "requires": { - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "viz.js": "^2.1.2", - "yargs": "^16.1.1" - }, - "dependencies": { - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "readable-stream": "3" } }, "wrap-ansi": { @@ -27732,6 +26638,12 @@ } } }, + "@sinclair/typebox": { + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", + "dev": true + }, "@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", @@ -27739,21 +26651,21 @@ "dev": true }, "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", "dev": true, "requires": { "type-detect": "4.0.8" } }, "@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.2.0.tgz", + "integrity": "sha512-OPwQlEdg40HAj5KNF8WW6q2KG4Z+cBCZb3m4ninfTZKaBmbIJodviQsDBoYMPHkOyJJMHnOJo5j2+LKDOhOACg==", "dev": true, "requires": { - "@sinonjs/commons": "^1.7.0" + "@sinonjs/commons": "^3.0.0" } }, "@szmarczak/http-timer": { @@ -27846,7 +26758,8 @@ "@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "peer": true }, "@tsconfig/node10": { "version": "1.0.8", @@ -27878,31 +26791,39 @@ "integrity": "sha512-cMRXVxb+NMb6EekKel1fPBfz2ZqE5cGhIS14G7FVUM4Bqilx0lHKnZbsDLWLSeckDpkvlp5six2F7UWyEEJSoQ==" }, "@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", + "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", "dev": true, "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" + }, + "dependencies": { + "@babel/parser": { + "version": "7.22.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.4.tgz", + "integrity": "sha512-VLLsx06XkEYqBtE5YGPwfSGwfrjnyPP5oiGty3S8pQLFDFLaS8VwWSIxkTXpcvr5zeYLE6+MBNl2npl/YnfofA==", + "dev": true + } } }, "@types/babel__generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", - "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, "requires": { "@babel/types": "^7.0.0" } }, "@types/babel__template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", - "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -27910,9 +26831,9 @@ } }, "@types/babel__traverse": { - "version": "7.17.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.17.1.tgz", - "integrity": "sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -27939,12 +26860,6 @@ "resolved": "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.0.tgz", "integrity": "sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg==" }, - "@types/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-5YG1AiIC8HPPXRvYAIa7ehK3YMAwd0DWiPCtpuL9sgKceWLyWsVtLRA+lT4NkoanDNF9slwQ66lPizWDpgRlWA==", - "dev": true - }, "@types/cacheable-request": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", @@ -28019,9 +26934,9 @@ } }, "@types/fs-extra": { - "version": "9.0.11", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.11.tgz", - "integrity": "sha512-mZsifGG4QeQ7hlkhO56u7zt/ycBgGxSVsFI/6lGTU34VtwkiqrrSDgw0+ygs8kFGWcXnFQWMrzF2h7TtDFNixA==", + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", "dev": true, "requires": { "@types/node": "*" @@ -28034,14 +26949,20 @@ "dev": true }, "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", "dev": true, "requires": { "@types/node": "*" } }, + "@types/hosted-git-info": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/hosted-git-info/-/hosted-git-info-3.0.2.tgz", + "integrity": "sha512-RURNTeEFUwF+ifnp7kK3WLLlTmBSlRynLNS9jeAsI6RHtSrupV0l0nO6kmpaz75EUJVexy348bR452SvmH98vQ==", + "dev": true + }, "@types/http-cache-semantics": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", @@ -28117,11 +27038,23 @@ "@types/node": "*" } }, + "@types/lodash": { + "version": "4.14.191", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", + "dev": true + }, "@types/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==" }, + "@types/marked": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.7.tgz", + "integrity": "sha512-eEAhnz21CwvKVW+YvRvcTuFKNU9CV1qH+opcgVK3pIMI6YZzDm6gc8o2vHjldFk6MGKt5pueSB7IOpvpx5Qekw==", + "dev": true + }, "@types/mdast": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz", @@ -28191,10 +27124,19 @@ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, + "@types/parse-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/parse-path/-/parse-path-4.0.1.tgz", + "integrity": "sha512-ZQffgFDaKTpSeO/NcBVPbJ21VvIuKAEcVMLapL6ltfrfIZyxNMjoQA+LB6af0E3C8dNVj+L76gjR6KzjKOA/9A==", + "dev": true, + "requires": { + "query-string": "^6.13.8" + } + }, "@types/prettier": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz", - "integrity": "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", "dev": true }, "@types/qs": { @@ -28241,9 +27183,9 @@ } }, "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, "@types/unist": { @@ -28845,16 +27787,6 @@ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, - "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, "acorn-jsx": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", @@ -28940,9 +27872,9 @@ "dev": true }, "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", @@ -29130,8 +28062,7 @@ "at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" }, "atob": { "version": "2.1.2", @@ -29165,18 +28096,17 @@ "dev": true }, "babel-jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", - "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", + "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", "dev": true, "requires": { - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.6.2", + "@jest/transform": "^29.5.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.5.0", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "slash": "^3.0.0" } }, @@ -29191,44 +28121,17 @@ "@istanbuljs/schema": "^0.1.2", "istanbul-lib-instrument": "^5.0.4", "test-exclude": "^6.0.0" - }, - "dependencies": { - "@babel/parser": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz", - "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } } }, "babel-plugin-jest-hoist": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", - "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", + "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", "dev": true, "requires": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", + "@types/babel__core": "^7.1.14", "@types/babel__traverse": "^7.0.6" } }, @@ -29264,12 +28167,12 @@ } }, "babel-preset-jest": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", - "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", + "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^26.6.2", + "babel-plugin-jest-hoist": "^29.5.0", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -29670,15 +28573,6 @@ } } }, - "capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "dev": true, - "requires": { - "rsvp": "^4.8.4" - } - }, "cardinal": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", @@ -29758,15 +28652,15 @@ } }, "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", + "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==", "dev": true }, "cjs-module-lexer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", - "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, "class-utils": { @@ -29930,7 +28824,7 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true }, "collapse-white-space": { @@ -30625,17 +29519,6 @@ "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==", "dev": true }, - "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "requires": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - } - }, "date-fns": { "version": "2.22.1", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.22.1.tgz", @@ -30688,12 +29571,6 @@ } } }, - "decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", - "dev": true - }, "decode-named-character-reference": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.1.tgz", @@ -30743,9 +29620,9 @@ "dev": true }, "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true }, "defer-to-connect": { @@ -31176,23 +30053,6 @@ } } }, - "domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "requires": { - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } - } - }, "dompurify": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.3.tgz", @@ -31304,9 +30164,9 @@ "dev": true }, "emittery": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", - "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true }, "emoji-regex": { @@ -31532,73 +30392,6 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, - "escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - } - } - }, "eslint": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.29.0.tgz", @@ -31981,12 +30774,6 @@ "es5-ext": "~0.10.14" } }, - "exec-sh": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", - "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==", - "dev": true - }, "execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", @@ -32049,7 +30836,7 @@ "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true }, "expand-brackets": { @@ -32159,17 +30946,24 @@ } }, "expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" + "@jest/expect-utils": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0" + }, + "dependencies": { + "jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true + } } }, "express": { @@ -32377,9 +31171,9 @@ } }, "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, "requires": { "bser": "2.1.1" @@ -32626,17 +31420,6 @@ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", "dev": true }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, "formdata-polyfill": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", @@ -32702,7 +31485,6 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, "requires": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -33200,6 +31982,14 @@ "dev": true, "requires": { "type-fest": "^0.20.2" + }, + "dependencies": { + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } } }, "globals-docs": { @@ -33249,16 +32039,9 @@ } }, "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" - }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==", - "dev": true, - "optional": true + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "handlebars": { "version": "4.7.7", @@ -33432,15 +32215,6 @@ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" }, - "html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.5" - } - }, "html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -33490,6 +32264,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "peer": true, "requires": { "@tootallnate/once": "1", "agent-base": "6", @@ -33527,6 +32302,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "peer": true, "requires": { "agent-base": "6", "debug": "4" @@ -33595,9 +32371,9 @@ } }, "import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, "requires": { "pkg-dir": "^4.2.0", @@ -33768,15 +32544,6 @@ "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", "dev": true }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, "is-core-module": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", @@ -33814,13 +32581,6 @@ "kind-of": "^6.0.2" } }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "optional": true - }, "is-empty": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-empty/-/is-empty-1.2.0.tgz", @@ -33938,12 +32698,6 @@ "isobject": "^3.0.1" } }, - "is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, "is-promise": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", @@ -34048,16 +32802,6 @@ "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", "dev": true }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "optional": true, - "requires": { - "is-docker": "^2.0.0" - } - }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -34099,17 +32843,24 @@ "dev": true }, "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "requires": { - "@babel/core": "^7.7.5", + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" }, "dependencies": { + "@babel/parser": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", + "dev": true + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -34130,9 +32881,9 @@ } }, "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "requires": { "debug": "^4.1.1", @@ -34149,9 +32900,9 @@ } }, "istanbul-reports": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", - "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -34165,63 +32916,54 @@ "peer": true }, "jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", - "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", + "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", "dev": true, "requires": { - "@jest/core": "^26.6.3", + "@jest/core": "^29.5.0", + "@jest/types": "^29.5.0", "import-local": "^3.0.2", - "jest-cli": "^26.6.3" + "jest-cli": "^29.5.0" } }, "jest-changed-files": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", - "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", + "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "execa": "^4.0.0", - "throat": "^5.0.0" + "execa": "^5.0.0", + "p-limit": "^3.1.0" }, "dependencies": { "execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, "npm-run-path": { @@ -34232,65 +32974,219 @@ "requires": { "path-key": "^3.0.0" } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + } + } + }, + "jest-circus": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", + "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", + "dev": true, + "requires": { + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.5.0", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.5.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true } } }, "jest-cli": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", - "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.5.0.tgz", + "integrity": "sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==", "dev": true, "requires": { - "@jest/core": "^26.6.3", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/core": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", "chalk": "^4.0.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.6.3", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", + "jest-config": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", "prompts": "^2.0.1", - "yargs": "^15.4.1" + "yargs": "^17.3.1" + }, + "dependencies": { + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + } } }, "jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.5.0.tgz", + "integrity": "sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.5.0", + "@jest/types": "^29.5.0", + "babel-jest": "^29.5.0", "chalk": "^4.0.0", + "ci-info": "^3.2.0", "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.5.0", + "jest-environment-node": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" }, "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true + }, "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true } } }, @@ -34307,54 +33203,70 @@ } }, "jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", + "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", "dev": true, "requires": { "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", + "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", "dev": true, "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^29.5.0", "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" - } - }, - "jest-environment-jsdom": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", - "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", - "dev": true, - "requires": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2", - "jsdom": "^16.4.0" + "jest-get-type": "^29.4.3", + "jest-util": "^29.5.0", + "pretty-format": "^29.5.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true + }, + "pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + } } }, "jest-environment-node": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", - "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.5.0.tgz", + "integrity": "sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==", "dev": true, "requires": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" } }, "jest-get-type": { @@ -34364,402 +33276,503 @@ "dev": true }, "jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", + "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@types/graceful-fs": "^4.1.2", + "@jest/types": "^29.5.0", + "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7" + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" }, "dependencies": { "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" } } } }, - "jest-jasmine2": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", - "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^26.6.2", - "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2", - "throat": "^5.0.0" - } - }, "jest-leak-detector": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", - "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz", + "integrity": "sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==", "dev": true, "requires": { - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true + }, + "pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + } } }, "jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "dev": true + }, + "jest-diff": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + } + }, + "jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true + }, + "pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + } } }, "jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.5.0", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "stack-utils": "^2.0.3" }, "dependencies": { + "@babel/code-frame": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", + "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" } + }, + "pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true } } }, "jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", + "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*" + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-util": "^29.5.0" } }, "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "requires": {} }, "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", "dev": true }, "jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", + "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", "dev": true, "requires": { - "@jest/types": "^26.6.2", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", "slash": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } } }, "jest-resolve-dependencies": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", - "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz", + "integrity": "sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.6.2" + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.5.0" } }, "jest-runner": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", - "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.5.0.tgz", + "integrity": "sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==", "dev": true, "requires": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^29.5.0", + "@jest/environment": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", - "emittery": "^0.7.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.6.2", - "jest-leak-detector": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-leak-detector": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-resolve": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-util": "^29.5.0", + "jest-watcher": "^29.5.0", + "jest-worker": "^29.5.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "dependencies": { + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + } } }, "jest-runtime": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", - "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/globals": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/yargs": "^15.0.0", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", + "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", + "dev": true, + "requires": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/globals": "^29.5.0", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", "chalk": "^4.0.0", - "cjs-module-lexer": "^0.6.0", + "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.4.1" - } - }, - "jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", - "dev": true, - "requires": { - "@types/node": "*", - "graceful-fs": "^4.2.4" + "strip-bom": "^4.0.0" } }, "jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", + "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", "dev": true, "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", + "expect": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" + "pretty-format": "^29.5.0", + "semver": "^7.3.5" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "dev": true + }, + "jest-diff": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + } + }, + "jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true + }, + "pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + } } }, "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", "dev": true, "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - }, - "dependencies": { - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - } + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" } }, "jest-validate": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", - "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", + "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "camelcase": "^6.0.0", + "@jest/types": "^29.5.0", + "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", + "jest-get-type": "^29.4.3", "leven": "^3.1.0", - "pretty-format": "^26.6.2" + "pretty-format": "^29.5.0" }, "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, "camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true + }, + "jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true + }, + "pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true } } }, "jest-watcher": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", - "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.5.0.tgz", + "integrity": "sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==", "dev": true, "requires": { - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^26.6.2", + "emittery": "^0.13.1", + "jest-util": "^29.5.0", "string-length": "^4.0.1" } }, "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", + "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", "dev": true, "requires": { "@types/node": "*", + "jest-util": "^29.5.0", "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" + "supports-color": "^8.0.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "js-tokens": { @@ -34782,49 +33795,6 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM= sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "dev": true }, - "jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "requires": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "dependencies": { - "acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true - } - } - }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -34885,9 +33855,9 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, "jsonfile": { "version": "6.1.0", @@ -35158,11 +34128,6 @@ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", "dev": true }, - "lodash.defaultsdeep": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz", - "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==" - }, "lodash.escaperegexp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", @@ -35204,17 +34169,18 @@ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "lodash.omitby": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.omitby/-/lodash.omitby-4.6.0.tgz", - "integrity": "sha1-XBX/R1StVVAWtTwEExHo8HkgR5E= sha512-5OrRcIVR75M288p4nbI2WLAf3ndw2GD9fyNv3Bc15+WCxJDdZ4lYndSxGd7hnG6PVjiJTeJE2dHEGhIuKGicIQ==" - }, "lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", @@ -36540,24 +35506,9 @@ "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, - "node-notifier": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", - "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", - "dev": true, - "optional": true, - "requires": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.2", - "shellwords": "^0.1.1", - "uuid": "^8.3.0", - "which": "^2.0.2" - } - }, "normalize-package-data": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", @@ -36865,8 +35816,6 @@ }, "@tootallnate/once": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "bundled": true, "peer": true }, @@ -36877,8 +35826,6 @@ }, "agent-base": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "bundled": true, "peer": true, "requires": { @@ -36897,8 +35844,6 @@ }, "aggregate-error": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "bundled": true, "peer": true, "requires": { @@ -36908,8 +35853,6 @@ }, "ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "bundled": true, "peer": true, "requires": { @@ -36926,8 +35869,6 @@ }, "ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "bundled": true, "peer": true, "requires": { @@ -36936,8 +35877,6 @@ }, "ansicolors": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", "bundled": true, "peer": true }, @@ -36972,8 +35911,6 @@ }, "asn1": { "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "bundled": true, "peer": true, "requires": { @@ -36982,43 +35919,31 @@ }, "assert-plus": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "bundled": true, "peer": true }, "asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "bundled": true, "peer": true }, "aws-sign2": { "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", "bundled": true, "peer": true }, "aws4": { "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "bundled": true, "peer": true }, "balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "bundled": true, "peer": true }, "bcrypt-pbkdf": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", "bundled": true, "peer": true, "requires": { @@ -37045,8 +35970,6 @@ }, "brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "bundled": true, "peer": true, "requires": { @@ -37086,15 +36009,11 @@ }, "caseless": { "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "bundled": true, "peer": true }, "chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "bundled": true, "peer": true, "requires": { @@ -37117,8 +36036,6 @@ }, "clean-stack": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "bundled": true, "peer": true }, @@ -37143,22 +36060,16 @@ "dependencies": { "ansi-regex": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "bundled": true, "peer": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "bundled": true, "peer": true }, "string-width": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "bundled": true, "peer": true, "requires": { @@ -37169,8 +36080,6 @@ }, "strip-ansi": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "bundled": true, "peer": true, "requires": { @@ -37199,8 +36108,6 @@ }, "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "bundled": true, "peer": true, "requires": { @@ -37209,8 +36116,6 @@ }, "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "bundled": true, "peer": true }, @@ -37236,8 +36141,6 @@ }, "combined-stream": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "bundled": true, "peer": true, "requires": { @@ -37251,8 +36154,6 @@ }, "concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "bundled": true, "peer": true }, @@ -37263,15 +36164,11 @@ }, "core-util-is": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", "bundled": true, "peer": true }, "dashdash": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "bundled": true, "peer": true, "requires": { @@ -37280,8 +36177,6 @@ }, "debug": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "bundled": true, "peer": true, "requires": { @@ -37290,8 +36185,6 @@ "dependencies": { "ms": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "bundled": true, "peer": true } @@ -37312,8 +36205,6 @@ }, "delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "bundled": true, "peer": true }, @@ -37343,8 +36234,6 @@ }, "ecc-jsbn": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", "bundled": true, "peer": true, "requires": { @@ -37354,8 +36243,6 @@ }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "bundled": true, "peer": true }, @@ -37380,29 +36267,21 @@ }, "extend": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "bundled": true, "peer": true }, "extsprintf": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", "bundled": true, "peer": true }, "fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "bundled": true, "peer": true }, "fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "bundled": true, "peer": true }, @@ -37413,8 +36292,6 @@ }, "forever-agent": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", "bundled": true, "peer": true }, @@ -37428,15 +36305,11 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "bundled": true, "peer": true }, "function-bind": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "bundled": true, "peer": true }, @@ -37458,8 +36331,6 @@ }, "getpass": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "bundled": true, "peer": true, "requires": { @@ -37481,22 +36352,16 @@ }, "graceful-fs": { "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", "bundled": true, "peer": true }, "har-schema": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", "bundled": true, "peer": true }, "har-validator": { "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "bundled": true, "peer": true, "requires": { @@ -37506,8 +36371,6 @@ }, "has": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "bundled": true, "peer": true, "requires": { @@ -37516,8 +36379,6 @@ }, "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "bundled": true, "peer": true }, @@ -37528,8 +36389,6 @@ }, "hosted-git-info": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", - "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", "bundled": true, "peer": true, "requires": { @@ -37543,8 +36402,6 @@ }, "http-proxy-agent": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "bundled": true, "peer": true, "requires": { @@ -37555,8 +36412,6 @@ }, "http-signature": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", "bundled": true, "peer": true, "requires": { @@ -37601,15 +36456,11 @@ }, "imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "bundled": true, "peer": true }, "indent-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "bundled": true, "peer": true }, @@ -37620,8 +36471,6 @@ }, "inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "bundled": true, "peer": true, "requires": { @@ -37631,8 +36480,6 @@ }, "inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "bundled": true, "peer": true }, @@ -37693,50 +36540,36 @@ }, "is-typedarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "bundled": true, "peer": true }, "isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "bundled": true, "peer": true }, "isstream": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", "bundled": true, "peer": true }, "jsbn": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "bundled": true, "peer": true }, "json-parse-even-better-errors": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "bundled": true, "peer": true }, "json-schema": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ==", "bundled": true, "peer": true }, "json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "bundled": true, "peer": true }, @@ -37747,8 +36580,6 @@ }, "json-stringify-safe": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "bundled": true, "peer": true }, @@ -37759,8 +36590,6 @@ }, "jsprim": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=sha512-4Dj8Rf+fQ+/Pn7C5qeEX02op1WfOss3PKTE9Nsop3Dx+6UPxlm1dr/og7o2cRa5hNN07CACr4NFzRLtj/rjWog==", "bundled": true, "peer": true, "requires": { @@ -37903,8 +36732,6 @@ }, "lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "bundled": true, "peer": true, "requires": { @@ -38132,8 +36959,6 @@ }, "normalize-package-data": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", "bundled": true, "peer": true, "requires": { @@ -38259,22 +37084,16 @@ }, "oauth-sign": { "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "bundled": true, "peer": true }, "object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "bundled": true, "peer": true }, "once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "bundled": true, "peer": true, "requires": { @@ -38288,8 +37107,6 @@ }, "p-map": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "bundled": true, "peer": true, "requires": { @@ -38334,15 +37151,11 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "bundled": true, "peer": true }, "performance-now": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", "bundled": true, "peer": true }, @@ -38385,15 +37198,11 @@ }, "psl": { "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", "bundled": true, "peer": true }, "punycode": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "bundled": true, "peer": true }, @@ -38404,8 +37213,6 @@ }, "qs": { "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "bundled": true, "peer": true }, @@ -38444,8 +37251,6 @@ }, "readable-stream": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "bundled": true, "peer": true, "requires": { @@ -38467,8 +37272,6 @@ }, "request": { "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "bundled": true, "peer": true, "requires": { @@ -38496,8 +37299,6 @@ "dependencies": { "form-data": { "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "bundled": true, "peer": true, "requires": { @@ -38524,8 +37325,6 @@ }, "rimraf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "bundled": true, "peer": true, "requires": { @@ -38534,22 +37333,16 @@ }, "safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "bundled": true, "peer": true }, "safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "bundled": true, "peer": true }, "semver": { "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "bundled": true, "peer": true, "requires": { @@ -38558,8 +37351,6 @@ }, "set-blocking": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "bundled": true, "peer": true }, @@ -38594,8 +37385,6 @@ }, "spdx-correct": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "bundled": true, "peer": true, "requires": { @@ -38605,15 +37394,11 @@ }, "spdx-exceptions": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "bundled": true, "peer": true }, "spdx-expression-parse": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "bundled": true, "peer": true, "requires": { @@ -38628,8 +37413,6 @@ }, "sshpk": { "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "bundled": true, "peer": true, "requires": { @@ -38686,8 +37469,6 @@ }, "stringify-package": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz", - "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==", "bundled": true, "peer": true }, @@ -38701,8 +37482,6 @@ }, "supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "bundled": true, "peer": true, "requires": { @@ -38739,8 +37518,6 @@ }, "tunnel-agent": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "bundled": true, "peer": true, "requires": { @@ -38749,15 +37526,11 @@ }, "tweetnacl": { "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", "bundled": true, "peer": true }, "typedarray-to-buffer": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "bundled": true, "peer": true, "requires": { @@ -38782,8 +37555,6 @@ }, "uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "bundled": true, "peer": true, "requires": { @@ -38792,22 +37563,16 @@ }, "util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "bundled": true, "peer": true }, "uuid": { "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "bundled": true, "peer": true }, "validate-npm-package-license": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "bundled": true, "peer": true, "requires": { @@ -38825,8 +37590,6 @@ }, "verror": { "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", "bundled": true, "peer": true, "requires": { @@ -38850,8 +37613,6 @@ }, "which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "bundled": true, "peer": true, "requires": { @@ -38868,8 +37629,6 @@ }, "wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "bundled": true, "peer": true }, @@ -38886,8 +37645,6 @@ }, "yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "bundled": true, "peer": true } @@ -39134,7 +37891,8 @@ "p-each-series": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", - "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==" + "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", + "peer": true }, "p-filter": { "version": "2.1.0", @@ -39265,9 +38023,9 @@ } }, "parse-md": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/parse-md/-/parse-md-2.0.4.tgz", - "integrity": "sha512-P45VmpnIo2QGErCa+YnpndzKXcu2v5qpFX31pOyGY+Ub9KuCAm6qKXCbR3sRsoESuy6XeY81hEIVnn6xz+0YcA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/parse-md/-/parse-md-2.0.5.tgz", + "integrity": "sha512-7ZhRqwFRTAXyr/PcXSafJpx3g7ZUs5vPvoYww4H4YJuDFDK5LLvHGhP13Kp5d0tAHHxIBITERToBS90YWN0/VQ==", "requires": { "js-yaml": "^3.13.1" } @@ -39279,9 +38037,9 @@ "dev": true }, "parse-path": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.3.tgz", - "integrity": "sha512-9Cepbp2asKnWTJ9x2kpw6Fe8y9JDbqwahGCTvklzd/cEq5C5JC59x2Xb0Kx+x0QZ8bvNquGO8/BWP0cwBHzSAA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.4.tgz", + "integrity": "sha512-Z2lWUis7jlmXC1jeOG9giRO2+FsuyNipeQ43HAjqAZjwSe3SEf+q/84FGPHoso3kyntbxa4c4i77t3m6fGf8cw==", "requires": { "is-ssh": "^1.3.0", "protocols": "^1.4.0", @@ -39317,12 +38075,6 @@ } } }, - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -39408,9 +38160,9 @@ "dev": true }, "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, "pid-port": { "version": "0.1.1", @@ -39765,6 +38517,21 @@ "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^17.0.1" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + } } }, "pretty-ms": { @@ -39811,9 +38578,9 @@ "dev": true }, "prompts": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", - "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, "requires": { "kleur": "^3.0.3", @@ -39899,6 +38666,12 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, + "pure-rand": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.2.tgz", + "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==", + "dev": true + }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -40579,6 +39352,12 @@ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==" }, + "resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true + }, "responselike": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", @@ -40642,12 +39421,6 @@ } } }, - "rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "dev": true - }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -40689,44 +39462,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "dev": true, - "requires": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, "sass": { "version": "1.55.0", "resolved": "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz", @@ -40738,15 +39473,6 @@ "source-map-js": ">=0.6.2 <2.0.0" } }, - "saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "requires": { - "xmlchars": "^2.2.0" - } - }, "scss-parser": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/scss-parser/-/scss-parser-1.0.5.tgz", @@ -41220,13 +39946,6 @@ "rechoir": "^0.6.2" } }, - "shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true, - "optional": true - }, "shuffle-seed": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/shuffle-seed/-/shuffle-seed-1.1.6.tgz", @@ -41246,9 +39965,9 @@ } }, "signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==" + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "signale": { "version": "1.4.0", @@ -41649,9 +40368,9 @@ } }, "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -41786,9 +40505,9 @@ } }, "stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -42198,13 +40917,13 @@ } }, "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "strip-ansi": "^6.0.1" }, "dependencies": { "emoji-regex": { @@ -42252,11 +40971,11 @@ "dev": true }, "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" } }, "strip-bom": { @@ -42318,6 +41037,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "peer": true, "requires": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" @@ -42463,16 +41183,6 @@ } } }, - "terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - } - }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -42495,12 +41205,6 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", - "dev": true - }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -42646,34 +41350,6 @@ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", "dev": true }, - "tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dev": true, - "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - }, - "dependencies": { - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - } - } - }, - "tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "requires": { - "punycode": "^2.1.1" - } - }, "traverse": { "version": "0.6.6", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", @@ -42723,21 +41399,27 @@ } }, "ts-jest": { - "version": "26.5.6", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.6.tgz", - "integrity": "sha512-rua+rCP8DxpA8b4DQD/6X2HQS8Zy/xzViVYfEs2OQu68tkCuKLV0Md8pmX55+W24uRIyAsf/BajRfxOs+R2MKA==", + "version": "29.1.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.0.tgz", + "integrity": "sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==", "dev": true, "requires": { "bs-logger": "0.x", - "buffer-from": "1.x", "fast-json-stable-stringify": "2.x", - "jest-util": "^26.1.0", - "json5": "2.x", - "lodash": "4.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", "make-error": "1.x", - "mkdirp": "1.x", "semver": "7.x", - "yargs-parser": "20.x" + "yargs-parser": "^21.0.1" + }, + "dependencies": { + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + } } }, "ts-node": { @@ -42866,10 +41548,9 @@ "dev": true }, "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.3.0.tgz", + "integrity": "sha512-gezeeOIZyQLGW5uuCeEnXF1aXmtt2afKspXz3YqoOcZ3l/YMJq1pujvgT+cz/Nw1O/7q/kSav5fihJHsC/AOUg==" }, "type-is": { "version": "1.6.18", @@ -43311,13 +41992,6 @@ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "optional": true - }, "uvu": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.3.tgz", @@ -43348,22 +42022,14 @@ "dev": true }, "v8-to-istanbul": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", - "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", "dev": true, "requires": { + "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "dependencies": { - "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true - } + "convert-source-map": "^1.6.0" } }, "validate-npm-package-license": { @@ -43783,15 +42449,6 @@ "browser-process-hrtime": "^1.0.0" } }, - "w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "requires": { - "xml-name-validator": "^3.0.0" - } - }, "walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -43807,12 +42464,6 @@ "integrity": "sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==", "dev": true }, - "webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true - }, "websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", @@ -43845,17 +42496,6 @@ "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", "dev": true }, - "whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "requires": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - } - }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 1198eafa9..a17eb1aef 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,6 @@ "workspaces": { "packages": [ "packages/*", - "src/tokens/*", - "src/plugins/*", - "src/libs/*", - "src/types/*", "tools/*" ] }, @@ -21,10 +17,8 @@ "build": "tsc -p tsconfig.json -d", "watch": "tsc -p tsconfig.json -d --watch --sourceMap", "build-docs": "bash -c 'scripts/build-doc.sh'", - "check-ts-strict": "tsc -p tsconfig.strict.json -d --noEmit", - "watch-ts-strict": "tsc -p tsconfig.strict.json -d --watch --noEmit", - "lint": "eslint --ext .js,.ts packages test", - "generate-config-schema": "cross-env NODE_OPTIONS=\\\"--unhandled-rejections=strict\\\" npm exec typescript-json-schema -- --out packages/pvm-types/lib/config-schema.json packages/pvm-types/lib/config-schema.ts Config && npm exec typescript-json-schema -- --out packages/pvm-types/lib/env-schema.json packages/pvm-types/lib/env-schema.ts Env", + "lint": "eslint --ext .ts packages test", + "generate-config-schema": "cross-env NODE_OPTIONS=\"--unhandled-rejections=strict\" npm exec typescript-json-schema -- --out packages/pvm/types/config-schema.json packages/pvm/types/config-schema.ts Config && npm exec typescript-json-schema -- --out packages/pvm/types/env-schema.json packages/pvm/types/env-schema.ts Env", "check-no-staged-changes": "git diff --name-only --exit-code", "lint:config-schema": "bash -c 'scripts/check-config-sync.sh'", "whoami": "node ./user.js" @@ -49,6 +43,11 @@ "@typescript-eslint/eslint-plugin": "^4.28.2", "@typescript-eslint/parser": "^4.20.0", "@tinkoff-monorepo/depscheck": "^1.8.21", + "@types/fs-extra": "^9.0.13", + "@types/lodash": "^4.14.191", + "@types/marked": "^4.0.7", + "@types/parse-path": "^4.0.1", + "@types/hosted-git-info": "^3.0.2", "babel-polyfill": "^6.26.0", "bench": "^0.3.6", "body-parser": "^1.18.3", @@ -70,7 +69,7 @@ "fkill": "^7.0.0", "fs-extra": "^9.0.1", "glob": "^7.2.0", - "jest": "26.6.3", + "jest": "^29.3.1", "json": "^9.0.6", "nock": "^13.0.4", "node-fetch": "^3.1.0", @@ -80,7 +79,7 @@ "remark-parse": "^10.0.1", "remark-stringify": "^10.0.2", "sprout-data": "^1.3.0", - "ts-jest": "^26.4.4", + "ts-jest": "^29.0.3", "typescript": "^4.7.4", "typescript-json-schema": "^0.51.0", "unified": "^10.1.2", diff --git a/packages/pvm-artifacts/.npmignore b/packages/cowners/.npmignore similarity index 80% rename from packages/pvm-artifacts/.npmignore rename to packages/cowners/.npmignore index e13e0d218..6a57518a1 100644 --- a/packages/pvm-artifacts/.npmignore +++ b/packages/cowners/.npmignore @@ -1,4 +1,5 @@ *.ts !*.d.ts +*.js.map __tests__ __snapshots__ diff --git a/packages/pvm-cowners/README.md b/packages/cowners/README.md similarity index 95% rename from packages/pvm-cowners/README.md rename to packages/cowners/README.md index b6d201d52..1d71b6d01 100644 --- a/packages/pvm-cowners/README.md +++ b/packages/cowners/README.md @@ -5,7 +5,7 @@ A library for working with CODEOWNERS file. ## Usage ```js -const { readCodeOwners } = require('@pvm/cowners') +const {readCodeOwners} = require('packages/cowners/lib/cowners') async function main() { const codeOwners = await readCodeOwners() diff --git a/packages/pvm-cowners/lib/__tests__/cowners.spec.ts b/packages/cowners/lib/__tests__/cowners.spec.ts similarity index 100% rename from packages/pvm-cowners/lib/__tests__/cowners.spec.ts rename to packages/cowners/lib/__tests__/cowners.spec.ts diff --git a/packages/pvm-cowners/lib/cowners.ts b/packages/cowners/lib/cowners.ts similarity index 100% rename from packages/pvm-cowners/lib/cowners.ts rename to packages/cowners/lib/cowners.ts diff --git a/packages/pvm-cowners/lib/iter.ts b/packages/cowners/lib/iter.ts similarity index 100% rename from packages/pvm-cowners/lib/iter.ts rename to packages/cowners/lib/iter.ts diff --git a/packages/pvm-cowners/lib/kvpairs.ts b/packages/cowners/lib/kvpairs.ts similarity index 100% rename from packages/pvm-cowners/lib/kvpairs.ts rename to packages/cowners/lib/kvpairs.ts diff --git a/packages/pvm-cowners/package.json b/packages/cowners/package.json similarity index 100% rename from packages/pvm-cowners/package.json rename to packages/cowners/package.json diff --git a/packages/pvm-add-tag/.npmignore b/packages/plugin-conventional-changelog/.npmignore similarity index 80% rename from packages/pvm-add-tag/.npmignore rename to packages/plugin-conventional-changelog/.npmignore index e13e0d218..6a57518a1 100644 --- a/packages/pvm-add-tag/.npmignore +++ b/packages/plugin-conventional-changelog/.npmignore @@ -1,4 +1,5 @@ *.ts !*.d.ts +*.js.map __tests__ __snapshots__ diff --git a/packages/pvm-plugin-conventional-changelog/README.md b/packages/plugin-conventional-changelog/README.md similarity index 100% rename from packages/pvm-plugin-conventional-changelog/README.md rename to packages/plugin-conventional-changelog/README.md diff --git a/packages/pvm-plugin-conventional-changelog/lib/common.ts b/packages/plugin-conventional-changelog/lib/common.ts similarity index 100% rename from packages/pvm-plugin-conventional-changelog/lib/common.ts rename to packages/plugin-conventional-changelog/lib/common.ts diff --git a/packages/plugin-conventional-changelog/lib/index.ts b/packages/plugin-conventional-changelog/lib/index.ts new file mode 100644 index 000000000..aa13dd406 --- /dev/null +++ b/packages/plugin-conventional-changelog/lib/index.ts @@ -0,0 +1,251 @@ +// @ts-ignore +import conventionalCommitsFilter from 'conventional-commits-filter' +// @ts-ignore +import conventionalChangelogPresetLoader from 'conventional-changelog-preset-loader' +// @ts-ignore +import conventionalChangelogWriter from 'conventional-changelog-writer' +// @ts-ignore +import mergeConfig from 'conventional-changelog-core/lib/merge-config' +// @ts-ignore +import streamFromArray from 'stream-from-array' +// @ts-ignore +import through from 'through2' +import resolvePreset from './preset-resolver' +import { parseCommit } from './common' +import type { ReleasedProps, Commit, ConventionalCommit } from '@pvm/pvm' +import { + CONFIG_TOKEN, + createToken, + declarePlugin, PLATFORM_TOKEN, + provide, + RELEASE_NOTIFICATIONS_MAP_TOKEN, +} from '@pvm/pvm' + +import { + COMMITS_TO_NOTES_TOKEN, + RELEASE_TYPE_BUILDER_TOKEN, + RELEASE_TYPE_BY_COMMITS_TOKEN, +} from '@pvm/pvm/tokens' +import type { PvmReleaseType } from '@pvm/pvm/types/publish' +import { releaseMessage } from './message-builder' + +export enum conventionalChangelogReleaseTypes {'major', 'minor', 'patch'} + +function parseCommits(commits: Commit[], parserOpts: Record): Array { + return commits.map(commit => { + const rawData = `${commit.subject}\n${commit.body}` + const parsed = parseCommit(rawData, parserOpts) + + if ('commit' in commit && commit.commit?.long) { + parsed.hash = commit.commit.long + } + + return parsed + }) +} + +const commitsCache = new Map() + +function parseCommitsWithCache(commits: Commit[], parserOpts: Record): Array { + if (commitsCache.has(commits)) { + return commitsCache.get(commits) + } + const parsed = parseCommits(commits, parserOpts) + commitsCache.set(commits, parsed) + return parsed +} + +/** + * Options that allowed to pass to plugin via config file + * + * Example + * ```javascript + * module.exports = { + * plugins: { + * options: { + * '@pvm/plugin-conventional-changelog': { + * ignoreReverted: false + * }, + * }, + * } + * } + * ``` + */ +export type PluginOpts = { + ignoreReverted?: boolean, + preset?: string, + config?: any, + /** + * Allow to customize release type choose behaviour + * + * .pvm.js example in which we disable version bump if all commits are of type 'chore' + * ```javascript + * module.exports = { + * update { + * default_release_type: 'none' + * }, + * plugins: { + * options: { + * '@pvm/plugin-conventional-changelog': { + * whatBump: (commits) => { + * return commits.every(c => c.type === 'chore') ? null : { level: 2 } + * }, + * }, + * }, + * } + * } + * ``` + * @param commits + */ + whatBump?: (commits: Array) => PvmReleaseType, +} + +const OPTS_TOKEN = createToken>('OPTS_TOKEN') + +export default declarePlugin({ + factory: (opts: PluginOpts = {}) => { + const { + ignoreReverted = true, + preset: passedPreset, + config: passedConfig, + whatBump, + } = opts + + return { + providers: [ + provide({ + provide: OPTS_TOKEN, + useFactory: async () => { + let presetPkg + const preset = !passedPreset && !passedConfig ? require.resolve('./preset') : passedPreset + if (preset) { + try { + presetPkg = conventionalChangelogPresetLoader(preset) + } catch (err) { + throw new Error(`Error loading "${preset}" conventional-changelog preset. Is it installed ?`) + } + } + + const config = await resolvePreset(presetPkg || passedConfig) || {} + opts.config = config + const mergedConfig = await mergeConfig(opts) + + const { recommendedBumpOpts = {} } = config + const { parserOpts: recommendedParserOpts } = recommendedBumpOpts + + const parserOpts = { + ...recommendedParserOpts, + ...mergedConfig.parserOpts, + } + + return { + parserOpts, + mergedConfig, + recommendedBumpOpts, + } + }, + }), + provide({ + provide: RELEASE_NOTIFICATIONS_MAP_TOKEN, + useFactory: ({ platform, config }) => ({ + release: (releaseProps: ReleasedProps) => releaseMessage(releaseProps, { + attachPackages: false, + platform, + config, + }), + releaseWithPackages: (releaseProps: ReleasedProps) => releaseMessage(releaseProps, { + attachPackages: true, + platform, + config, + }), + }), + deps: { + platform: PLATFORM_TOKEN, + config: CONFIG_TOKEN, + }, + }), + provide({ + provide: COMMITS_TO_NOTES_TOKEN, + useFactory: ({ opts }) => async (commits) => { + const { parserOpts, mergedConfig } = await opts + const commitsStream = streamFromArray.obj(parseCommitsWithCache(commits, parserOpts)) + const { writerOpts } = mergedConfig + writerOpts.includeDetails = false + + /* + Если репозиторий не-монорепа, то формат тегов - vX.X.X и это включает альтернативную логику включения вывода лога + Логика включения этого флага зашита в https://github.com/conventional-changelog/conventional-changelog/blob/8076d4666c2a3ea728b95bf1e4e78d4c7189b1dc/packages/conventional-changelog-core/lib/merge-config.js#L196. Логика включения коммита в + лог находится тут https://github.com/conventional-changelog/conventional-changelog/blob/8076d4666c2a3ea728b95bf1e4e78d4c7189b1dc/packages/conventional-changelog-writer/index.js#L147 + и видно, что если doFlush в false, то вывод лога регулируется наличием и валидностью version в объекте commit'а и + тут есть проблемы: + 1. Код, который проставляет версию в коммит находится в секции conventional-commit-changelog'а которая вызывается + только при генерации чейнджлога через него + 2. Pvm ставит версию в тег после генерации чейнджлога + 3. Pvm формирует релиз из всех коммитов с последнего релиза и ситуация когда может быть несколько секций в релизе - невозможна + */ + writerOpts.doFlush = true + + return new Promise((resolve, reject) => { + let result = '' + + const concatStream = through((chunk: string, _enc: void, cb: () => void) => { + result += chunk + cb() + }, (cb: () => void) => { + resolve(result) + cb() + }) + + commitsStream + .pipe(conventionalChangelogWriter(mergedConfig.context, writerOpts)) + .on('error', (e: any) => { + reject(e) + }) + .pipe(concatStream) + }) + }, + deps: { + opts: OPTS_TOKEN, + }, + }), + provide({ + provide: RELEASE_TYPE_BY_COMMITS_TOKEN, + useFactory: ({ opts, releaseTypeBuilder }) => async (gitCommits) => { + const { parserOpts, recommendedBumpOpts } = await opts + let commits = parseCommitsWithCache(gitCommits, parserOpts) + if (ignoreReverted) { + commits = conventionalCommitsFilter(commits) + } + + // для кастомного whatBump и билдера от плагинов мы ожидаем возвращаемого значения в формате строки releaseType или 'none' + const customWhatBump = whatBump || releaseTypeBuilder + if (customWhatBump) { + return await customWhatBump(commits) + } + + // recommendedBumpOpts.whatBump возвращает тип релиза в формате { result: { level: 0 | 1 | 2 } } + if (recommendedBumpOpts.whatBump) { + const result = recommendedBumpOpts.whatBump(commits) + if (result && result.level !== null) { + return conventionalChangelogReleaseTypes[result.level] as PvmReleaseType + } + } + + return null + }, + deps: { + opts: OPTS_TOKEN, + releaseTypeBuilder: { + token: RELEASE_TYPE_BUILDER_TOKEN, + optional: true, + }, + }, + }), + ], + } + }, +}) diff --git a/packages/pvm-plugin-conventional-changelog/lib/message-builder.ts b/packages/plugin-conventional-changelog/lib/message-builder.ts similarity index 81% rename from packages/pvm-plugin-conventional-changelog/lib/message-builder.ts rename to packages/plugin-conventional-changelog/lib/message-builder.ts index 7ec153810..1e7d92fcb 100644 --- a/packages/pvm-plugin-conventional-changelog/lib/message-builder.ts +++ b/packages/plugin-conventional-changelog/lib/message-builder.ts @@ -1,11 +1,9 @@ -import { initVcsPlatform } from '@pvm/vcs' -import { isGenericTagUsed } from '@pvm/core/lib/tag-meta' -import { issueToMdLink } from '@pvm/core/lib/text/jira' +import { isGenericTagUsed, issueToMdLink, defaultMessageBodyWrapper } from '@pvm/pvm' + import { parseCommit } from './common' import type { Commit as ConventionalCommit } from 'conventional-commits-parser' -import type { ReleasedProps, Message } from '@pvm/types' -import { defaultMessageBodyWrapper } from '@pvm/plugin-core/messages/message-builder' +import type { ReleasedProps, Message, Config, PlatformInterface } from '@pvm/pvm' function cutText(text: string, maxLen: number): string { return text.length <= maxLen ? text : text.substr(0, maxLen) @@ -13,6 +11,8 @@ function cutText(text: string, maxLen: number): string { interface MessageBuilderOpts { attachPackages?: boolean, + platform: PlatformInterface, + config: Config, } interface BodyWrapperParams { @@ -26,16 +26,16 @@ interface BuildMessageOpts { attachPackages?: boolean, bodyWrapper?: BodyWrapper, conventionalCommits?: ConventionalCommit[], + platform: PlatformInterface, + config: Config, } -async function buildMessage(releaseProps: ReleasedProps, opts: BuildMessageOpts = {}): Promise> { - const { tag, commits, pvmConfig, packagesStats } = releaseProps - const { cwd } = pvmConfig - - const { bodyWrapper = (x) => x, attachPackages = false, conventionalCommits = [] } = opts +async function buildMessage(releaseProps: ReleasedProps, opts: BuildMessageOpts): Promise> { + const { tag, commits, packagesStats } = releaseProps + const { bodyWrapper = (x) => x, attachPackages = false, conventionalCommits = [], config, platform } = opts // tag.slice(19) works like this: `release-09.07.2019-Slayback ` → `Slayback` - const releaseName = isGenericTagUsed(pvmConfig) ? tag.slice(19) : tag + const releaseName = isGenericTagUsed(config) ? tag.slice(19) : tag const commitsByType: Map< string, @@ -130,20 +130,17 @@ async function buildMessage(releaseProps: ReleasedProps, opts: BuildMessageOpts ], ]) - const vcs = await initVcsPlatform({ - cwd, - }) // eslint-disable-next-line max-statements for (const [i, commit] of (commits || []).entries()) { const conventionalCommit = conventionalCommits[i] - const commitLink = await vcs.getCommitLink(commit.commit.long) - const needAddIssueLink = pvmConfig.jira.url && conventionalCommit && conventionalCommit.references.length + const commitLink = await platform.getCommitLink(commit.commit.long) + const needAddIssueLink = config.jira.url && conventionalCommit && conventionalCommit.references.length const hasExtraInfo = commitLink || needAddIssueLink let message = commit.subject - if (pvmConfig.jira.url) { - message = issueToMdLink(pvmConfig.jira.url, message) + if (config.jira.url) { + message = issueToMdLink(config.jira.url, message) } if (hasExtraInfo) { @@ -165,7 +162,7 @@ async function buildMessage(releaseProps: ReleasedProps, opts: BuildMessageOpts conventionalCommit.references.forEach((ref, pI) => { const refsSeparator = pI > 0 ? ', ' : '' - message += `${refsSeparator}[${ref.issue}](${pvmConfig.jira.url}/browse/${ref.issue})` + message += `${refsSeparator}[${ref.issue}](${config.jira.url}/browse/${ref.issue})` }) } @@ -198,7 +195,7 @@ async function buildMessage(releaseProps: ReleasedProps, opts: BuildMessageOpts text = n.text ? `(${conventionalCommit.scope}): ` : conventionalCommit.scope } if (n.text) { - text += pvmConfig.jira.url ? issueToMdLink(pvmConfig.jira.url, n.text) : n.text + text += config.jira.url ? issueToMdLink(config.jira.url, n.text) : n.text } if (text) { commitsByType.get('notes')!.commits.push(`${text}`) @@ -219,7 +216,7 @@ async function buildMessage(releaseProps: ReleasedProps, opts: BuildMessageOpts } }) - const { releaseLink } = pvmConfig.templating.vars + const { releaseLink } = config.templating.vars const attachments: Message['attachments'] = [] @@ -244,10 +241,10 @@ async function buildMessage(releaseProps: ReleasedProps, opts: BuildMessageOpts export async function releaseMessage( releaseProps: ReleasedProps, - opts: MessageBuilderOpts = {} + opts: MessageBuilderOpts ): Promise> { - const { pvmConfig, packagesStats } = releaseProps - const { attachPackages = isGenericTagUsed(pvmConfig) } = opts + const { packagesStats } = releaseProps + const { platform, config, attachPackages = isGenericTagUsed(config) } = opts const conventionalCommits = convertCommitsToConvFormat(releaseProps.commits) return buildMessage(releaseProps, { @@ -261,6 +258,8 @@ export async function releaseMessage( }, attachPackages, conventionalCommits, + platform, + config, }) } diff --git a/packages/pvm-plugin-conventional-changelog/lib/preset-resolver.ts b/packages/plugin-conventional-changelog/lib/preset-resolver.ts similarity index 68% rename from packages/pvm-plugin-conventional-changelog/lib/preset-resolver.ts rename to packages/plugin-conventional-changelog/lib/preset-resolver.ts index ac7c78eed..98e04fb55 100644 --- a/packages/pvm-plugin-conventional-changelog/lib/preset-resolver.ts +++ b/packages/plugin-conventional-changelog/lib/preset-resolver.ts @@ -1,5 +1,5 @@ -function resolvePreset(preset): Record { +function resolvePreset(preset: ((cb: (err: any, result: any) => void) => Record) | Record): Record { if (typeof preset === 'function') { return new Promise((resolve, reject) => { preset((err, result) => { diff --git a/packages/pvm-plugin-conventional-changelog/lib/preset.ts b/packages/plugin-conventional-changelog/lib/preset.ts similarity index 91% rename from packages/pvm-plugin-conventional-changelog/lib/preset.ts rename to packages/plugin-conventional-changelog/lib/preset.ts index b2b8451a4..bf6e9c79e 100644 --- a/packages/pvm-plugin-conventional-changelog/lib/preset.ts +++ b/packages/plugin-conventional-changelog/lib/preset.ts @@ -2,6 +2,7 @@ import path from 'path' import fs from 'fs' import { conventionalChangelogParserOpts } from './common' +import type { Commit } from 'conventional-commits-parser' const resolveTemplate = (tplPath: string) => fs.readFileSync(path.resolve(__dirname, tplPath), 'utf-8') @@ -21,10 +22,10 @@ module.exports = new Promise((resolve) => { preset.writerOpts.headerPartial = resolveTemplate('./templates/header.hbs') preset.writerOpts.commitPartial = resolveTemplate('./templates/commit.hbs') - preset.writerOpts.transform = (commit, context) => { + preset.writerOpts.transform = (commit: Commit, context: any) => { const issues: string[] = [] - commit.notes.forEach((note) => { + commit.notes.forEach((note: any) => { note.title = '💥 BREAKING CHANGES' }) @@ -67,7 +68,7 @@ module.exports = new Promise((resolve) => { if (url) { url = `${url}/issues/` // Issue URLs. - commit.subject = commit.subject.replace(/#([0-9]+)/g, (_, issue) => { + commit.subject = commit.subject.replace(/#([0-9]+)/g, (_: any, issue: string) => { issues.push(issue) return `[${issue}](${url}${issue})` }) @@ -76,7 +77,7 @@ module.exports = new Promise((resolve) => { // User URLs. commit.subject = commit.subject.replace( /\B@([a-z0-9](?:-?[a-z0-9/]){0,38})/g, - (_, username) => { + (_: any, username: string) => { if (username.includes('/')) { return `@${username}` } @@ -88,7 +89,7 @@ module.exports = new Promise((resolve) => { } // remove references that already appear in the subject - commit.references = commit.references.filter((reference) => { + commit.references = commit.references.filter((reference: { issue: string }) => { if (issues.indexOf(reference.issue) === -1) { return true } diff --git a/packages/pvm-plugin-conventional-changelog/lib/templates/commit.hbs b/packages/plugin-conventional-changelog/lib/templates/commit.hbs similarity index 100% rename from packages/pvm-plugin-conventional-changelog/lib/templates/commit.hbs rename to packages/plugin-conventional-changelog/lib/templates/commit.hbs diff --git a/packages/pvm-plugin-conventional-changelog/lib/templates/header.hbs b/packages/plugin-conventional-changelog/lib/templates/header.hbs similarity index 100% rename from packages/pvm-plugin-conventional-changelog/lib/templates/header.hbs rename to packages/plugin-conventional-changelog/lib/templates/header.hbs diff --git a/packages/pvm-plugin-conventional-changelog/package.json b/packages/plugin-conventional-changelog/package.json similarity index 83% rename from packages/pvm-plugin-conventional-changelog/package.json rename to packages/plugin-conventional-changelog/package.json index 53973eaeb..f05e390e0 100644 --- a/packages/pvm-plugin-conventional-changelog/package.json +++ b/packages/plugin-conventional-changelog/package.json @@ -6,10 +6,6 @@ "author": "Andrey Rublev ", "license": "Apache-2.0", "dependencies": { - "@pvm/core": "0.0.0-stub", - "@pvm/plugin-core": "0.0.0-stub", - "@pvm/types": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", "conventional-changelog-angular": "^5.0.10", "conventional-changelog-core": "^4.2.2", "conventional-changelog-preset-loader": "^2.3.4", @@ -19,6 +15,9 @@ "stream-from-array": "^1.0.0", "through2": "^4.0.2" }, + "peerDependencies": { + "@pvm/pvm": "^0.0.0-stub" + }, "devDependencies": { "@types/conventional-commits-parser": "^3.0.1" } diff --git a/packages/pvm-changelog/.npmignore b/packages/plugin-conventional-semantic-release/.npmignore similarity index 80% rename from packages/pvm-changelog/.npmignore rename to packages/plugin-conventional-semantic-release/.npmignore index e13e0d218..6a57518a1 100644 --- a/packages/pvm-changelog/.npmignore +++ b/packages/plugin-conventional-semantic-release/.npmignore @@ -1,4 +1,5 @@ *.ts !*.d.ts +*.js.map __tests__ __snapshots__ diff --git a/packages/pvm-plugin-conventional-semantic-release/README.md b/packages/plugin-conventional-semantic-release/README.md similarity index 100% rename from packages/pvm-plugin-conventional-semantic-release/README.md rename to packages/plugin-conventional-semantic-release/README.md diff --git a/packages/pvm-plugin-conventional-semantic-release/lib/analyze-commits.ts b/packages/plugin-conventional-semantic-release/lib/analyze-commits.ts similarity index 94% rename from packages/pvm-plugin-conventional-semantic-release/lib/analyze-commits.ts rename to packages/plugin-conventional-semantic-release/lib/analyze-commits.ts index 13349d30d..631212bc1 100644 --- a/packages/pvm-plugin-conventional-semantic-release/lib/analyze-commits.ts +++ b/packages/plugin-conventional-semantic-release/lib/analyze-commits.ts @@ -1,10 +1,14 @@ import type { Commit } from 'conventional-commits-parser' +// @ts-ignore import DEFAULT_RELEASE_RULES from '@semantic-release/commit-analyzer/lib/default-release-rules' +// @ts-ignore import compareReleaseTypes from '@semantic-release/commit-analyzer/lib/compare-release-types' +// @ts-ignore import RELEASE_TYPES from '@semantic-release/commit-analyzer/lib/default-release-types' +// @ts-ignore import analyzeCommit from '@semantic-release/commit-analyzer/lib/analyze-commit' import { logger } from './logger' -import type { PvmReleaseType } from '@pvm/types' +import type { PvmReleaseType } from '@pvm/pvm' import type { Options } from './types' // taken from https://github.com/semantic-release/commit-analyzer/blob/master/index.js diff --git a/packages/plugin-conventional-semantic-release/lib/index.ts b/packages/plugin-conventional-semantic-release/lib/index.ts new file mode 100644 index 000000000..4c17c3491 --- /dev/null +++ b/packages/plugin-conventional-semantic-release/lib/index.ts @@ -0,0 +1,21 @@ +import { analyzeCommits } from './analyze-commits' + +import type { PvmReleaseType, ConventionalCommit } from '@pvm/pvm' +import { declarePlugin, provide } from '@pvm/pvm' +import type { Options } from './types' +import { RELEASE_TYPE_BUILDER_TOKEN } from '@pvm/pvm/tokens' + +export default declarePlugin({ + factory: (opts: Options = {}) => { + return { + providers: [ + provide({ + provide: RELEASE_TYPE_BUILDER_TOKEN, + useValue: function releaseTypeBuilder(commits: ConventionalCommit[]): Promise { + return Promise.resolve(analyzeCommits(commits, opts)) + }, + }), + ], + } + }, +}) diff --git a/packages/pvm-plugin-conventional-semantic-release/lib/logger.ts b/packages/plugin-conventional-semantic-release/lib/logger.ts similarity index 58% rename from packages/pvm-plugin-conventional-semantic-release/lib/logger.ts rename to packages/plugin-conventional-semantic-release/lib/logger.ts index 3dca60196..ae0788bec 100644 --- a/packages/pvm-plugin-conventional-semantic-release/lib/logger.ts +++ b/packages/plugin-conventional-semantic-release/lib/logger.ts @@ -1,3 +1,3 @@ -import { loggerFor } from '@pvm/core/lib/logger' +import { loggerFor } from '@pvm/pvm' export const logger = loggerFor('pvm:conventional-preset-semantic') diff --git a/packages/pvm-plugin-conventional-semantic-release/lib/types.ts b/packages/plugin-conventional-semantic-release/lib/types.ts similarity index 80% rename from packages/pvm-plugin-conventional-semantic-release/lib/types.ts rename to packages/plugin-conventional-semantic-release/lib/types.ts index b3e8d05cf..03e4477c2 100644 --- a/packages/pvm-plugin-conventional-semantic-release/lib/types.ts +++ b/packages/plugin-conventional-semantic-release/lib/types.ts @@ -1,4 +1,4 @@ -import type { PvmReleaseType } from '@pvm/types' +import type { PvmReleaseType } from '@pvm/pvm' export type Options = { releaseRules?: Array<{ diff --git a/packages/pvm-plugin-conventional-semantic-release/package.json b/packages/plugin-conventional-semantic-release/package.json similarity index 72% rename from packages/pvm-plugin-conventional-semantic-release/package.json rename to packages/plugin-conventional-semantic-release/package.json index 904ed806d..0b6be004c 100644 --- a/packages/pvm-plugin-conventional-semantic-release/package.json +++ b/packages/plugin-conventional-semantic-release/package.json @@ -3,12 +3,11 @@ "version": "0.0.0-stub", "main": "lib/index.js", "dependencies": { - "@pvm/core": "0.0.0-stub", - "@pvm/types": "0.0.0-stub", "@semantic-release/commit-analyzer": "^8.0.1", "conventional-commits-parser": "^3.2.1" }, "peerDependencies": { - "semantic-release": ">=16.0.0" + "semantic-release": ">=16.0.0", + "@pvm/pvm": "^0.0.0-stub" } } diff --git a/packages/pvm-core/.npmignore b/packages/plugin-github/.npmignore similarity index 80% rename from packages/pvm-core/.npmignore rename to packages/plugin-github/.npmignore index e13e0d218..6a57518a1 100644 --- a/packages/pvm-core/.npmignore +++ b/packages/plugin-github/.npmignore @@ -1,4 +1,5 @@ *.ts !*.d.ts +*.js.map __tests__ __snapshots__ diff --git a/src/plugins/github/README.md b/packages/plugin-github/README.md similarity index 100% rename from src/plugins/github/README.md rename to packages/plugin-github/README.md diff --git a/src/plugins/github/__tests__/index.spec.ts b/packages/plugin-github/__tests__/github.spec.ts similarity index 97% rename from src/plugins/github/__tests__/index.spec.ts rename to packages/plugin-github/__tests__/github.spec.ts index 881072181..6a8333354 100644 --- a/src/plugins/github/__tests__/index.spec.ts +++ b/packages/plugin-github/__tests__/github.spec.ts @@ -1,6 +1,6 @@ import { GithubPlatform } from '../platform' -import initRepo from '../../../../test/initRepo' -import { env } from '@pvm/core/lib/env' +import initRepo from '../../../test/initRepo' +import { env, GLOBAL_FLAGS_TOKEN, HOST_API_TOKEN } from '@pvm/pvm' import { randomUUID } from 'crypto' import { Octokit } from 'octokit' @@ -18,10 +18,12 @@ const githubClient = new Octokit({ (env.PVM_GITHUB_TEST_REPO_TOKEN ? describe : describe.skip)('pvm-github', () => { beforeAll(() => { + // eslint-disable-next-line pvm/no-process-env process.env.GITHUB_TOKEN = process.env.PVM_GITHUB_TEST_REPO_TOKEN }) afterAll(() => { + // eslint-disable-next-line pvm/no-process-env process.env.GITHUB_TOKEN = undefined }) @@ -311,6 +313,9 @@ async function prepareRepository() { auth_strategy: 'authToken', }, }, + hostApi: repo.di.get(HOST_API_TOKEN), + globalFlags: repo.di.get(GLOBAL_FLAGS_TOKEN), + cwd: repo.dir, }) const headCommit = (await repo.execScript('git rev-parse HEAD')).stdout.trim() @@ -344,7 +349,7 @@ async function createRepo(initRepoOpts: any): Promise<{ owner: string, repoName: return { owner: GITHUB_TEST_OWNER, repoName, repoGitPath: `git@github.com:pvm-test-bot/${repoName}.git`, repo } } -async function createWorkflowedPullRequest(repoName: string, repo: any, push) { +async function createWorkflowedPullRequest(repoName: string, repo: any, push: () => Promise) { await repo.execScript('git checkout -b test-branch') await repo.writeFile('.github/workflows/actions.yml', ` name: Test @@ -425,6 +430,6 @@ async function retryWithTimeout(what: string, fn: () => Promise, timeLimit return result } -function sleep(ms): Promise { +function sleep(ms: number): Promise { return new Promise((resolve) => setTimeout(resolve, ms)) } diff --git a/packages/plugin-github/index.ts b/packages/plugin-github/index.ts new file mode 100644 index 000000000..19aeb16fc --- /dev/null +++ b/packages/plugin-github/index.ts @@ -0,0 +1,29 @@ +import { + CONFIG_TOKEN, + CWD_TOKEN, + declarePlugin, + GLOBAL_FLAGS_TOKEN, + HOST_API_TOKEN, + provide, + RAW_PLATFORM_TOKEN, +} from '@pvm/pvm' +import { GithubPlatform } from './platform' + +export default declarePlugin({ + factory: function() { + return { + providers: [ + provide({ + provide: RAW_PLATFORM_TOKEN, + useClass: GithubPlatform, + deps: { + config: CONFIG_TOKEN, + cwd: CWD_TOKEN, + hostApi: HOST_API_TOKEN, + globalFlags: GLOBAL_FLAGS_TOKEN, + }, + }), + ], + } + }, +}) diff --git a/packages/plugin-github/logger.ts b/packages/plugin-github/logger.ts new file mode 100644 index 000000000..ecc9d41f5 --- /dev/null +++ b/packages/plugin-github/logger.ts @@ -0,0 +1,3 @@ +import { loggerFor } from '@pvm/pvm' + +export const log = loggerFor('pvm:github') diff --git a/src/plugins/github/package.json b/packages/plugin-github/package.json similarity index 66% rename from src/plugins/github/package.json rename to packages/plugin-github/package.json index 2acf0cfef..671d24944 100644 --- a/src/plugins/github/package.json +++ b/packages/plugin-github/package.json @@ -3,16 +3,14 @@ "version": "0.0.0-stub", "exports": "./index.js", "dependencies": { - "@pvm/core": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", - "@pvm/types": "0.0.0-stub", - "@pvm/di": "0.0.0-stub", "@octokit/openapi-types": "^11.2.0", "@octokit/auth-app": "^3.6.1", "@octokit/auth-action": "^1.3.3", "parse-md": "^2.0.4", "octokit": "^1.7.0", "hosted-git-info": "^3.0.2" + }, + "peerDependencies": { + "@pvm/pvm": "^0.0.0-stub" } } diff --git a/src/plugins/github/platform.ts b/packages/plugin-github/platform.ts similarity index 87% rename from src/plugins/github/platform.ts rename to packages/plugin-github/platform.ts index 999889f09..fe9291fb2 100644 --- a/src/plugins/github/platform.ts +++ b/packages/plugin-github/platform.ts @@ -1,27 +1,34 @@ +// @ts-ignore import parseMd from 'parse-md' import { Octokit } from 'octokit' import { createAppAuth } from '@octokit/auth-app' import { createActionAuth } from '@octokit/auth-action' +import { + wdShell, + PlatformResult, + env, + PlatformInterface, + releaseTagFilter, + getCurrentBranchIgnoreEnv, + getHostUrl, + gracefullyTruncateText, +} from '@pvm/pvm' import type { GetReleaseResult, VcsRelease, CreateReleasePayload, PlatformReleaseTag, AlterReleaseResult, MetaComment, Config, -} from '@pvm/types' -import { PlatformInterface } from '@pvm/vcs/lib/platform-interface' -import type { IssueComment, PullRequest } from './types' -import { PlatformResult } from '@pvm/types' + CommitResult, + HostApi, +} from '@pvm/pvm' +import type { IssueComment, PullRequest } from './types' import hostedGitInfo from 'hosted-git-info' -import { env } from '@pvm/core/lib/env' -import { releaseTagFilter } from '@pvm/core/lib/tag-meta' -import { getCurrentBranchIgnoreEnv, getHostUrl } from '@pvm/core/lib/git/commands' import { log } from './logger' -import { gracefullyTruncateText } from '@pvm/core/lib/utils/string' -import { wdShell } from '@pvm/core' +import type { GlobalFlags } from '@pvm/pvm/lib/cli/global-flags' export const AuthenticationStrategy = { 'authApp': createAppAuth, @@ -38,22 +45,24 @@ function getSuccessRequestLogTitle(options: any): string { return `${options.method} ${options.url} ${JSON.stringify(printableData)}` } -function getFailedRequestLogTitle(error): string { - let loggedBody +function getFailedRequestLogTitle(error: any): string { + let loggedBody: Record = {} if (error.request.body) { loggedBody = JSON.parse(error.request.body) Object.keys(loggedBody).forEach(k => { loggedBody[k] = gracefullyTruncateText(loggedBody[k].toString(), MAX_LOG_PROP_LENGTH, '...') }) } - return `${error.response.status}: ${error.request.method} ${error.request.url} ${loggedBody ? JSON.stringify(loggedBody, null, 2) : ''}` + return `${error.response.status}: ${error.request.method} ${error.request.url} ${Object.keys(loggedBody).length ? JSON.stringify(loggedBody, null, 2) : ''}` } -export class GithubPlatform extends PlatformInterface { +export class GithubPlatform extends PlatformInterface { public currentMr: PullRequest | null = null; private githubClient: Octokit private githubRepoPath: { repo: string, owner: string } private config: Config; + protected cwd: string + protected hostApi: HostApi static getAuthStrategy(config: Config): typeof createAppAuth | typeof createActionAuth | undefined { let resultStrategy @@ -99,9 +108,11 @@ export class GithubPlatform extends PlatformInterface { return resultRepo } - constructor({ config }: { config: Config }) { - super() + constructor({ config, cwd, hostApi, globalFlags }: { config: Config, cwd: string, hostApi: HostApi, globalFlags: GlobalFlags }) { + super({ name: GithubPlatform.name, globalFlags }) this.config = config + this.cwd = cwd + this.hostApi = hostApi this.githubClient = new Octokit({ authStrategy: GithubPlatform.getAuthStrategy(config), auth: env.GITHUB_TOKEN, @@ -137,7 +148,7 @@ export class GithubPlatform extends PlatformInterface { name: name ?? tag_name, description: body ?? '', }] - } catch (e) { + } catch (e: any) { if (e.statusCode === 404) { return [PlatformResult.NO_SUCH_TAG, null] } @@ -280,8 +291,8 @@ export class GithubPlatform extends PlatformInterface { this.logReleaseTag(tagName) return res - } catch (e) { - if (e.response.data.errors.find(e => e.code === 'already_exists')) { + } catch (e: any) { + if (e.response.data.errors.find((e: any) => e.code === 'already_exists')) { return this.editRelease(tagName, data) } @@ -310,10 +321,10 @@ export class GithubPlatform extends PlatformInterface { continue } const { metadata, content } = parseResult - - if (metadata && metadata.kind === kind) { + const typedMetadata = metadata as Record | undefined + if (typedMetadata?.kind === kind) { return { - metadata, + metadata: typedMetadata, content, note: { ...note, @@ -404,4 +415,32 @@ export class GithubPlatform extends PlatformInterface { private logReleaseTag(tagName: string): void { log.info(`release tag link: ${getHostUrl(this.config.cwd)}/${this.githubRepoPath.owner}/${this.githubRepoPath.repo}/tags/${tagName}`) } + + updateFile(): void { + throw new Error('Not supported') + } + + commit(): Promise { + throw new Error('Not supported') + } + + deleteFile(): void { + throw new Error('Not supported') + } + + rollbackCommit(): Promise { + throw new Error('Not supported') + } + + addFiles(): void { + throw new Error('Not supported') + } + + appendFile(): void { + throw new Error('Not supported') + } + + beginCommit(): never { + throw new Error('Not supported') + } } diff --git a/src/plugins/github/types.ts b/packages/plugin-github/types.ts similarity index 100% rename from src/plugins/github/types.ts rename to packages/plugin-github/types.ts diff --git a/packages/plugin-gitlab/.npmignore b/packages/plugin-gitlab/.npmignore new file mode 100644 index 000000000..6a57518a1 --- /dev/null +++ b/packages/plugin-gitlab/.npmignore @@ -0,0 +1,5 @@ +*.ts +!*.d.ts +*.js.map +__tests__ +__snapshots__ diff --git a/packages/pvm-gitlab/README.md b/packages/plugin-gitlab/README.md similarity index 100% rename from packages/pvm-gitlab/README.md rename to packages/plugin-gitlab/README.md diff --git a/packages/pvm-gitlab/__tests__/platform.spec.ts b/packages/plugin-gitlab/__tests__/platform.spec.ts similarity index 100% rename from packages/pvm-gitlab/__tests__/platform.spec.ts rename to packages/plugin-gitlab/__tests__/platform.spec.ts diff --git a/packages/plugin-gitlab/index.ts b/packages/plugin-gitlab/index.ts new file mode 100644 index 000000000..d5e3011a6 --- /dev/null +++ b/packages/plugin-gitlab/index.ts @@ -0,0 +1,32 @@ +import { + declarePlugin, + provide, + DI_TOKEN, + RAW_PLATFORM_TOKEN, + GLOBAL_FLAGS_TOKEN, + CWD_TOKEN, + HOST_API_TOKEN, CONFIG_TOKEN, +} from '@pvm/pvm' +import { GitlabPlatform } from './platform' + +export * from './tokens' + +export default declarePlugin({ + factory: function() { + return { + providers: [ + provide({ + provide: RAW_PLATFORM_TOKEN, + useClass: GitlabPlatform, + deps: { + di: DI_TOKEN, + cwd: CWD_TOKEN, + hostApi: HOST_API_TOKEN, + globalFlags: GLOBAL_FLAGS_TOKEN, + config: CONFIG_TOKEN, + }, + }), + ], + } + }, +}) diff --git a/packages/pvm-gitlab/lib/api/api-helpers.ts b/packages/plugin-gitlab/lib/api/api-helpers.ts similarity index 100% rename from packages/pvm-gitlab/lib/api/api-helpers.ts rename to packages/plugin-gitlab/lib/api/api-helpers.ts diff --git a/packages/pvm-gitlab/lib/api/index.ts b/packages/plugin-gitlab/lib/api/index.ts similarity index 69% rename from packages/pvm-gitlab/lib/api/index.ts rename to packages/plugin-gitlab/lib/api/index.ts index 753ace281..1167046a7 100644 --- a/packages/pvm-gitlab/lib/api/index.ts +++ b/packages/plugin-gitlab/lib/api/index.ts @@ -1,24 +1,22 @@ -import type { HttpReqOptions, HttpResponseSuccess } from '@pvm/core/lib/httpreq' -import httpreq, { requestWithRetries } from '@pvm/core/lib/httpreq' -import shell from '@pvm/core/lib/shell' -import { getConfig } from '@pvm/core/lib/config' +import type { Container, HttpReqOptions, HttpResponseSuccess } from '@pvm/pvm' +import { requestWithRetries, httpreq, shell, env, CONFIG_TOKEN } from '@pvm/pvm' import { getApiUrl } from '../remote-url' -import { getHostApi } from '@pvm/core/lib/plugins/index' -import { env } from '@pvm/core/lib/env' +import { GITLAB_AUTH_FUNCTION_TOKEN } from '../../tokens' const retryTimeouts = [ 5000, 15000, 60000, 200000, 300000, ] -async function glapi(uri: string, opts: HttpReqOptions = {}): Promise> { +async function glapi(di: Container, uri: string, opts: HttpReqOptions = {}): Promise> { const { GL_TOKEN, GITLAB_TOKEN, GITLAB_AUTH_COMMAND, } = env - const hostApi = await getHostApi() + const gitlabAuthFn = di.get({ token: GITLAB_AUTH_FUNCTION_TOKEN, optional: true }) + const config = di.get(CONFIG_TOKEN) let privateToken = GL_TOKEN || GITLAB_TOKEN if (!privateToken) { @@ -27,8 +25,8 @@ async function glapi(uri: string, opts: HttpReqOptions = {}): Promise(uri: string, opts: HttpReqOptions = {}): Promise = {} diff --git a/packages/plugin-gitlab/lib/api/labels/create.ts b/packages/plugin-gitlab/lib/api/labels/create.ts new file mode 100644 index 000000000..e1d3ea7b4 --- /dev/null +++ b/packages/plugin-gitlab/lib/api/labels/create.ts @@ -0,0 +1,13 @@ +import type { Container } from '@pvm/pvm' +import glapi from '../index' + +// https://docs.gitlab.com/ee/api/labels.html#create-a-new-label + +function createLabel(di: Container, projectId: string, label: Record) { + return glapi(di, `/projects/${encodeURIComponent(projectId)}/labels`, { + method: 'POST', + body: label, + }) +} + +export default createLabel diff --git a/packages/plugin-gitlab/lib/api/labels/labels.ts b/packages/plugin-gitlab/lib/api/labels/labels.ts new file mode 100644 index 000000000..8615e10d5 --- /dev/null +++ b/packages/plugin-gitlab/lib/api/labels/labels.ts @@ -0,0 +1,9 @@ +import { projectPagesGen } from '../pages-gen' +import type { Container } from '@pvm/pvm' + +// https://docs.gitlab.com/ee/api/labels.html#list-labels +function labels(di: Container, projectId: string, queryArgs = {}) { + return projectPagesGen(di, projectId, `/labels`, queryArgs) +} + +export default labels diff --git a/packages/pvm-gitlab/lib/api/mr/approvals.ts b/packages/plugin-gitlab/lib/api/mr/approvals.ts similarity index 64% rename from packages/pvm-gitlab/lib/api/mr/approvals.ts rename to packages/plugin-gitlab/lib/api/mr/approvals.ts index e4ec9e875..e243352f5 100644 --- a/packages/pvm-gitlab/lib/api/mr/approvals.ts +++ b/packages/plugin-gitlab/lib/api/mr/approvals.ts @@ -2,9 +2,9 @@ import glapi from '../index' import type { UriSlug } from '../api-helpers' import { encodeSlug } from '../api-helpers' import type { Group, PublicPerson } from '../../../types/api/people' -import type { HttpResponseSuccess } from '@pvm/core/lib/httpreq' +import type { HttpResponseSuccess, Container } from '@pvm/pvm' import pMap from 'p-map' -import { error } from '@pvm/core/lib/logger' +import { logger } from '@pvm/pvm' interface UserWrapper { user: PublicPerson, @@ -23,8 +23,8 @@ export interface ProjectApprovals { merge_requests_author_approval: boolean, } -async function projectApprovals(projectId: UriSlug): Promise { - const { json } = await glapi(`/projects/${encodeSlug(projectId)}/approvals`) +async function projectApprovals(di: Container, projectId: UriSlug): Promise { + const { json } = await glapi(di, `/projects/${encodeSlug(projectId)}/approvals`) return json } @@ -44,16 +44,16 @@ export interface MergeRequestApprovals { approver_groups: GroupWrapper[], } -async function mergeRequestApprovals(projectId: UriSlug, mrIid: number): Promise { - const { json } = await glapi(`/projects/${encodeSlug(projectId)}/merge_requests/${mrIid}/approvals`) +async function mergeRequestApprovals(di: Container, projectId: UriSlug, mrIid: number): Promise { + const { json } = await glapi(di, `/projects/${encodeSlug(projectId)}/merge_requests/${mrIid}/approvals`) return json } // feature not stable, see https://gitlab.com/gitlab-org/gitlab-ee/issues/12055 // @TODO: Deprecated in 12.0 in favor of Approval Rules API. -async function setApprovalsRequired(projectId: UriSlug, iid: number, count: number): Promise> { +async function setApprovalsRequired(di: Container, projectId: UriSlug, iid: number, count: number): Promise> { // https://docs.gitlab.com/ee/api/merge_request_approvals.html#change-approval-configuration - return glapi(`/projects/${encodeSlug(projectId)}/merge_requests/${iid}/approvals`, { + return glapi(di, `/projects/${encodeSlug(projectId)}/merge_requests/${iid}/approvals`, { method: 'POST', body: { approvals_required: count, @@ -61,15 +61,15 @@ async function setApprovalsRequired(projectId: UriSlug, iid: number, count: numb }) } -async function setApprovers(projectId: UriSlug, iid: number, approvers: string[]): Promise { +async function setApprovers(di: Container, projectId: UriSlug, iid: number, approvers: string[]): Promise { let approver_ids = await pMap(approvers, async username => { - const { json: list } = await glapi(`/users?username=${encodeURIComponent(username)}`) + const { json: list } = await glapi(di, `/users?username=${encodeURIComponent(username)}`) if (list.length === 1) { return list[0].id } else if (list.length === 0) { - error(`user ${username} not found`) + logger.error(`user ${username} not found`) } else { - error(`multiple users for ${username}`) + logger.error(`multiple users for ${username}`) } }, { concurrency: 3, @@ -81,7 +81,7 @@ async function setApprovers(projectId: UriSlug, iid: number, approvers: string[] // so we do request to do a empty approvers first // @TODO: This API endpoint has been deprecated. Please use Approval Rule API instead. Introduced in GitLab Starter 10.6. // https://docs.gitlab.com/ee/api/merge_request_approvals.html#change-allowed-approvers-for-merge-request - await glapi(`/projects/${encodeSlug(projectId)}/merge_requests/${iid}/approvers`, { + await glapi(di, `/projects/${encodeSlug(projectId)}/merge_requests/${iid}/approvers`, { method: 'PUT', body: { approver_ids: [], @@ -89,7 +89,7 @@ async function setApprovers(projectId: UriSlug, iid: number, approvers: string[] }, }) - return glapi(`/projects/${encodeSlug(projectId)}/merge_requests/${iid}/approvers`, { + return glapi(di, `/projects/${encodeSlug(projectId)}/merge_requests/${iid}/approvers`, { method: 'PUT', body: { approver_ids, @@ -103,7 +103,7 @@ function ownersWithoutDogs(owners: string[]): string[] { if (owner.startsWith('@')) { withoutDogs.push(owner.substr(1)) } else { - error(`assign approvers by emails not supported for gitlab! Email ${owner} will be ignored`) + logger.error(`assign approvers by emails not supported for gitlab! Email ${owner} will be ignored`) } return withoutDogs diff --git a/packages/plugin-gitlab/lib/api/mr/get.ts b/packages/plugin-gitlab/lib/api/mr/get.ts new file mode 100644 index 000000000..1ee4a4c02 --- /dev/null +++ b/packages/plugin-gitlab/lib/api/mr/get.ts @@ -0,0 +1,12 @@ +import glapi from '../index' +import type { UriSlug } from '../api-helpers' +import { encodeSlug } from '../api-helpers' +import type { MergeRequest } from './types' +import type { Container } from '@pvm/pvm' + +async function getMergeRequest(di: Container, projectId: UriSlug, mrIid: number): Promise { + const { json } = await glapi(di, `/projects/${encodeSlug(projectId)}/merge_requests/${mrIid}`) + return json +} + +export default getMergeRequest diff --git a/packages/plugin-gitlab/lib/api/mr/list.ts b/packages/plugin-gitlab/lib/api/mr/list.ts new file mode 100644 index 000000000..37f867dc0 --- /dev/null +++ b/packages/plugin-gitlab/lib/api/mr/list.ts @@ -0,0 +1,10 @@ +import type { Container } from '@pvm/pvm' +import type { QueryArgs } from '../pages-gen' +import { projectPagesGen } from '../pages-gen' +import type { MergeRequest } from './types' + +function list(di: Container, projectId: string, queryArgs: QueryArgs): AsyncIterableIterator { + return projectPagesGen(di, projectId, `/merge_requests`, queryArgs) +} + +export default list diff --git a/packages/plugin-gitlab/lib/api/mr/notes.ts b/packages/plugin-gitlab/lib/api/mr/notes.ts new file mode 100644 index 000000000..980c2f3f3 --- /dev/null +++ b/packages/plugin-gitlab/lib/api/mr/notes.ts @@ -0,0 +1,9 @@ +import { projectPagesGen } from '../pages-gen' +import type { Container } from '@pvm/pvm' + +// https://docs.gitlab.com/ee/api/notes.html#list-all-merge-request-notes +function getNotes(di: Container, projectId: string, mrIid: number, queryArgs = {}) { + return projectPagesGen(di, projectId, `/merge_requests/${mrIid}/notes`, queryArgs) +} + +export default getNotes diff --git a/packages/pvm-gitlab/lib/api/mr/types.ts b/packages/plugin-gitlab/lib/api/mr/types.ts similarity index 100% rename from packages/pvm-gitlab/lib/api/mr/types.ts rename to packages/plugin-gitlab/lib/api/mr/types.ts diff --git a/packages/plugin-gitlab/lib/api/mr/update.ts b/packages/plugin-gitlab/lib/api/mr/update.ts new file mode 100644 index 000000000..dd21fac36 --- /dev/null +++ b/packages/plugin-gitlab/lib/api/mr/update.ts @@ -0,0 +1,11 @@ +import glapi from '../index' +import type { Container } from '@pvm/pvm' + +function update(di: Container, projectId: string, mrIid: number, attrs = {}) { + return glapi(di, `/projects/${encodeURIComponent(projectId)}/merge_requests/${mrIid}`, { + method: 'PUT', + body: attrs, + }) +} + +export default update diff --git a/packages/pvm-gitlab/lib/api/pages-gen.ts b/packages/plugin-gitlab/lib/api/pages-gen.ts similarity index 69% rename from packages/pvm-gitlab/lib/api/pages-gen.ts rename to packages/plugin-gitlab/lib/api/pages-gen.ts index e7fa3382b..99216c2d7 100644 --- a/packages/pvm-gitlab/lib/api/pages-gen.ts +++ b/packages/plugin-gitlab/lib/api/pages-gen.ts @@ -1,9 +1,9 @@ import { URL } from 'url' import glapi from './index' -import type { HttpReqOptions, HttpResponseSuccess } from '@pvm/core/lib/httpreq' +import { pagingMeta } from '@pvm/pvm' +import type { HttpReqOptions, HttpResponseSuccess, Container } from '@pvm/pvm' import type { UriSlug } from './api-helpers' import { encodeSlug } from './api-helpers' -import { pagingMeta } from '@pvm/core/lib/vcs-meta' export interface QueryArgs { page?: number, @@ -11,7 +11,7 @@ export interface QueryArgs { } // https://docs.gitlab.com/ee/api/#pagination -async function * httpPagesGen( +async function * httpPagesGen(di: Container, href: string, queryArgs: QueryArgs = {}, fetchOpts: HttpReqOptions = {} ): AsyncIterableIterator>> { let page = queryArgs.page || 1 @@ -25,7 +25,7 @@ async function * httpPagesGen( do { url.searchParams.set('page', String(page)) - const response = await glapi>( + const response = await glapi>(di, `${url.pathname}${url.search}`, fetchOpts ) @@ -36,9 +36,9 @@ async function * httpPagesGen( } // https://docs.gitlab.com/ee/api/#pagination -async function * pagesGen(url, queryArgs: QueryArgs = {}, fetchOpts: HttpReqOptions = {}): AsyncIterableIterator { - for await (const response of httpPagesGen(url, queryArgs, fetchOpts)) { - const data = response.json +async function * pagesGen(di: Container, url: string, queryArgs: QueryArgs = {}, fetchOpts: HttpReqOptions = {}): AsyncIterableIterator { + for await (const response of httpPagesGen(di, url, queryArgs, fetchOpts)) { + const data = response.json as any if (data) { const metaTarget = Array.isArray(data) ? data[0] : data if (typeof metaTarget === 'object' && metaTarget) { @@ -52,10 +52,10 @@ async function * pagesGen(url, queryArgs: QueryArgs = {}, fetchOpts: Ht } } -async function * projectPagesGen( +async function * projectPagesGen(di: Container, projectId: UriSlug, url: string, queryArgs: QueryArgs = {}, fetchOpts: HttpReqOptions = {} ): AsyncIterableIterator { - yield * pagesGen(`/projects/${encodeSlug(projectId)}${url}`, queryArgs, fetchOpts) + yield * pagesGen(di, `/projects/${encodeSlug(projectId)}${url}`, queryArgs, fetchOpts) } export { diff --git a/packages/plugin-gitlab/lib/api/releases/by-releases/alter.ts b/packages/plugin-gitlab/lib/api/releases/by-releases/alter.ts new file mode 100644 index 000000000..87a781c56 --- /dev/null +++ b/packages/plugin-gitlab/lib/api/releases/by-releases/alter.ts @@ -0,0 +1,31 @@ +import glapi from '../../index' + +import type { AlterReleaseResult } from '../types' +import type { Container } from '@pvm/pvm' + +// https://docs.gitlab.com/ee/api/releases/index.html#create-a-release +async function createRelease(di: Container, projectId: string, data: Record): Promise { + const { json } = await glapi(di, `/projects/${encodeURIComponent(projectId)}/releases`, { + method: 'POST', + body: data, + }) + + return { + id: json.tag_name, + } +} + +// https://docs.gitlab.com/ee/api/releases/index.html#update-a-release +async function updateRelease(di: Container, projectId: string, data: Record): Promise { + const { json } = await glapi(di, `/projects/${encodeURIComponent(projectId)}/releases/${data.tag_name}`, { + method: 'POST', + body: data, + }) + + return { + id: json.tag_name, + } +} + +export { createRelease as create } +export { updateRelease as update } diff --git a/packages/plugin-gitlab/lib/api/releases/by-releases/list.ts b/packages/plugin-gitlab/lib/api/releases/by-releases/list.ts new file mode 100644 index 000000000..cedf835cb --- /dev/null +++ b/packages/plugin-gitlab/lib/api/releases/by-releases/list.ts @@ -0,0 +1,10 @@ +import type { Container } from '@pvm/pvm' +import type { QueryArgs } from '../../pages-gen' +import { projectPagesGen } from '../../pages-gen' + +// https://docs.gitlab.com/ee/api/releases/index.html#list-releases +function tags(di: Container, projectId: string, queryArgs: QueryArgs) { + return projectPagesGen(di, projectId, `/releases`, queryArgs) +} + +export default tags diff --git a/packages/pvm-gitlab/lib/api/releases/by-tags/alter.ts b/packages/plugin-gitlab/lib/api/releases/by-tags/alter.ts similarity index 58% rename from packages/pvm-gitlab/lib/api/releases/by-tags/alter.ts rename to packages/plugin-gitlab/lib/api/releases/by-tags/alter.ts index 0559d6f11..6e3fb323e 100644 --- a/packages/pvm-gitlab/lib/api/releases/by-tags/alter.ts +++ b/packages/plugin-gitlab/lib/api/releases/by-tags/alter.ts @@ -1,8 +1,9 @@ import glapi from '../../index' import type { AlterReleaseResult, EditReleasePayload, CreateReleasePayload } from '../types' +import type { Container } from '@pvm/pvm' -async function addTagAndRelease(projectId: string | number, ref: string, data: CreateReleasePayload): Promise { +async function addTagAndRelease(di: Container, projectId: string | number, ref: string, data: CreateReleasePayload): Promise { const payload: Record = { ref: ref, tag_name: data.tag_name, @@ -11,12 +12,12 @@ async function addTagAndRelease(projectId: string | number, ref: string, data: C payload.message = data.annotation } const encodedProjectId = encodeURIComponent(projectId) - await glapi(`/projects/${encodedProjectId}/repository/tags`, { + await glapi(di, `/projects/${encodedProjectId}/repository/tags`, { method: 'POST', body: payload, }) - await glapi(`/projects/${encodedProjectId}/releases`, { + await glapi(di, `/projects/${encodedProjectId}/releases`, { method: 'POST', body: { tag_name: data.tag_name, @@ -29,8 +30,8 @@ async function addTagAndRelease(projectId: string | number, ref: string, data: C } } -async function createRelease(projectId: string | number, data: EditReleasePayload): Promise { - await glapi(`/projects/${encodeURIComponent(projectId)}/releases`, { +async function createRelease(di: Container, projectId: string | number, data: EditReleasePayload): Promise { + await glapi(di, `/projects/${encodeURIComponent(projectId)}/releases`, { method: 'POST', body: { tag_name: data.tag_name, @@ -44,13 +45,13 @@ async function createRelease(projectId: string | number, data: EditReleasePayloa } // тег должен существовать, если тега нет – метод упадет -async function upsertRelease(projectId: string | number, data: EditReleasePayload): Promise { +async function upsertRelease(di: Container, projectId: string | number, data: EditReleasePayload): Promise { try { - await createRelease(projectId, data) - } catch (e) { + await createRelease(di, projectId, data) + } catch (e: any) { if (e.statusCode === 409) { // релиз уже есть, и нам нужно его отредактировать в этом случае - return await updateRelease(projectId, data) + return await updateRelease(di, projectId, data) } throw e } @@ -62,8 +63,8 @@ async function upsertRelease(projectId: string | number, data: EditReleasePayloa // we only can update description // https://docs.gitlab.com/ee/api/tags.html#update-a-release -async function updateRelease(projectId: string | number, data: EditReleasePayload): Promise { - await glapi(`/projects/${encodeURIComponent(projectId)}/releases`, { +async function updateRelease(di: Container, projectId: string | number, data: EditReleasePayload): Promise { + await glapi(di, `/projects/${encodeURIComponent(projectId)}/releases`, { method: 'PUT', body: { tag_name: data.tag_name, diff --git a/packages/plugin-gitlab/lib/api/releases/by-tags/list.ts b/packages/plugin-gitlab/lib/api/releases/by-tags/list.ts new file mode 100644 index 000000000..b1e9e3e5d --- /dev/null +++ b/packages/plugin-gitlab/lib/api/releases/by-tags/list.ts @@ -0,0 +1,17 @@ +import { releaseTags } from '../../tags/tags' +import reformat from './reformat' +import type { Container } from '@pvm/pvm' + +const hasReleaseDescription = (tag: { release?: { description?: any }}): boolean => { + return !!tag.release && !!tag.release.description +} + +async function * releases(di: Container, projectId: string) { + for await (const tag of releaseTags(di, projectId)) { + if (hasReleaseDescription(tag)) { + yield reformat(tag) + } + } +} + +export default releases diff --git a/packages/plugin-gitlab/lib/api/releases/by-tags/reformat.ts b/packages/plugin-gitlab/lib/api/releases/by-tags/reformat.ts new file mode 100644 index 000000000..f7f0e3d70 --- /dev/null +++ b/packages/plugin-gitlab/lib/api/releases/by-tags/reformat.ts @@ -0,0 +1,34 @@ +import type { VcsRelease } from '@pvm/pvm' + +function reformat(releaseTag: { + [key: string]: unknown, + id: string, + name: string, + release?: { + description: string, + }, + commit: { + id: string, + created_at: string, + }, +}): VcsRelease & { author: Record, assets: { + count: number, + sources: string[], + links: string[], + }, } { + return { + ...releaseTag, + name: releaseTag.name, + tag_name: releaseTag.name, + description: releaseTag.release ? releaseTag.release.description : '', + created_at: releaseTag.commit.created_at, + author: {}, + assets: { + count: 0, + sources: [], + links: [], + }, + } +} + +export default reformat diff --git a/packages/pvm-gitlab/lib/api/releases/index.ts b/packages/plugin-gitlab/lib/api/releases/index.ts similarity index 100% rename from packages/pvm-gitlab/lib/api/releases/index.ts rename to packages/plugin-gitlab/lib/api/releases/index.ts diff --git a/packages/pvm-gitlab/lib/api/releases/types.ts b/packages/plugin-gitlab/lib/api/releases/types.ts similarity index 100% rename from packages/pvm-gitlab/lib/api/releases/types.ts rename to packages/plugin-gitlab/lib/api/releases/types.ts diff --git a/packages/plugin-gitlab/lib/api/tags/create.ts b/packages/plugin-gitlab/lib/api/tags/create.ts new file mode 100644 index 000000000..878a99f14 --- /dev/null +++ b/packages/plugin-gitlab/lib/api/tags/create.ts @@ -0,0 +1,12 @@ +import glapi from '../index' +import type { Container } from '@pvm/pvm' + +// https://docs.gitlab.com/ee/api/tags.html#create-a-new-tag +function createTag(di: Container, projectId: string, data: Record) { + return glapi(di, `/projects/${encodeURIComponent(projectId)}/repository/tags`, { + method: 'POST', + body: data, + }) +} + +export default createTag diff --git a/packages/pvm-gitlab/lib/api/tags/get.ts b/packages/plugin-gitlab/lib/api/tags/get.ts similarity index 51% rename from packages/pvm-gitlab/lib/api/tags/get.ts rename to packages/plugin-gitlab/lib/api/tags/get.ts index 6359c3f93..d469b9008 100644 --- a/packages/pvm-gitlab/lib/api/tags/get.ts +++ b/packages/plugin-gitlab/lib/api/tags/get.ts @@ -1,5 +1,5 @@ import glapi from '../index' -import type { HttpResponseSuccess } from '@pvm/core/lib/httpreq' +import type { HttpResponseSuccess, Container } from '@pvm/pvm' export interface GitlabTagRelease { tag_name: string, @@ -14,8 +14,8 @@ export interface GitlabTagResult { } // https://docs.gitlab.com/ee/api/tags.html#get-a-single-repository-tag -async function getTag(projectId, tagName: string): Promise> { - return await glapi(`/projects/${encodeURIComponent(projectId)}/repository/tags/${encodeURIComponent(tagName)}`) +async function getTag(di: Container, projectId: string, tagName: string): Promise> { + return await glapi(di, `/projects/${encodeURIComponent(projectId)}/repository/tags/${encodeURIComponent(tagName)}`) } export default getTag diff --git a/packages/plugin-gitlab/lib/api/tags/tags.ts b/packages/plugin-gitlab/lib/api/tags/tags.ts new file mode 100644 index 000000000..d83f635e1 --- /dev/null +++ b/packages/plugin-gitlab/lib/api/tags/tags.ts @@ -0,0 +1,30 @@ +import type { QueryArgs } from '../pages-gen' +import { projectPagesGen } from '../pages-gen' +import { releaseTagPrefix, releaseTagFilter, CONFIG_TOKEN } from '@pvm/pvm' +import type { HttpReqOptions, Container } from '@pvm/pvm' + +// https://docs.gitlab.com/ee/api/tags.html#list-project-repository-tags +async function * tags(di: Container, projectId: string, queryArgs: QueryArgs = {}, fetchOpts: HttpReqOptions = {}) { + yield * projectPagesGen(di, projectId, `/repository/tags`, queryArgs, fetchOpts) +} + +async function * releaseTags(di: Container, projectId: string, fetchOpts: HttpReqOptions = {}) { + const config = di.get(CONFIG_TOKEN) + const tagPrefix = releaseTagPrefix(config) + // @TODO: isReleaseTag логику надо вынести выше, чтобы работало на всех типах vcs + const isReleaseTag = releaseTagFilter(config) + + const queryArgs = { + search: tagPrefix, + } + for await (const tag of tags(di, projectId, queryArgs, fetchOpts)) { + if (isReleaseTag(tag.name)) { + yield tag + } + } +} + +export default tags +export { + releaseTags, +} diff --git a/packages/pvm-gitlab/lib/api/upload.ts b/packages/plugin-gitlab/lib/api/upload.ts similarity index 73% rename from packages/pvm-gitlab/lib/api/upload.ts rename to packages/plugin-gitlab/lib/api/upload.ts index 07ea05296..b83f97d51 100644 --- a/packages/pvm-gitlab/lib/api/upload.ts +++ b/packages/plugin-gitlab/lib/api/upload.ts @@ -1,6 +1,6 @@ -import type { HttpReqOptions } from '@pvm/core/lib/httpreq' +import type { HttpReqOptions, Container } from '@pvm/pvm' import glapi from './index' -import { debug } from '@pvm/core/lib/logger' +import { logger } from '@pvm/pvm' function uploadOpts(data: Buffer, filename: string): HttpReqOptions { const crlf = '\r\n' @@ -38,10 +38,10 @@ export interface UploadResult { } // https://docs.gitlab.com/ee/api/projects.html#upload-a-file -async function uploadFile(projectId: string | number, data: Buffer, filename: string): Promise { +async function uploadFile(di: Container, projectId: string | number, data: Buffer, filename: string): Promise { const opts = uploadOpts(data, filename) - const { json } = await glapi(`/projects/${toSlug(projectId)}/uploads`, opts) - debug('upload file result:\n', JSON.stringify(json, null, 2)) + const { json } = await glapi(di, `/projects/${toSlug(projectId)}/uploads`, opts) + logger.debug('upload file result:\n', JSON.stringify(json, null, 2)) return json } diff --git a/packages/pvm-gitlab/lib/env.ts b/packages/plugin-gitlab/lib/env.ts similarity index 86% rename from packages/pvm-gitlab/lib/env.ts rename to packages/plugin-gitlab/lib/env.ts index 9a1fc6f56..222e509b4 100644 --- a/packages/pvm-gitlab/lib/env.ts +++ b/packages/plugin-gitlab/lib/env.ts @@ -1,8 +1,7 @@ import parsePath from 'parse-path' -import { cwdShell, shell } from '@pvm/core/lib/shell' -import { getCurrentBranchIgnoreEnv } from '@pvm/core/lib/git/commands' -import type { Config } from '@pvm/core/lib/config' -import { env } from '@pvm/core/lib/env' +import { cwdShell, shell, getCurrentBranchIgnoreEnv, env } from '@pvm/pvm' + +import type { Config } from '@pvm/pvm' function resolveProjectId(cwd = process.cwd()): string { if (env.CI_PROJECT_ID) { diff --git a/packages/pvm-gitlab/lib/hal/mark-pr.ts b/packages/plugin-gitlab/lib/hal/mark-pr.ts similarity index 57% rename from packages/pvm-gitlab/lib/hal/mark-pr.ts rename to packages/plugin-gitlab/lib/hal/mark-pr.ts index 221b599b6..eda5aeecd 100644 --- a/packages/pvm-gitlab/lib/hal/mark-pr.ts +++ b/packages/plugin-gitlab/lib/hal/mark-pr.ts @@ -1,5 +1,6 @@ +// @ts-ignore import parseMd from 'parse-md' -import { debug } from '@pvm/core/lib/logger' +import { logger, getNoteBody } from '@pvm/pvm' import crypto from 'crypto' import path from 'path' @@ -9,12 +10,10 @@ import { uploadFile } from '../api/upload' import gitlabEnv from '../env' import type { MrNote } from '../../types/api/notes' -import type { HttpResponseSuccess } from '@pvm/core/lib/httpreq' -import type { MetaComment } from '@pvm/vcs/types/index' -import { getNoteBody } from '@pvm/vcs/lib' +import type { HttpResponseSuccess, MetaComment, Container } from '@pvm/pvm' -async function findNote(iid: number, kind: string): Promise | void> { - const notesIterator = getNotes(gitlabEnv.projectId, iid) +async function findNote(di: Container, iid: number, kind: string): Promise | void> { + const notesIterator = getNotes(di, gitlabEnv.projectId, iid) for await (const note of notesIterator) { let parseResult @@ -27,9 +26,10 @@ async function findNote(iid: number, kind: string): Promise } const { metadata, content } = parseResult - if (metadata && metadata.kind === kind) { + const typedMetadata = metadata as Record | undefined + if (typedMetadata?.kind === kind) { return { - metadata, + metadata: typedMetadata, content, note, } @@ -37,20 +37,20 @@ async function findNote(iid: number, kind: string): Promise } } -async function syncText(iid: number, kind: string, text: string): Promise { - const existsNote = await findNote(iid, kind) +async function syncText(di: Container, iid: number, kind: string, text: string): Promise { + const existsNote = await findNote(di, iid, kind) const noteBody = getNoteBody([['kind', kind], ['ref', gitlabEnv.commitSha]], text) if (existsNote) { - return glapi(`/projects/${gitlabEnv.projectSlug}/merge_requests/${iid}/notes/${existsNote.note.id}`, { + return glapi(di, `/projects/${gitlabEnv.projectSlug}/merge_requests/${iid}/notes/${existsNote.note.id}`, { method: 'PUT', body: { body: noteBody, }, }) } else { - return glapi(`/projects/${gitlabEnv.projectSlug}/merge_requests/${iid}/notes`, { + return glapi(di, `/projects/${gitlabEnv.projectSlug}/merge_requests/${iid}/notes`, { method: 'POST', body: { body: noteBody, @@ -63,8 +63,8 @@ export interface SyncAttachmentOpts { filename?: string, } -async function syncAttachment(iid: number, kind: string, attachment: Buffer, opts: SyncAttachmentOpts = {}): Promise { - const existsNote: MetaComment | void = await findNote(iid, kind) +async function syncAttachment(di: Container, iid: number, kind: string, attachment: Buffer, opts: SyncAttachmentOpts = {}): Promise { + const existsNote: MetaComment | void = await findNote(di, iid, kind) const { filename = 'attachment.file' } = opts let markdown @@ -78,19 +78,19 @@ async function syncAttachment(iid: number, kind: string, attachment: Buffer, opt const [algo, attachDigest] = metadata.integrity.split('-') const digest = crypto.createHash(algo).update(attachment).digest('hex') doUpload = attachDigest !== digest - debug('integrity match:', !doUpload) + logger.debug('integrity match:', !doUpload) } } catch (e) { - debug(e) + logger.debug(e) } if (doUpload) { - markdown = (await uploadFile(gitlabEnv.projectId, attachment, path.basename(filename))).markdown + markdown = (await uploadFile(di, gitlabEnv.projectId, attachment, path.basename(filename))).markdown } else { markdown = content } } else { - markdown = (await uploadFile(gitlabEnv.projectId, attachment, path.basename(filename))).markdown + markdown = (await uploadFile(di, gitlabEnv.projectId, attachment, path.basename(filename))).markdown } const digest = crypto.createHash('sha1').update(attachment).digest('hex') @@ -98,14 +98,14 @@ async function syncAttachment(iid: number, kind: string, attachment: Buffer, opt const noteBody = getNoteBody([['kind', kind], ['ref', gitlabEnv.commitSha], ['integrity', `sha1-${digest}`]], markdown) if (existsNote) { - return glapi(`/projects/${gitlabEnv.projectSlug}/merge_requests/${iid}/notes/${existsNote.note.id}`, { + return glapi(di, `/projects/${gitlabEnv.projectSlug}/merge_requests/${iid}/notes/${existsNote.note.id}`, { method: 'PUT', body: { body: noteBody, }, }) } else { - return glapi(`/projects/${gitlabEnv.projectSlug}/merge_requests/${iid}/notes`, { + return glapi(di, `/projects/${gitlabEnv.projectSlug}/merge_requests/${iid}/notes`, { method: 'POST', body: { body: noteBody, diff --git a/packages/pvm-gitlab/lib/hal/members.ts b/packages/plugin-gitlab/lib/hal/members.ts similarity index 57% rename from packages/pvm-gitlab/lib/hal/members.ts rename to packages/plugin-gitlab/lib/hal/members.ts index 345461350..361f1eccd 100644 --- a/packages/pvm-gitlab/lib/hal/members.ts +++ b/packages/plugin-gitlab/lib/hal/members.ts @@ -1,28 +1,29 @@ +import type { Container } from '@pvm/pvm' import type { PublicMember } from '../../types/api/people' import type { UriSlug } from '../api/api-helpers' import { projectPagesGen } from '../api/pages-gen' import gitalbEnv from '../env' -async function * getProjectMembers(projectId: UriSlug = gitalbEnv.projectId): AsyncIterableIterator { +async function * getProjectMembers(di: Container, projectId: UriSlug = gitalbEnv.projectId): AsyncIterableIterator { const seenUsers = new Set() // итерируем сначала по прямым членам проекта, т.к. там данные более точные в контексте самого проекта - for await (const user of projectPagesGen(projectId, `/members`)) { + for await (const user of projectPagesGen(di, projectId, `/members`)) { if (user.state === 'active') { yield user seenUsers.add(user.username) } } - for await (const user of projectPagesGen(projectId, `/members/all`)) { + for await (const user of projectPagesGen(di, projectId, `/members/all`)) { if (user.state === 'active' && !seenUsers.has(user.username)) { yield user } } } -async function * getMaintainers(projectId: UriSlug = gitalbEnv.projectId): AsyncIterableIterator { - for await (const user of getProjectMembers(projectId)) { +async function * getMaintainers(di: Container, projectId: UriSlug = gitalbEnv.projectId): AsyncIterableIterator { + for await (const user of getProjectMembers(di, projectId)) { if (user.access_level === 40) { yield user } diff --git a/packages/pvm-gitlab/lib/hal/merge-request.ts b/packages/plugin-gitlab/lib/hal/merge-request.ts similarity index 54% rename from packages/pvm-gitlab/lib/hal/merge-request.ts rename to packages/plugin-gitlab/lib/hal/merge-request.ts index 10f777b1b..34f056477 100644 --- a/packages/pvm-gitlab/lib/hal/merge-request.ts +++ b/packages/plugin-gitlab/lib/hal/merge-request.ts @@ -1,12 +1,13 @@ import gitlabEnv from '../env' import glapi from '../api' import type { MergeRequest } from '../api/mr/types' +import type { Container } from '@pvm/pvm' -async function findOpenSingleMr(branchName: string | undefined = gitlabEnv.getBranchName()): Promise { +async function findOpenSingleMr(di: Container, branchName: string | undefined = gitlabEnv.getBranchName()): Promise { if (!branchName) { throw new Error(`Couldn't find open single merge request without branch name`) } - const { json: mrs } = await glapi>(`/projects/${gitlabEnv.projectSlug}/merge_requests?source_branch=${branchName}&state=opened&per_page=2`) + const { json: mrs } = await glapi>(di, `/projects/${gitlabEnv.projectSlug}/merge_requests?source_branch=${branchName}&state=opened&per_page=2`) if (!mrs || mrs.length === 0) { throw new Error(`There is no merge request for branch ${branchName}`) @@ -16,11 +17,11 @@ async function findOpenSingleMr(branchName: string | undefined = gitlabEnv.getBr throw new Error(`There are ${mrs.length} merge requests opened for branch ${branchName}. Expected one.`) } -async function findMergedLastMr(branchName: string | undefined = gitlabEnv.getBranchName()): Promise { +async function findMergedLastMr(di: Container, branchName: string | undefined = gitlabEnv.getBranchName()): Promise { if (!branchName) { throw new Error(`Couldn't find open single merge request without branch name`) } - const { json: mrs } = await glapi>(`/projects/${gitlabEnv.projectSlug}/merge_requests?source_branch=${branchName}&state=merged&per_page=1&order_by=updated_at`) + const { json: mrs } = await glapi>(di, `/projects/${gitlabEnv.projectSlug}/merge_requests?source_branch=${branchName}&state=merged&per_page=1&order_by=updated_at`) if (!mrs || mrs.length === 0) { throw new Error(`There is no merged merge request for branch ${branchName}`) diff --git a/packages/pvm-gitlab/lib/public-api.ts b/packages/plugin-gitlab/lib/public-api.ts similarity index 100% rename from packages/pvm-gitlab/lib/public-api.ts rename to packages/plugin-gitlab/lib/public-api.ts diff --git a/packages/pvm-gitlab/lib/remote-url.ts b/packages/plugin-gitlab/lib/remote-url.ts similarity index 56% rename from packages/pvm-gitlab/lib/remote-url.ts rename to packages/plugin-gitlab/lib/remote-url.ts index eda53c4ba..5b9396bb9 100644 --- a/packages/pvm-gitlab/lib/remote-url.ts +++ b/packages/plugin-gitlab/lib/remote-url.ts @@ -1,6 +1,5 @@ -import type { Config } from '@pvm/core/lib/config' -import { getHostUrl } from '@pvm/core/lib/git/commands' -import { env } from '@pvm/core/lib/env' +import type { Config } from '@pvm/pvm' +import { getHostUrl, env } from '@pvm/pvm' export function getApiUrl(config: Config): string { if (config.gitlab.api_url) { @@ -26,12 +25,3 @@ export function getGitlabHostUrl(config: Config): string { return config.gitlab.default_url } - -if (require.main === module) { - // eslint-disable-next-line @typescript-eslint/no-var-requires - const { getConfig } = require('@pvm/core/lib/config') - - getConfig().then(config => { - console.log(getGitlabHostUrl(config)) - }) -} diff --git a/packages/pvm-gitlab/package.json b/packages/plugin-gitlab/package.json similarity index 55% rename from packages/pvm-gitlab/package.json rename to packages/plugin-gitlab/package.json index 7a77c3e8a..3fbf0af50 100644 --- a/packages/pvm-gitlab/package.json +++ b/packages/plugin-gitlab/package.json @@ -1,20 +1,18 @@ { - "name": "@pvm/gitlab", + "name": "@pvm/plugin-gitlab", "version": "0.0.0-stub", "description": "GitLab additions for pvm", - "main": "lib/public-api.js", "repository": "git@github.com:Tinkoff/pvm.git", "author": "Andrey Rublev ", "license": "Apache-2.0", "dependencies": { - "@pvm/core": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", "p-map": "^4.0.0", "parse-md": "^2.0.4", - "parse-path": "^4.0.1", + "parse-path": "^4.0.4", "@iarna/toml": "^2.2.5", - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "marked": "^2.1.3" + "marked": "^4.2.3" + }, + "peerDependencies": { + "@pvm/pvm": "^0.0.0-stub" } } diff --git a/packages/pvm-gitlab/platform.ts b/packages/plugin-gitlab/platform.ts similarity index 73% rename from packages/pvm-gitlab/platform.ts rename to packages/plugin-gitlab/platform.ts index e02031a0b..d7a3ba4b6 100644 --- a/packages/pvm-gitlab/platform.ts +++ b/packages/plugin-gitlab/platform.ts @@ -1,14 +1,29 @@ import fs from 'fs' import { Lexer } from 'marked' import * as TOML from '@iarna/toml' -import { cwdShell } from '@pvm/core/lib/shell' -import { getContents } from '@pvm/core/lib/git/commands' +import { + cwdShell, getContents, PlatformResult, + PlatformInterface, + env, + log, +} from '@pvm/pvm' +import type { + AddTagOptions, + CommitResult, + GetReleaseResult, + CommitOptions, MetaComment, + Config, + + Container, + HostApi, + ReleasePayload, + CreateReleasePayload, +} from '@pvm/pvm' import { releasesIterator, updateRelease, createRelease, upsertRelease, addTagAndRelease } from './lib/api/releases' import { releaseTags } from './lib/api/tags/tags' import getTag from './lib/api/tags/get' import createTag from './lib/api/tags/create' -import { PlatformResult } from '@pvm/core/lib/shared' import type { SyncAttachmentOpts } from './lib/hal/mark-pr' import { syncAttachment, findNote } from './lib/hal/mark-pr' @@ -18,23 +33,13 @@ import gitlabEnv from './lib/env' import glapi from './lib/api' import type { MergeRequest } from './lib/api/mr/types' -import type { - AddTagOptions, - CommitResult, - GetReleaseResult, - CommitOptions, MetaComment, -} from '@pvm/vcs/types' import type { AlterReleaseResult } from './lib/api/releases/types' -import type { Config } from '@pvm/core/lib/config' -import { getConfig } from '@pvm/core/lib/config' -import { PlatformInterfaceWithFileCommitApi } from '@pvm/vcs/lib/platform-interface' import createLabel from './lib/api/labels/create' import getLabels from './lib/api/labels/labels' import updateMr from './lib/api/mr/update' -import { env } from '@pvm/core/lib/env' -import { log } from '@pvm/core/lib/logger' import { getGitlabHostUrl } from './lib/remote-url' +import type { GlobalFlags } from '@pvm/pvm/lib/cli/global-flags' const PVM_UPDATE_HINTS_KIND = 'pvm-update-hints' @@ -59,30 +64,36 @@ function isFileInitiallyExists(filePath: string): boolean { } } -export class GitlabPlatform extends PlatformInterfaceWithFileCommitApi { - public supportsFileCommitApi = true as const; +export class GitlabPlatform extends PlatformInterface { public currentMr: MergeRequest | null = null; - private config: Config; + protected config: Config; + protected di: Container + protected cwd: string + protected hostApi: HostApi + + constructor({ di, globalFlags, hostApi, config, cwd }: { di: Container, globalFlags: GlobalFlags, hostApi: HostApi, config: Config, cwd: string }) { + super({ name: GitlabPlatform.name, globalFlags }) - constructor({ config }: { config: Config }) { - super() this.config = config + this.cwd = cwd + this.hostApi = hostApi + this.di = di } setMrLabels(labels: string[]): Promise { const iid = this.requireMr().iid - return updateMr(gitlabEnv.projectId, iid, { + return updateMr(this.di, gitlabEnv.projectId, iid, { labels: labels.join(','), }) } getProjectLabels(): AsyncIterable<{ name: string }> { - return getLabels(gitlabEnv.projectId) + return getLabels(this.di, gitlabEnv.projectId) } async createProjectLabel(label: string, color: string): Promise { - return await createLabel(gitlabEnv.projectId, { + return await createLabel(this.di, gitlabEnv.projectId, { name: label, color, }) @@ -93,13 +104,13 @@ export class GitlabPlatform extends PlatformInterfaceWithFileCommitApi | void> { const iid = this.requireMr().iid - return await findNote(iid, kind) + return await findNote(this.di, iid, kind) } async createMrNote(body: string): Promise { const iid = this.requireMr().iid - await glapi(`/projects/${gitlabEnv.projectSlug}/merge_requests/${iid}/notes`, { + await glapi(this.di, `/projects/${gitlabEnv.projectSlug}/merge_requests/${iid}/notes`, { method: 'POST', body: { body, @@ -110,7 +121,7 @@ export class GitlabPlatform extends PlatformInterfaceWithFileCommitApi { const iid = this.requireMr().iid - await glapi(`/projects/${gitlabEnv.projectSlug}/merge_requests/${iid}/notes/${commentId}`, { + await glapi(this.di, `/projects/${gitlabEnv.projectSlug}/merge_requests/${iid}/notes/${commentId}`, { method: 'PUT', body: { body, @@ -120,7 +131,7 @@ export class GitlabPlatform extends PlatformInterfaceWithFileCommitApi { try { - const { json } = await getTag(gitlabEnv.projectId, tagName) + const { json } = await getTag(this.di, gitlabEnv.projectId, tagName) const { release } = json if (release) { return [PlatformResult.OK, { @@ -128,7 +139,7 @@ export class GitlabPlatform extends PlatformInterfaceWithFileCommitApi { - const res = await addTagAndRelease(gitlabEnv.projectId, ref, { + async addTagAndRelease(ref: string, tag_name: string, data: CreateReleasePayload): Promise { + const res = await addTagAndRelease(this.di, gitlabEnv.projectId, ref, { ...data, // name and description tag_name, }) @@ -168,8 +179,8 @@ export class GitlabPlatform extends PlatformInterfaceWithFileCommitApi { - const res = await createRelease(gitlabEnv.projectId, { + async createRelease(tag_name: string, data: CreateReleasePayload): Promise { + const res = await createRelease(this.di, gitlabEnv.projectId, { ...data, // name and description tag_name, }) @@ -179,15 +190,15 @@ export class GitlabPlatform extends PlatformInterfaceWithFileCommitApi { - return await updateRelease(gitlabEnv.projectId, { + async editRelease(tag_name: string, data: ReleasePayload): Promise { + return await updateRelease(this.di, gitlabEnv.projectId, { ...data, tag_name, }) } - async upsertRelease(tagName: string, data): Promise { - const res = await upsertRelease(gitlabEnv.projectId, { + async upsertRelease(tagName: string, data: ReleasePayload): Promise { + const res = await upsertRelease(this.di, gitlabEnv.projectId, { ...data, tag_name: tagName, }) @@ -198,7 +209,7 @@ export class GitlabPlatform extends PlatformInterfaceWithFileCommitApi { - const { json: commits } = await glapi( + const { json: commits } = await glapi(this.di, `/projects/${gitlabEnv.projectSlug}/repository/commits?per_page=1&ref_name=${encodeURIComponent(refName)}` ) return commits.length ? commits[0].id : '0000000000000000000000000000000000000000' @@ -297,13 +308,13 @@ export class GitlabPlatform extends PlatformInterfaceWithFileCommitApi } = await glapi(`/projects/${gitlabEnv.projectId}/repository/commits/${commit}/merge_requests`) + const { json: mrs }: { json: Array } = await glapi(this.di, `/projects/${gitlabEnv.projectId}/repository/commits/${commit}/merge_requests`) processedMr = mrs.find(mr => mr.state === 'merged' && mr.target_branch === currentBranch) @@ -352,37 +363,41 @@ export class GitlabPlatform extends PlatformInterfaceWithFileCommitApi | null { - let parsedDescription + let tokens try { const lexer = new Lexer() - parsedDescription = lexer.lex(text) + tokens = lexer.lex(text) } catch (e) { log(`Failed to parse MR description`) log(e) return null } - const tomlCodeBlocks = parsedDescription.filter(block => block.type === 'code' && block.lang === 'toml') - if (!tomlCodeBlocks.length) { - log(`toml code not found in mr description`) - return null - } + let codeBlockFound = false + for (const token of tokens) { + if (token.type !== 'code' || token.lang !== 'toml') { + codeBlockFound = true + continue + } - for (const block of tomlCodeBlocks) { try { - const parsed = TOML.parse(block.text) as any + const parsed = TOML.parse(token.text) as any if (parsed.kind === PVM_UPDATE_HINTS_KIND) { delete parsed.kind return parsed } } catch (e) { log(`Failed to parse toml code block`) - log(block.text) + log(token.text) log(e) break } } + if (!codeBlockFound) { + log(`toml code block not found in mr description`) + } + return null } diff --git a/packages/plugin-gitlab/tokens.ts b/packages/plugin-gitlab/tokens.ts new file mode 100644 index 000000000..11577c574 --- /dev/null +++ b/packages/plugin-gitlab/tokens.ts @@ -0,0 +1,3 @@ +import { createToken } from '@pvm/pvm' + +export const GITLAB_AUTH_FUNCTION_TOKEN = createToken<() => Promise>('GITLAB_AUTH_FUNCTION_TOKEN') diff --git a/packages/pvm-gitlab/types/api/notes.ts b/packages/plugin-gitlab/types/api/notes.ts similarity index 100% rename from packages/pvm-gitlab/types/api/notes.ts rename to packages/plugin-gitlab/types/api/notes.ts diff --git a/packages/pvm-gitlab/types/api/people.ts b/packages/plugin-gitlab/types/api/people.ts similarity index 100% rename from packages/pvm-gitlab/types/api/people.ts rename to packages/plugin-gitlab/types/api/people.ts diff --git a/packages/plugin-http-proxy/.npmignore b/packages/plugin-http-proxy/.npmignore new file mode 100644 index 000000000..6a57518a1 --- /dev/null +++ b/packages/plugin-http-proxy/.npmignore @@ -0,0 +1,5 @@ +*.ts +!*.d.ts +*.js.map +__tests__ +__snapshots__ diff --git a/packages/pvm-plugin-http-proxy/README.md b/packages/plugin-http-proxy/README.md similarity index 100% rename from packages/pvm-plugin-http-proxy/README.md rename to packages/plugin-http-proxy/README.md diff --git a/packages/plugin-http-proxy/lib/index.ts b/packages/plugin-http-proxy/lib/index.ts new file mode 100644 index 000000000..e0274cc9e --- /dev/null +++ b/packages/plugin-http-proxy/lib/index.ts @@ -0,0 +1,15 @@ +// @ts-ignore +import { bootstrap } from 'global-agent' +import { declarePlugin } from '@pvm/pvm' + +export default declarePlugin({ + factory: () => { + bootstrap({ + environmentVariableNamespace: '', + }) + + return { + providers: [], + } + }, +}) diff --git a/packages/pvm-plugin-http-proxy/package.json b/packages/plugin-http-proxy/package.json similarity index 81% rename from packages/pvm-plugin-http-proxy/package.json rename to packages/plugin-http-proxy/package.json index 075b29280..3da28e6d1 100644 --- a/packages/pvm-plugin-http-proxy/package.json +++ b/packages/plugin-http-proxy/package.json @@ -7,5 +7,8 @@ "license": "Apache-2.0", "dependencies": { "global-agent": "^2.1.12" + }, + "peerDependencies": { + "@pvm/pvm": "^0.0.0-stub" } } diff --git a/packages/plugin-mattermost/.npmignore b/packages/plugin-mattermost/.npmignore new file mode 100644 index 000000000..6a57518a1 --- /dev/null +++ b/packages/plugin-mattermost/.npmignore @@ -0,0 +1,5 @@ +*.ts +!*.d.ts +*.js.map +__tests__ +__snapshots__ diff --git a/packages/pvm-mattermost/README.md b/packages/plugin-mattermost/README.md similarity index 100% rename from packages/pvm-mattermost/README.md rename to packages/plugin-mattermost/README.md diff --git a/packages/pvm-mattermost/lib/index.ts b/packages/plugin-mattermost/lib/index.ts similarity index 83% rename from packages/pvm-mattermost/lib/index.ts rename to packages/plugin-mattermost/lib/index.ts index c90ad57ff..d75e6e504 100644 --- a/packages/pvm-mattermost/lib/index.ts +++ b/packages/plugin-mattermost/lib/index.ts @@ -1,15 +1,25 @@ -import type { Message } from '@pvm/types' -import { AbstractMessengerClient } from '@pvm/notifications' -import { httpreq } from '@pvm/core' -import { checkEnv, env } from '@pvm/core/lib/env' -import { loggerFor } from '@pvm/core/lib/logger' -import { gracefullyTruncateText } from '@pvm/core/lib/utils/string' -import { requestWithRetries } from '@pvm/core/lib/httpreq' +import type { + Message, + MessengerClientConfig, +} from '@pvm/pvm' +import { + AbstractMessengerClient, + httpreq, + checkEnv, + env, + loggerFor, + gracefullyTruncateText, + requestWithRetries, + declarePlugin, + provide, +} from '@pvm/pvm' +import { CONFIG_TOKEN, CWD_TOKEN, MESSENGER_CLIENT_TOKEN } from '@pvm/pvm/tokens' +import { Notificator } from '@pvm/pvm/mechanics/notifications/notificator' const logger = loggerFor('pvm:mattermost') const MAX_TEXT_LENGTH = 4000 // ограничение блока текста в mattermost -export class MattermostClient extends AbstractMessengerClient { +class MattermostClient extends AbstractMessengerClient { isReady(): boolean { const someEnvsSpecified = Boolean(env.PVM_MATTERMOST_INCOMING_WEBHOOK) || checkEnv(['PVM_MATTERMOST_TOKEN', 'PVM_MATTERMOST_URL'], 'mattermost integration', { logger, silent: true }) @@ -151,4 +161,20 @@ export class MattermostClient extends AbstractMessengerClient { } } -export const MessengerClient = MattermostClient +export default declarePlugin({ + factory: (opts: MessengerClientConfig & { name?: string }) => ({ + providers: [ + provide({ + provide: MESSENGER_CLIENT_TOKEN, + useFactory: ({ config }) => Notificator.createClient(MattermostClient, config, { + name: 'mattermost', + ...opts, + }), + deps: { + config: CONFIG_TOKEN, + cwd: CWD_TOKEN, + }, + }), + ], + }), +}) diff --git a/packages/pvm-mattermost/package.json b/packages/plugin-mattermost/package.json similarity index 62% rename from packages/pvm-mattermost/package.json rename to packages/plugin-mattermost/package.json index 91c0590da..7dbe92266 100644 --- a/packages/pvm-mattermost/package.json +++ b/packages/plugin-mattermost/package.json @@ -1,14 +1,12 @@ { - "name": "@pvm/mattermost", + "name": "@pvm/plugin-mattermost", "version": "0.0.0-stub", "description": "Api utilities for sending messages to mattermost", "main": "./lib", "repository": "git@github.com:Tinkoff/pvm.git", "author": "Mikhail Shipov ", "license": "Apache-2.0", - "dependencies": { - "@pvm/core": "0.0.0-stub", - "@pvm/notifications": "0.0.0-stub", - "@pvm/types": "0.0.0-stub" + "peerDependencies": { + "@pvm/pvm": "^0.0.0-stub" } } diff --git a/packages/plugin-slack/.npmignore b/packages/plugin-slack/.npmignore new file mode 100644 index 000000000..6a57518a1 --- /dev/null +++ b/packages/plugin-slack/.npmignore @@ -0,0 +1,5 @@ +*.ts +!*.d.ts +*.js.map +__tests__ +__snapshots__ diff --git a/packages/pvm-slack/README.md b/packages/plugin-slack/README.md similarity index 100% rename from packages/pvm-slack/README.md rename to packages/plugin-slack/README.md diff --git a/packages/pvm-slack/lib/__tests__/slack-api.spec.ts b/packages/plugin-slack/lib/__tests__/slack-api.spec.ts similarity index 97% rename from packages/pvm-slack/lib/__tests__/slack-api.spec.ts rename to packages/plugin-slack/lib/__tests__/slack-api.spec.ts index 0af5f8267..32673aebc 100644 --- a/packages/pvm-slack/lib/__tests__/slack-api.spec.ts +++ b/packages/plugin-slack/lib/__tests__/slack-api.spec.ts @@ -16,7 +16,6 @@ describe('slack-api', () => { .post('/chat.postMessage') .reply(200, { ok: true }) - // @ts-ignore await sendMessage({ text: 'hello world' }, { env: { PVM_SLACK_TOKEN: 'xoxb-test-token', diff --git a/packages/pvm-slack/lib/api.ts b/packages/plugin-slack/lib/api.ts similarity index 91% rename from packages/pvm-slack/lib/api.ts rename to packages/plugin-slack/lib/api.ts index b0ee612da..b29259d79 100644 --- a/packages/pvm-slack/lib/api.ts +++ b/packages/plugin-slack/lib/api.ts @@ -1,10 +1,7 @@ -import { loggerFor } from '@pvm/core/lib/logger' -import type { HttpResponseSuccess } from '@pvm/core/lib/httpreq' -import httpreq from '@pvm/core/lib/httpreq' -import resolveFrom from 'resolve-from' -import { requireDefault } from '@pvm/core/lib' +import { httpreq, loggerFor, requireDefault, env as defaultEnv } from '@pvm/pvm' +import type { HttpResponseSuccess } from '@pvm/pvm' -import { env as defaultEnv } from '@pvm/core/lib/env' +import resolveFrom from 'resolve-from' const SLACK_API_URL = defaultEnv.SLACK_API_URL || 'https://slack.com/api' const logger = loggerFor('pvm:slack') @@ -81,7 +78,7 @@ function chatPostMessage(message: SlackMessage, opts: SlackSendOpts = {}): Promi }) } -function readPvmEnv(name: string, env = defaultEnv): string | undefined { +function readPvmEnv(name: string, env: Record = defaultEnv): string | undefined { return env[name] ?? env[`PVM_${name}`] } diff --git a/packages/pvm-slack/lib/client.ts b/packages/plugin-slack/lib/client.ts similarity index 56% rename from packages/pvm-slack/lib/client.ts rename to packages/plugin-slack/lib/client.ts index f90fd9af1..354174416 100644 --- a/packages/pvm-slack/lib/client.ts +++ b/packages/plugin-slack/lib/client.ts @@ -1,11 +1,9 @@ -import type { Message } from '@pvm/types' -import { AbstractMessengerClient } from '@pvm/notifications' +import type { Message } from '@pvm/pvm' +import { AbstractMessengerClient, checkEnv, loggerFor, gracefullyTruncateText } from '@pvm/pvm' import { sendMessage } from './api' -import { checkEnv } from '@pvm/core/lib/env' -import { loggerFor } from '@pvm/core/lib/logger' -import { gracefullyTruncateText } from '@pvm/core/lib/utils/string' + import slackifyMarkdown from 'slackify-markdown' -import omitBy from 'lodash.omitby' +import { typedObjectKeys } from '@pvm/pvm/lib/utils' const logger = loggerFor('pvm:slack') @@ -17,7 +15,7 @@ export class SlackClient extends AbstractMessengerClient { } protected async internalSendMessage(message: Message): Promise { - await sendMessage(omitBy({ + const slackMessage: Record = { username: message.author?.name, icon_emoji: message.author?.avatarEmoji, icon_url: message.author?.avatarUrl, @@ -28,20 +26,30 @@ export class SlackClient extends AbstractMessengerClient { text: slackifyMarkdown(gracefullyTruncateText(message.content, MAX_TEXT_LENGTH)).trim(), }, }], - attachments: message.attachments?.map(attachment => { - const slackified = {} + attachments: message.attachments?.map((attachment) => { + const slackified: { [p in keyof typeof attachment]: any } = {} + const attachmentFields = typedObjectKeys(attachment) - for (const field of Object.keys(attachment)) { - if (typeof attachment[field] !== 'string') { + for (const field of attachmentFields) { + const fieldValue = attachment[field] + if (typeof fieldValue !== 'string') { slackified[field] = attachment[field] } else { - slackified[field] = slackifyMarkdown(attachment[field]).trim() + slackified[field] = slackifyMarkdown(fieldValue).trim() } } return slackified }), channel: message.channel, - }, prop => prop === undefined)) + } + + for (const [k, v] of Object.entries(slackMessage)) { + if (v === undefined) { + delete slackMessage[k] + } + } + + await sendMessage(slackMessage) } } diff --git a/packages/plugin-slack/lib/index.ts b/packages/plugin-slack/lib/index.ts new file mode 100644 index 000000000..010d53f9a --- /dev/null +++ b/packages/plugin-slack/lib/index.ts @@ -0,0 +1,25 @@ +import type { MessengerClientConfig } from '@pvm/pvm' +import { declarePlugin, Notificator, provide } from '@pvm/pvm' +import { CONFIG_TOKEN, CWD_TOKEN, MESSENGER_CLIENT_TOKEN } from '@pvm/pvm/tokens' +import { SlackClient } from './client' + +export * from './api' +export * from './messaging' + +export default declarePlugin({ + factory: (opts: MessengerClientConfig & { name?: string }) => ({ + providers: [ + provide({ + provide: MESSENGER_CLIENT_TOKEN, + useFactory: ({ config }) => Notificator.createClient(SlackClient, config, { + name: 'slack', + ...opts, + }), + deps: { + config: CONFIG_TOKEN, + cwd: CWD_TOKEN, + }, + }), + ], + }), +}) diff --git a/packages/pvm-slack/lib/messaging.ts b/packages/plugin-slack/lib/messaging.ts similarity index 88% rename from packages/pvm-slack/lib/messaging.ts rename to packages/plugin-slack/lib/messaging.ts index dcb6fdf54..41a4e8627 100644 --- a/packages/pvm-slack/lib/messaging.ts +++ b/packages/plugin-slack/lib/messaging.ts @@ -1,4 +1,4 @@ -import { replaceLinks, dottifyList } from '@pvm/core/lib/text/markdown' +import { replaceLinks, dottifyList } from '@pvm/pvm' export function processMarkdown(text: string): string { return replaceLinks(text, (_, subj, link) => { diff --git a/packages/pvm-slack/package.json b/packages/plugin-slack/package.json similarity index 60% rename from packages/pvm-slack/package.json rename to packages/plugin-slack/package.json index 0795778bc..2c7742ac0 100644 --- a/packages/pvm-slack/package.json +++ b/packages/plugin-slack/package.json @@ -1,5 +1,5 @@ { - "name": "@pvm/slack", + "name": "@pvm/plugin-slack", "version": "0.0.0-stub", "description": "Cli and api utilities for sending messages to slack", "main": "./lib", @@ -7,11 +7,10 @@ "author": "Andrey Rublev ", "license": "Apache-2.0", "dependencies": { - "@pvm/core": "^0.0.0-stub", - "@pvm/notifications": "^0.0.0-stub", - "@pvm/types": "^0.0.0-stub", "resolve-from": "^5.0.0", - "slackify-markdown": "4.3.1", - "lodash.omitby": "^4.6.0" + "slackify-markdown": "4.3.1" + }, + "peerDependencies": { + "@pvm/pvm": "^0.0.0-stub" } -} \ No newline at end of file +} diff --git a/packages/pvm-add-tag/.gitignore b/packages/pvm-add-tag/.gitignore deleted file mode 100644 index 8d1c01490..000000000 --- a/packages/pvm-add-tag/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/node_modules -/.cache -*.log diff --git a/packages/pvm-add-tag/README.md b/packages/pvm-add-tag/README.md deleted file mode 100644 index 825947da6..000000000 --- a/packages/pvm-add-tag/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# @pvm/add-tag - -Provides a `node api` for getting a new release tag and a `cli api` for -adding a release tag to a commit. `@pvm/add-tag` only add tag and not generating any additional stuff like changelogs and other artifacts what `@pvm/update` do. \ No newline at end of file diff --git a/packages/pvm-add-tag/cli/pvm-add-tag.ts b/packages/pvm-add-tag/cli/pvm-add-tag.ts deleted file mode 100755 index a1869122f..000000000 --- a/packages/pvm-add-tag/cli/pvm-add-tag.ts +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env node - -import { log } from '@pvm/core/lib/logger' -import { getConfig } from '@pvm/core/lib/config' -import { wdShell } from '@pvm/core/lib/shell' -import { getNewTag } from '../lib' -import { initVcsPlatform } from '@pvm/vcs' - -export const command = 'add-tag' -export const description = 'Creates a new release tag via GitLab API based on commits made after the last release tag' -export const builder = {} -export const handler = main - -async function createTag(tag, ref) { - const vcsPlatform = await initVcsPlatform({ vcsMode: 'platform' }) - - log(`creating tag ${tag} for ${ref} ref by platform api`) - return vcsPlatform.addTag(tag, ref) -} - -async function main() { - const config = await getConfig() - const targetRef = wdShell(config.cwd, 'git rev-parse HEAD') - const newTag = await getNewTag(config, targetRef) - if (newTag) { - return createTag(newTag, targetRef) - } else { - log('new tag not calculated (see logs below)') - } -} diff --git a/packages/pvm-add-tag/lib/index.ts b/packages/pvm-add-tag/lib/index.ts deleted file mode 100644 index b55799bfd..000000000 --- a/packages/pvm-add-tag/lib/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { getNewTag } from './get-new-tag' diff --git a/packages/pvm-add-tag/package.json b/packages/pvm-add-tag/package.json deleted file mode 100644 index 60780a63e..000000000 --- a/packages/pvm-add-tag/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "@pvm/add-tag", - "version": "0.0.0-stub", - "description": "Определение следующего релиза для простых репозиториев", - "main": "lib/index.js", - "repository": "git@github.com:Tinkoff/pvm.git", - "author": "Andrey Rublev ", - "license": "Apache-2.0", - "dependencies": { - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/core": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", - "@pvm/update": "0.0.0-stub" - } -} diff --git a/packages/pvm-add-tag/plugin.ts b/packages/pvm-add-tag/plugin.ts deleted file mode 100644 index 623e9e3d7..000000000 --- a/packages/pvm-add-tag/plugin.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { declarePlugin, provide } from '@pvm/di' -import { CLI_EXTENSION_TOKEN } from '@pvm/tokens-core' - -import * as addTagCommand from './cli/pvm-add-tag' - -export default declarePlugin({ - factory: function() { - return { - providers: [ - provide({ - provide: CLI_EXTENSION_TOKEN, - useValue: [ - addTagCommand, - ], - multi: true, - }), - ], - } - }, -}) diff --git a/packages/pvm-artifacts/README.md b/packages/pvm-artifacts/README.md deleted file mode 100644 index ba4246d7f..000000000 --- a/packages/pvm-artifacts/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# @pvm/artifacts - -The module provides functionality for loading and unloading release artifacts. In particular changelogs and list of releases. -The module is useful if pushing to the master is disabled or versioning is built through git tags and you do not want additional -commits to master. - -Supported Artifact Types: -* Changelogs -* Release lists - -Supported artifact storage types: -* git branch in the repository \ No newline at end of file diff --git a/packages/pvm-artifacts/cli/pvm-artifacts-download.ts b/packages/pvm-artifacts/cli/pvm-artifacts-download.ts deleted file mode 100644 index 7c0506c8f..000000000 --- a/packages/pvm-artifacts/cli/pvm-artifacts-download.ts +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env node - -import type { ArtifactsTransferArgs } from '../pub/artifacts' -import { download } from '../pub/artifacts' -import { cliArtifactsChoices } from './common' - -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' - -export const command = 'download ' -export const description = 'Download a given kind of artifacts from remote storage' -export const builder = (yargs: Argv) => { - return yargs - .positional('kind', { - desc: 'Kind of artifact for downloading', - type: 'string' as const, - choices: cliArtifactsChoices, - }) - .option('quiet', { - desc: `Don't print warnings`, - type: 'boolean' as const, - default: false, - }) - .option('force', { - desc: `Download an artifact even if it is not turned on in config`, - type: 'boolean' as const, - default: false, - }) -} - -export const handler = main - -async function main(args: Record): Promise { - await download(args as ArtifactsTransferArgs) -} diff --git a/packages/pvm-artifacts/cli/pvm-artifacts-upload.ts b/packages/pvm-artifacts/cli/pvm-artifacts-upload.ts deleted file mode 100644 index dbeefb31a..000000000 --- a/packages/pvm-artifacts/cli/pvm-artifacts-upload.ts +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env node - -import type { ArtifactsTransferArgs } from '../pub/artifacts' -import { upload } from '../pub/artifacts' -import { cliArtifactsChoices } from './common' - -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' - -export const command = 'upload ' -export const description = 'Upload a given kind of artifacts from remote storage' -export const builder = (yargs: Argv) => { - return yargs - .positional('kind', { - desc: 'Kind of artifact for uploading', - type: 'string' as const, - choices: cliArtifactsChoices, - }) - .option('quiet', { - desc: `Don't print warnings`, - type: 'boolean' as const, - default: false, - }) - .option('force', { - desc: `Upload artifacts even if they are not turned on in config`, - type: 'boolean' as const, - default: false, - }) -} - -export const handler = main - -async function main(args: Record): Promise { - await upload(args as ArtifactsTransferArgs) -} diff --git a/packages/pvm-artifacts/cli/pvm-artifacts.ts b/packages/pvm-artifacts/cli/pvm-artifacts.ts deleted file mode 100644 index 1f0b3bd11..000000000 --- a/packages/pvm-artifacts/cli/pvm-artifacts.ts +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env node - -import * as pvmArtifactsDownload from './pvm-artifacts-download' -import * as pvmArtifactsUpload from './pvm-artifacts-upload' - -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' - -export const command = 'artifacts ' -export const description = 'Commands for working with pvm artifacts' -export const builder = (yargs: Argv) => { - return yargs - .command(pvmArtifactsDownload) - .command(pvmArtifactsUpload) -} - -export const handler = function() {} diff --git a/packages/pvm-artifacts/package.json b/packages/pvm-artifacts/package.json deleted file mode 100644 index ed0f1d0bf..000000000 --- a/packages/pvm-artifacts/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "@pvm/artifacts", - "version": "0.0.0-stub", - "description": "Artifacts manager", - "main": "pub/artifacts.js", - "repository": "git@github.com:Tinkoff/pvm.git", - "author": "Andrey Rublev ", - "license": "Apache-2.0", - "dependencies": { - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/core": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", - "@pvm/vcs-git": "0.0.0-stub", - "chalk": "^4.0.0", - "fs-extra": "^10.0.0", - "tempy": "^1.0.1", - "yargs": "^16.1.1" - }, - "devDependencies": { - "@types/fs-extra": "^9.0.11" - } -} diff --git a/packages/pvm-artifacts/plugin.ts b/packages/pvm-artifacts/plugin.ts deleted file mode 100644 index cfa3944b8..000000000 --- a/packages/pvm-artifacts/plugin.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { declarePlugin, provide } from '@pvm/di' -import { CLI_EXTENSION_TOKEN } from '@pvm/tokens-core' - -import * as command from './cli/pvm-artifacts' - -export default declarePlugin({ - factory: function() { - return { - providers: [ - provide({ - provide: CLI_EXTENSION_TOKEN, - useValue: command, - multi: true, - }), - ], - } - }, -}) diff --git a/packages/pvm-changelog/README.md b/packages/pvm-changelog/README.md deleted file mode 100644 index ce1e367ea..000000000 --- a/packages/pvm-changelog/README.md +++ /dev/null @@ -1 +0,0 @@ -# @pvm/changelog diff --git a/packages/pvm-changelog/cli/pvm-changelog-download.ts b/packages/pvm-changelog/cli/pvm-changelog-download.ts deleted file mode 100644 index 3af714850..000000000 --- a/packages/pvm-changelog/cli/pvm-changelog-download.ts +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env node - -import { download, ArtifactsStorages } from '@pvm/artifacts/pub/artifacts' - -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' - -export const command = 'download' -export const description = 'Download Changelog artifacts from remote storage' -export const builder = (yargs: Argv) => { - return yargs - .option('quiet', { - desc: `Don't print warnings`, - type: 'boolean' as const, - default: false, - }) - .option('force', { - desc: `Download artifacts even if they are not turned on`, - type: 'boolean' as const, - default: false, - }) -} - -export const handler = main - -async function main(args: Record): Promise { - await download({ - force: args.force, - quiet: args.quiet, - kind: ArtifactsStorages.Changelogs, - }) -} diff --git a/packages/pvm-changelog/cli/pvm-changelog-make.ts b/packages/pvm-changelog/cli/pvm-changelog-make.ts deleted file mode 100644 index 628eb30ab..000000000 --- a/packages/pvm-changelog/cli/pvm-changelog-make.ts +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env node - -import chalk from 'chalk' -import initVcs from '@pvm/vcs' -import { log } from '@pvm/core/lib/logger' -import { makeChangelog } from '../lib' -import { getConfig } from '@pvm/core/lib/config' -import { StorageManager } from '@pvm/artifacts/lib/storage-manager' -import { releaseDataMaker } from '@pvm/releases/lib/release-data' -import { getUpdateState } from '@pvm/update/lib' -import { createReleaseContext } from '@pvm/update/lib/release/release-context' - -import type { ReleaseData } from '@pvm/releases/types' -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' - -export const command = 'make' -export const description = 'Generate changelogs from ReleaseList artifact' -export const builder = (yargs: Argv) => { - return yargs - .option('append-upcoming-release', { - desc: `Generate ReleasedData based on unreleased changes and count it in case incremental changelog renderering`, - type: 'boolean' as const, - default: false, - }) -} -export const handler = main - -async function main(flags: Record): Promise { - log(chalk`{yellow Generating changelog}`) - const cwd = process.cwd() - const config = await getConfig(cwd) - const vcs = await initVcs({ - vcsType: 'fs', - cwd, - }) - - const storageManager = new StorageManager({ - config, - vcs, - }) - - const releaseListStorage = await storageManager.initFor(StorageManager.ArtifactsStorages.ReleaseList) - await releaseListStorage.download() - - let releaseData: ReleaseData | undefined - - if (flags.appendUpcomingRelease) { - const updateState = await getUpdateState({ - includeUncommited: true, - }) - - const releaseContext = await createReleaseContext(updateState) - if (releaseContext) { - releaseData = await releaseDataMaker.fromReleaseContext(releaseContext) - } - } - - const changelogsStorage = await storageManager.initFor(StorageManager.ArtifactsStorages.Changelogs) - - if ((config.changelog.enabled || config.changelog.for_packages.enabled)) { - await changelogsStorage.download() - await makeChangelog(config, releaseData) - } else { - log(`Changelog is not enabled. Exiting`) - } - - await storageManager.finish() -} diff --git a/packages/pvm-changelog/cli/pvm-changelog-upload.ts b/packages/pvm-changelog/cli/pvm-changelog-upload.ts deleted file mode 100644 index d78b9e367..000000000 --- a/packages/pvm-changelog/cli/pvm-changelog-upload.ts +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env node - -import { upload, ArtifactsStorages } from '@pvm/artifacts/pub/artifacts' - -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' - -export const command = 'upload' -export const description = 'Upload Changelog artifacts to remote storage' -export const builder = (yargs: Argv) => { - return yargs - .option('quiet', { - desc: `Don't print warnings`, - type: 'boolean' as const, - default: false, - }) - .option('force', { - desc: `Upload artifacts even they are not turned on`, - type: 'boolean' as const, - default: false, - }) -} - -export const handler = main - -async function main(args: Record): Promise { - await upload({ - force: args.force, - quiet: args.quiet, - kind: ArtifactsStorages.Changelogs, - }) -} diff --git a/packages/pvm-changelog/cli/pvm-changelog.ts b/packages/pvm-changelog/cli/pvm-changelog.ts deleted file mode 100644 index cb04267f1..000000000 --- a/packages/pvm-changelog/cli/pvm-changelog.ts +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env node - -import * as pvmChangelogMake from './pvm-changelog-make' -import * as pvmChangelogDownload from './pvm-changelog-download' -import * as pvmChangelogUpload from './pvm-changelog-upload' -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' - -export const command = 'changelog ' -export const description = 'Commands for working with Changelog artifacts' -export const builder = (yargs: Argv) => { - return yargs - .command(pvmChangelogMake) - .command(pvmChangelogDownload) - .command(pvmChangelogUpload) -} - -export const handler = function() {} diff --git a/packages/pvm-changelog/lib/provide-builtin-renderers.ts b/packages/pvm-changelog/lib/provide-builtin-renderers.ts deleted file mode 100644 index 23afe0d64..000000000 --- a/packages/pvm-changelog/lib/provide-builtin-renderers.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { getHostApi } from '@pvm/core/lib/plugins' -import ListRenderer from './md/list' -import ListWithPackagesRenderer from './md/list-with-packages' - -async function provideBuiltinRenderers(cwd: string): Promise { - const hostApi = await getHostApi(cwd) - - hostApi.provides('changelog.builtin.list', ListRenderer) - hostApi.provides('changelog.builtin.list-with-packages', ListWithPackagesRenderer) -} - -export default provideBuiltinRenderers diff --git a/packages/pvm-changelog/package.json b/packages/pvm-changelog/package.json deleted file mode 100644 index c0a9dd358..000000000 --- a/packages/pvm-changelog/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "@pvm/changelog", - "version": "0.0.0-stub", - "description": "helps generate changelogs for pvm projects", - "main": "lib/index.js", - "repository": "git@github.com:Tinkoff/pvm.git", - "author": "Andrey Rublev ", - "license": "Apache-2.0", - "dependencies": { - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/artifacts": "0.0.0-stub", - "@pvm/core": "0.0.0-stub", - "@pvm/pkgset": "0.0.0-stub", - "@pvm/releases": "0.0.0-stub", - "@pvm/template": "0.0.0-stub", - "@pvm/update": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", - "chalk": "^4.0.0", - "date-fns": "^2.7.0", - "front-matter": "^3.0.2", - "remarkable": "^2.0.0", - "resolve-from": "^5.0.0", - "yargs": "^16.1.1" - }, - "devDependencies": { - "@pvm/vcs": "0.0.0-stub" - } -} diff --git a/packages/pvm-changelog/plugin.ts b/packages/pvm-changelog/plugin.ts deleted file mode 100644 index c1bd8448e..000000000 --- a/packages/pvm-changelog/plugin.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { declarePlugin, provide } from '@pvm/di' -import { CLI_EXTENSION_TOKEN } from '@pvm/tokens-core' - -import * as command from './cli/pvm-changelog' - -export default declarePlugin({ - factory: function() { - return { - providers: [ - provide({ - provide: CLI_EXTENSION_TOKEN, - useValue: command, - multi: true, - }), - ], - } - }, -}) diff --git a/packages/pvm-core/README.md b/packages/pvm-core/README.md deleted file mode 100644 index adbdad073..000000000 --- a/packages/pvm-core/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# @pvm/core - diff --git a/packages/pvm-core/lib/analyzer/simple.ts b/packages/pvm-core/lib/analyzer/simple.ts deleted file mode 100644 index 2cd87a41d..000000000 --- a/packages/pvm-core/lib/analyzer/simple.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { PvmReleaseType } from '@pvm/types' - -const isPatchRe = /^(fix|patch):/i -const isMajorRe = /^BREAKING CHANGE:/ - -function releaseType(messages: string[], defaultLevel: PvmReleaseType = 'minor'): PvmReleaseType { - let isPatch = true - - for (const message of messages) { - if (isMajorRe.test(message)) { - return 'major' - } - - if (!isPatchRe.test(message)) { - isPatch = false - } - } - - return isPatch ? 'patch' : defaultLevel -} - -export default releaseType -export const tags = [isPatchRe, isMajorRe] diff --git a/packages/pvm-core/lib/app/README.md b/packages/pvm-core/lib/app/README.md deleted file mode 100644 index be989ddd3..000000000 --- a/packages/pvm-core/lib/app/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# @pvm/app - -Entrypoint to pvm functionality. Consumes user config and additional plugins list - - -## Usage examples - -As node library: -```javascript -import { Pvm } from '@pvm/app' - -const pvm = new Pvm({ - config: './.pvm.toml', // or config object { mark_pr: { analyze_update: true } } for example, - plugins: [], // this is useful for providing preconfigured Pvm instances (examples here will be github usage where github plugin is required) - cwd: '.', // from where plugins resolving will happen - repo: '.' // by default is equal to cwd but can differ in case you want to process external repository where pvm is not installed -}) - -const pkgs = await pvm.pkgset('all') -``` - -and as cli: -```javascript -// cli.js -import { Pvm } from '@pvm/app' -import { CLI_TOKEN } from '@pvm/tokens-core' -import PvmCliPlugin from '@pvm/plugin-cli' - -const pvm = new Pvm({ - config: {}, // or config object { mark_pr: { analyze_update: true } } for example, - plugins: [{ - plugin: PvmCliPlugin - }], // this is useful for providing preconfigured Pvm instances (examples here will be github usage where github plugin is required) - cwd: process.cwd(), // by default is equal `process.cwd()`. Spcify from where plugins resolving will happen - repo: process.cwd() // by default is equal to cwd but can differ in case you want to process external repository where pvm is not installed -}) - -pvm.container.get(CLI_TOKEN)(process.argv) // will start [`yargs`](https://yargs.js.org/) with all extensions, provided by CLI_EXTENSION_TOKEN, appliend -``` - -then you can call `cli.js` file and use provided cli api -``` -> node ./cli.js --help -``` \ No newline at end of file diff --git a/packages/pvm-core/lib/app/__tests__/__fixtures__/non-cwd-config-and-provider/pvm/index.js b/packages/pvm-core/lib/app/__tests__/__fixtures__/non-cwd-config-and-provider/pvm/index.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/pvm-core/lib/app/__tests__/__fixtures__/plugin-with-config-extension.js b/packages/pvm-core/lib/app/__tests__/__fixtures__/plugin-with-config-extension.js deleted file mode 100644 index 340a55418..000000000 --- a/packages/pvm-core/lib/app/__tests__/__fixtures__/plugin-with-config-extension.js +++ /dev/null @@ -1,9 +0,0 @@ -const { declarePlugin } = require('@pvm/di') - -module.exports = declarePlugin({ - configExt: { - mark_pr: { - analyze_update: true, - }, - }, -}) diff --git a/packages/pvm-core/lib/app/__tests__/__fixtures__/provided-plugins/plugin.js b/packages/pvm-core/lib/app/__tests__/__fixtures__/provided-plugins/plugin.js deleted file mode 100644 index bbe2a6e9b..000000000 --- a/packages/pvm-core/lib/app/__tests__/__fixtures__/provided-plugins/plugin.js +++ /dev/null @@ -1,6 +0,0 @@ -const { declarePlugin } = require('@pvm/di') -module.exports = declarePlugin({ - configExt: { - test: true, - }, -}) diff --git a/packages/pvm-core/lib/app/__tests__/__fixtures__/user-config-plugins/pvm/plugin.js b/packages/pvm-core/lib/app/__tests__/__fixtures__/user-config-plugins/pvm/plugin.js deleted file mode 100644 index bbe2a6e9b..000000000 --- a/packages/pvm-core/lib/app/__tests__/__fixtures__/user-config-plugins/pvm/plugin.js +++ /dev/null @@ -1,6 +0,0 @@ -const { declarePlugin } = require('@pvm/di') -module.exports = declarePlugin({ - configExt: { - test: true, - }, -}) diff --git a/packages/pvm-core/lib/app/index.ts b/packages/pvm-core/lib/app/index.ts deleted file mode 100644 index bb36eee39..000000000 --- a/packages/pvm-core/lib/app/index.ts +++ /dev/null @@ -1,172 +0,0 @@ -import path from 'path' -import type { PluginConfig, PluginFactory, Config, RecursivePartial, PluginDeclaration } from '@pvm/types' -import { Container, DI_TOKEN, provide } from '@pvm/di' -import { CLI_TOKEN, CONFIG_TOKEN, CWD_TOKEN } from '@pvm/tokens-core' -import { - defaultsFromProvider, - loadRawConfig, - mergeDefaults, - migrateDeprecated, - readEnv, - validateAgainstSchema, -} from '../config/get-config' -import { defaultConfig } from '../../pvm-defaults' -import { logger, loggerFor } from '../logger' -import { verifyRequiredBins } from './required-bin-versions' -import chalk from 'chalk' -import { resolvePvmProvider } from '../plugins/provider' - -const log = loggerFor('pvm:app') - -export function isPlainObject(x: unknown): x is Record { - return !!x && !Array.isArray(x) && typeof x === 'object' -} - -export class Pvm { - container: Container - cwd: string - configDir: string - registeredPlugins = new Set() - - constructor(opts: { - config?: RecursivePartial | string | null, - plugins?: PluginConfig[], - cwd?: string, - } = {}) { - const { config, cwd = process.cwd(), plugins = [] } = opts ?? {} - - this.cwd = cwd - this.configDir = typeof config === 'string' ? config : cwd - - this.container = new Container() - - this.container.register(provide({ - provide: CWD_TOKEN, - useValue: cwd, - })) - - this.container.register(provide({ - useValue: this.container, - provide: DI_TOKEN, - })) - - this.initConfigAndPlugins(config, plugins) - } - - runCli(argv: string[] = process.argv): void { - verifyRequiredBins().then(() => { - this.container.get(CLI_TOKEN)({ - argv, - }) - }).catch(e => { - console.error(e) - process.exitCode = 1 - }) - } - - protected initConfigAndPlugins(config: RecursivePartial | string | null | undefined, plugins: PluginConfig[] = []) { - const configExtensions:RecursivePartial[] = [] - // Env config - configExtensions.push(readEnv()) - - // User defined config - const userConfig: { config: RecursivePartial, filepath: string | null } = (typeof config === 'string' || !config) ? loadRawConfig(this.configDir) : { config: config ?? {}, filepath: null } - configExtensions.push(this.setupConfigDirs(userConfig.config, this.cwd, this.configDir)) - let nextConfig = this.mergeConfigExtensions(configExtensions) - - // Config extensions from plugins - let nextConfigExtensions = this.registerPlugins(plugins ?? [], this.configDir) - nextConfig = mergeDefaults(nextConfig, this.mergeConfigExtensions(nextConfigExtensions)) - - // Config extensions from user defined plugins - nextConfigExtensions = this.registerPlugins(nextConfig.plugins_v2 ?? [], this.configDir) - nextConfig = mergeDefaults(nextConfig, this.mergeConfigExtensions(nextConfigExtensions)) - - const provider = resolvePvmProvider(userConfig.filepath ? path.dirname(path.resolve(this.configDir, userConfig.filepath)) : this.configDir) - if (provider) { - const providerConfig = defaultsFromProvider(provider) - if (providerConfig) { - // Config extensions from provider itself - nextConfig = mergeDefaults(nextConfig, providerConfig) - if (providerConfig.plugins_v2) { - nextConfigExtensions = this.registerPlugins(providerConfig.plugins_v2, provider.path) - // Config extensions from provider plugins - nextConfig = mergeDefaults(nextConfig, this.mergeConfigExtensions(nextConfigExtensions)) - } - } - } - - if (defaultConfig.plugins_v2) { - nextConfigExtensions = this.registerPlugins(defaultConfig.plugins_v2, path.dirname(require.resolve('../../pvm-defaults'))) - // Config extensions from default config plugins - nextConfig = mergeDefaults(nextConfig, this.mergeConfigExtensions(nextConfigExtensions)) - } - // Config extensions from default config itself - nextConfig = mergeDefaults(nextConfig, defaultConfig) - - migrateDeprecated(nextConfig) - - validateAgainstSchema(nextConfig) - - logger.debug('config.versioning.source is', nextConfig.versioning.source) - logger.debug('config.versioning.unified_versions_for is', JSON.stringify(nextConfig.versioning.unified_versions_for)) - - nextConfig.executionContext = { - dryRun: false, - local: false, - } - - this.container.register(provide({ - useValue: nextConfig, - provide: CONFIG_TOKEN, - })) - } - - private setupConfigDirs(resultConfig: RecursivePartial, cwd: string, configLookupDir: string) { - resultConfig.cwd = cwd - resultConfig.configLookupDir = configLookupDir - - return resultConfig - } - - protected mergeConfigExtensions(configExtensions: RecursivePartial[]): Config { - return configExtensions.reduce((acc, extension) => mergeDefaults(acc, extension), {} as Config) as Config - } - - protected registerPlugins(plugins: PluginConfig[], resolveRoot: string): RecursivePartial[] { - let configExtensions: RecursivePartial[] = [] - for (const pluginConfig of plugins) { - const { factory, configExt, resolvedPath } = this.resolvePlugin(pluginConfig, resolveRoot) - - if (factory ? this.registeredPlugins.has(factory) : this.registeredPlugins.has(configExt)) { - throw new Error(`Plugin ${typeof pluginConfig.plugin === 'string' ? pluginConfig.plugin : pluginConfig.plugin.name} resolved from ${resolveRoot} already registered`) - } - this.registeredPlugins.add(factory ?? configExt) - const pluginProviders = factory ? factory(pluginConfig.options || {}).providers : [] - for (const provider of pluginProviders) { - this.container.register(provider) - } - log.info(chalk`plugin {blue ${resolvedPath}} loaded. Resolved from ${resolveRoot}`) - - if (configExt) { - configExtensions.push(configExt) - if (configExt.plugins_v2) { - configExtensions = configExtensions.concat(this.registerPlugins(configExt.plugins_v2, path.dirname(resolvedPath))) - } - } - } - return configExtensions - } - - protected resolvePlugin(pluginConfig: PluginConfig, resolveRoot: string): { factory?: PluginFactory, configExt?: RecursivePartial, resolvedPath: string } { - if (typeof pluginConfig.plugin === 'string') { - const pluginPath = require.resolve(pluginConfig.plugin, { paths: [resolveRoot] }) - const pluginModule = require(pluginPath) - return { ...((pluginModule.__esModule ? pluginModule.default : pluginModule) as PluginDeclaration), resolvedPath: pluginPath } - } - - const opts = isPlainObject(pluginConfig.plugin) ? pluginConfig.plugin : { factory: pluginConfig.plugin } - - return { ...opts, resolvedPath: resolveRoot } - } -} diff --git a/packages/pvm-core/lib/config/defaults.ts b/packages/pvm-core/lib/config/defaults.ts deleted file mode 100644 index df9e6bd06..000000000 --- a/packages/pvm-core/lib/config/defaults.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { Config } from './types' -import { defaultConfig } from './../../pvm-defaults' - -function readDefaults(): Config { - return defaultConfig as Config -} - -export default readDefaults() diff --git a/packages/pvm-core/lib/config/index.ts b/packages/pvm-core/lib/config/index.ts deleted file mode 100644 index 9af7bec0a..000000000 --- a/packages/pvm-core/lib/config/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -import getConfig, { clearConfigCacheFor, loadRawConfig, getConfigWithoutIncludes } from './get-config' -import type { Config } from './types' -import defaultConfig from './defaults' - -export { - Config, - getConfig, - defaultConfig, - clearConfigCacheFor, - loadRawConfig, - getConfigWithoutIncludes, -} diff --git a/packages/pvm-core/lib/config/types.ts b/packages/pvm-core/lib/config/types.ts deleted file mode 100644 index 2465f0747..000000000 --- a/packages/pvm-core/lib/config/types.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { Config as ConfigSchema } from '@pvm/types' - -export type { StorageDef, ArtifactLimitDef } from '@pvm/types' - -export interface Config extends ConfigSchema { - cwd: string, - // директория в которой искать конфигурационные файлы на случай, если мы работаем с неполным worktree - configLookupDir: string, - executionContext: { - dryRun: boolean, - local: boolean, - }, -} diff --git a/packages/pvm-core/lib/index.ts b/packages/pvm-core/lib/index.ts deleted file mode 100644 index 7027d6dec..000000000 --- a/packages/pvm-core/lib/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { shell, wdShell, cwdShell } from './shell' -import httpreq from './httpreq' - -export { requireDefault } from './interop' -export { shell, wdShell, cwdShell, httpreq } diff --git a/packages/pvm-core/lib/plugins/index.ts b/packages/pvm-core/lib/plugins/index.ts deleted file mode 100644 index bcdde7660..000000000 --- a/packages/pvm-core/lib/plugins/index.ts +++ /dev/null @@ -1,307 +0,0 @@ -import path from 'path' -import { EventEmitter } from 'events' -import chalk from 'chalk' -import { log, logger } from '../logger' -import pEachSeries from 'p-each-series' -import resolveFrom from 'resolve-from' -import { requireDefault } from '../interop' -import markdownifyCommits from '../markdownify-commits' -import { getConfig } from '../config' -import { releaseMark } from '../consts' -import { mema } from '../memoize' -import { resolvePvmProvider } from './provider' - -import type { Commit, PvmReleaseType, SemverReleaseType } from '@pvm/types' -import type { Pkg } from '../pkg' -import type { ChangedContext } from '@pvm/update/lib/changed-context' -import type { VcsPlatform } from '@pvm/vcs/lib' -import type { ReleaseContext } from '@pvm/update/types' -import type { ReleaseData, ReleaseDataExt } from '@pvm/releases/types' -import type { VcsRelease } from '@pvm/vcs/types' - -import type { UpdateState } from '@pvm/update/lib/update-state' - -type PipelineFn = (...args: any[]) => Promise -const pipelines: Record> = Object.create(null) -const providers = Object.create(null) - -export const features = { - commitsToNotes: 'commits-to-notes', - preReleaseHook: 'pre-release-hook', - releaseTypeByCommits: 'release-type-by-commits', - releaseTypeBuilder: 'release-type-builder', - releaseType: 'release-type', - releaseInfoFromReleaseCtx: 'release-info-from-release-ctx', - releaseInfoFromVcs: 'release-info-from-vcs', - attributeReleaseData: 'attribute-release-data', - notifyScriptsPath: 'notify-scripts-path', -} - -const featureDefaults = { - [features.commitsToNotes]: (commits, _maybePkg, config) => markdownifyCommits(commits, { jiraUrl: config.jira.url }), -} - -type AnyFunc = any - -interface Features { - [key: string]: AnyFunc, // @TODO -} - -export interface PluginsApi { - features: typeof features, - cwd: string, - provides(feature: K, impl: Features[K]): void, - provideRecord(ns: string, rec: Partial): void, - provideClass(ns: string, rec: Partial): void, - getDefaultImpl(feature: K): Features[K], - getOr(feature: K, defaultIml: D): Features[K] | D, - has(feature: K): boolean, - resolve(feature: K): Features[K], - run(feature: K, ...args: any[]): ReturnType, - runOr(feature: K, defaultValue: D, ...args: any[]): ReturnType | D, - addPipeline(name: string, fn: PipelineFn): void, - plPipe(name: string, initialValue: D, ...args: any[]): Promise, - plEachSeries(name: string, ...args: any[]): Promise, -} - -export interface HostApi extends PluginsApi { - commitsToNotes(commits: Commit[], maybePkg?: Pkg | void): Promise, - releaseTypeByCommits(commits: Commit[], defaultValue?: SemverReleaseType | null): Promise, - releaseType(pkg: Pkg, changedContext: ChangedContext): Promise, - preReleaseHook(vcs: VcsPlatform, releaseContext: ReleaseContext): Promise, - releaseInfoFromReleaseCtx(releaseData: ReleaseData, releaseContext: ReleaseContext): Promise, - releaseInfoFromVcs(releaseData: ReleaseData, vcsRelease: VcsRelease): Promise, - attributeReleaseData(releaseData: ReleaseData, updateState: UpdateState | null): Promise, - notifyScriptsPath(): Promise, -} - -type PluginsContext = { - hostApi: HostApi, - pluginsApi: PluginsApi, - lazyLoadPluginsOnce: () => Promise, -} - -function filterPluginsFromDeps(deps: Record = {}): string[] { - const pluginsToLoad: string[] = [] - - for (const depName of Object.keys(deps)) { - const [, unscopedDepName = ''] = depName.split('/') - if ( - depName.startsWith('pvm-plugin') || - depName.startsWith('@pvm/plugin') || - unscopedDepName.startsWith('pvm-plugin') - ) { - pluginsToLoad.push(depName) - } - } - - return pluginsToLoad -} - -function makePluginsContext(cwd: string): PluginsContext { - const pluginsApi: PluginsApi = Object.assign(new EventEmitter(), { - features, - cwd, - provides(feature: keyof Features, impl: T) { - if (!providers[feature]) { - providers[feature] = impl - } - }, - provideRecord>(ns: string, rec: T) { - for (const [key, val] of Object.entries(rec)) { - const boundVal = typeof val === 'function' ? val.bind(rec) : val - this.provides(`${ns}.${key}`, boundVal) - } - }, - provideClass>(ns: string, cls: T) { - this.provides(ns, cls) - }, - getDefaultImpl(feature) { - return featureDefaults[feature] - }, - getOr(feature, defaultImpl) { - return feature in providers ? providers[feature] : defaultImpl - }, - has(feature): boolean { - return feature in providers - }, - resolve(feature) { - let impl = this.getOr(feature, this.getDefaultImpl(feature)) - if (!impl) { - const [ns, method] = feature.split('.') - const cls = this.getOr(ns, undefined) - if (!cls) { - return - } - - impl = cls[method] - if (!impl) { - return - } - impl = impl.bind(cls) - } - return impl - }, - run(feature, ...args) { - const impl = this.resolve(feature) - - if (impl) { - return impl(...args) - } - - throw new Error(`Feature ${feature} not found`) - }, - runOr(feature, defaultValue, ...args) { - const impl = this.resolve(feature) - if (impl === void 0) { - return defaultValue - } - return impl(...args) - }, - addPipeline(name, fn: PipelineFn) { - pipelines[name] = pipelines[name] || [] - pipelines[name].push(fn) - }, - async plPipe(name, initialValue, ...args) { - const pipelineFns = pipelines[name] || [] - if (pipelineFns.length === 0) { - return initialValue - } - - let currentValue = initialValue - for (const fn of pipelineFns) { - currentValue = await fn(currentValue, ...args) - } - - return currentValue - }, - async plEachSeries(name, ...args) { - const pipelineFns = pipelines[name] || [] - - for (const fn of pipelineFns) { - await fn(...args) - } - }, - }) - - async function loadPlugin(plugin, name: string): Promise { - const config = await getConfig(cwd) - const opts = config.plugins.options[name] - - await plugin(pluginsApi, opts) - log(chalk`plugin {blue ${name}} loaded`) - } - - async function loadPluginByName(name: string, resolveFromPath: string = cwd): Promise { - const plugin = requireDefault(resolveFrom(resolveFromPath, name)) - // todo: will be removed with all the old plugins mechanism - if (typeof plugin === 'function') { - await loadPlugin(plugin, name) - } - } - - async function loadProvidedPlugins(): Promise { - const config = await getConfig(cwd) - const provider = resolvePvmProvider(config.configLookupDir) - if (!provider) { - return - } - const pluginsToLoad = filterPluginsFromDeps(provider.pkg.dependencies) - - return pEachSeries(pluginsToLoad, async (name) => loadPluginByName(name, provider.path)) - } - - async function loadLocalPlugins(): Promise { - const config = await getConfig(cwd) - const { local_plugins = [] } = config.plugins - for (const localPluginPath of local_plugins) { - const resolvedPath = path.resolve(config.configLookupDir, localPluginPath) - const pluginName = localPluginPath.replace(/\.js$/, '') - - await loadPlugin(requireDefault(resolvedPath), pluginName) - } - } - - async function loadPlugins(): Promise { - await loadProvidedPlugins() - await loadLocalPlugins() - await loadPluginsFromDeps() - } - - async function loadPluginsFromDeps(): Promise { - const config = await getConfig(cwd) - - const rootPkgPath = path.join(config.configLookupDir, 'package.json') - let pkg - try { - pkg = requireDefault(rootPkgPath) - } catch (e) { - return - } - - const deps = { - ...(pkg.dependencies || {}), - ...(pkg.devDependencies || {}), - } - - const pluginsToLoad = filterPluginsFromDeps(deps) - - return pEachSeries(pluginsToLoad, async (name) => loadPluginByName(name, config.configLookupDir)) - } - - let pluginsWillBeReady - async function lazyLoadPluginsOnce(): Promise { - if (!pluginsWillBeReady) { - pluginsWillBeReady = loadPlugins() - } - await pluginsWillBeReady - } - - const hostApi: HostApi = Object.assign(Object.create(pluginsApi), { - async commitsToNotes(commits, maybePkg: Pkg | void = void 0) { - const config = await getConfig(cwd) - const filteredCommits = commits.filter(commit => { - return commit.subject.indexOf('[pvm noshow]') === -1 && commit.body.indexOf(releaseMark) === -1 - }) - const releaseNotes = await this.run(features.commitsToNotes, filteredCommits, maybePkg, config) - return this.plPipe('release-notes', releaseNotes) - }, - releaseTypeByCommits(commits: Commit[], defaultValue = null) { - return this.runOr(features.releaseTypeByCommits, defaultValue, commits) - }, - async releaseType(pkg: Pkg, changedContext: ChangedContext): Promise { - return this.runOr(features.releaseType, void 0, pkg, changedContext) - }, - async preReleaseHook(vcs: VcsPlatform, releaseContext: ReleaseContext) { - return this.plEachSeries(features.preReleaseHook, vcs, releaseContext) - }, - async releaseInfoFromReleaseCtx(releaseData: ReleaseData, releaseContext: ReleaseContext): Promise { - logger.deprecate('releaseInfoFromVcs is DEPRECATED. Please use attributeReleaseData method') - return this.attributeReleaseData(releaseData, releaseContext.updateState) - }, - async releaseInfoFromVcs(releaseData: ReleaseData, _not_used: any = void 0): Promise { - logger.deprecate('releaseInfoFromVcs is NOOP. Please use attributeReleaseData method') - return releaseData - }, - async attributeReleaseData(releaseData: ReleaseData, updateState: UpdateState | null): Promise { - return this.plPipe(features.attributeReleaseData, releaseData, updateState) - }, - async notifyScriptsPath(): Promise { - return this.runOr(features.notifyScriptsPath) - }, - }) - - return { - hostApi, - pluginsApi, - lazyLoadPluginsOnce, - } -} - -const pluginsContextLazy = mema(makePluginsContext) - -export async function getHostApi(cwd: string = process.cwd()): Promise { - const context = pluginsContextLazy(cwd) - await context.lazyLoadPluginsOnce() - return context.hostApi -} diff --git a/packages/pvm-core/lib/plugins/provider.ts b/packages/pvm-core/lib/plugins/provider.ts deleted file mode 100644 index d710ae826..000000000 --- a/packages/pvm-core/lib/plugins/provider.ts +++ /dev/null @@ -1,58 +0,0 @@ -import path from 'path' -import fs from 'fs' -import chalk from 'chalk' -import resolveFrom from 'resolve-from' -import { requireDefault } from '../interop' -import { logger } from '../logger' - -export interface PvmProviderInfo { - pkg: Record, - path: string, -} - -const allSeenProviders = new Map() - -export const resolvePvmProvider = (cwd: string): PvmProviderInfo | undefined => { - cwd = fs.realpathSync(cwd) - const rootPkgPath = path.join(cwd, 'package.json') - let pkg - try { - pkg = requireDefault(rootPkgPath) - } catch (e) { - return - } - let seenProviders = allSeenProviders.get(cwd) - if (!seenProviders) { - seenProviders = [] - allSeenProviders.set(cwd, seenProviders) - } - - const deps = { - ...(pkg.dependencies || {}), - ...(pkg.devDependencies || {}), - } - - for (const depName of Object.keys(deps)) { - if (depName.indexOf('pvm') !== -1 && !depName.startsWith('@pvm/plugin') && depName.indexOf('pvm-plugin') === -1) { - const pkgRelativePath = deps[depName].startsWith('file:') ? deps[depName].replace(/^file:/, '') : depName - const depPkgPackagePath = resolveFrom.silent(cwd, `${pkgRelativePath}/package.json`) - if (!depPkgPackagePath) { - continue - } - const depPkg = require(depPkgPackagePath) - - if (depPkg?.pvm?.provider) { - if (seenProviders.indexOf(depName) === -1) { - logger.info(chalk`Load pvm provider {blue ${depName}}`) - seenProviders.push(depName) - allSeenProviders.set(cwd, seenProviders) - } - - return { - pkg: depPkg, - path: path.dirname(depPkgPackagePath), - } - } - } - } -} diff --git a/packages/pvm-core/lib/release-notes.ts b/packages/pvm-core/lib/release-notes.ts deleted file mode 100644 index bc5882429..000000000 --- a/packages/pvm-core/lib/release-notes.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { log } from './logger' -import { getHostApi } from './plugins' -import getCommits from './git/commits' -import { PlatformResult } from './shared' - -import type { Vcs } from '@pvm/vcs/lib' -import type { ReleasePayload } from '@pvm/vcs/types' - -async function prepareReleaseData(cwd: string, targetTag: string, prevRef: string): Promise { - log(`making release for ${targetTag} tag`) - const commits = await getCommits(cwd, prevRef, targetTag) - const hostApi = await getHostApi(cwd) - - log(`generating release notes from commits ${prevRef}..${targetTag}`) - const releaseNotes = await hostApi.commitsToNotes(commits) - - return { - name: targetTag, - description: releaseNotes, - } -} - -async function makeReleaseForTag(vcs: Vcs, tagObject, prevRef: string): Promise { - const releaseData = await prepareReleaseData(vcs.cwd, tagObject.name, prevRef) - - // цель: обновить у существующего тега/релиза description в не зависимости от наличия релиза - await vcs.upsertRelease(tagObject.name, releaseData) - - log(`release notes for ${tagObject.name} have written successfully`) -} - -interface MakeReleaseForTagNameOpts { - skipIfExists?: boolean, -} - -// тег должен существовать -async function makeReleaseForTagName(vcs: Vcs, tagName: string, prevRef: string, opts: MakeReleaseForTagNameOpts = {}): Promise { - const { skipIfExists = false } = opts - const releaseData = await prepareReleaseData(vcs.cwd, tagName, prevRef) - - const [responseCode, maybeRelease] = await vcs.getRelease(tagName) - - if (responseCode === PlatformResult.OK) { - if (!maybeRelease!.description || !skipIfExists) { - await vcs.editRelease(tagName, releaseData) - } else { - log(`release notes for ${tagName} already exists, skipping`) - return - } - } else if (responseCode === PlatformResult.NOT_FOUND) { // тег есть, но нет релиза - await vcs.createRelease(tagName, releaseData) - } else if (responseCode === PlatformResult.NO_SUCH_TAG) { - throw new Error(`Couldn't write release notes for tag "${tagName}". It doesn't exist.`) - } - - log(`release notes for ${tagName} have written successfully`) -} - -export { - prepareReleaseData, - makeReleaseForTag, - makeReleaseForTagName, -} diff --git a/packages/pvm-core/package.json b/packages/pvm-core/package.json deleted file mode 100644 index 23af12cc2..000000000 --- a/packages/pvm-core/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "@pvm/core", - "version": "0.0.0-stub", - "description": "core library for pvm packages", - "main": "lib", - "repository": "git@github.com:Tinkoff/pvm.git", - "author": "Andrey Rublev ", - "license": "Apache-2.0", - "dependencies": { - "@pvm/types": "^0.0.0-stub", - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/plugin-common-plugins": "0.0.0-stub", - "@pvm/suffixes": "0.0.0-stub", - "@iarna/toml": "^2.2.3", - "@hutson/parse-repository-url": "^5.0.0", - "ajv": "^6.12.2", - "chalk": "^4.0.0", - "cli-table": "^0.3.6", - "cosmiconfig": "^6.0.0", - "fast-deep-equal": "^3.1.3", - "fast-glob": "^3.1.1", - "git-log-parser": "^1.2.0", - "js-yaml": "^3.13.1", - "micromatch": "^3.1.10", - "mri": "^1.1.4", - "p-each-series": "^2.1.0", - "resolve-from": "^5.0.0", - "rfc6902": "^4.0.2", - "semver": "^7.3.0", - "signales": "^2.0.5", - "through2": "^4.0.2", - "git-url-parse": "^11.4.4", - "json5": "^2.2.1", - "bin-version-check": "^4.0.0", - "ini": "^1.3.8" - }, - "devDependencies": { - "@pvm/releases": "0.0.0-stub", - "@pvm/update": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub" - } -} diff --git a/packages/pvm-cowners/.npmignore b/packages/pvm-cowners/.npmignore deleted file mode 100644 index e13e0d218..000000000 --- a/packages/pvm-cowners/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -*.ts -!*.d.ts -__tests__ -__snapshots__ diff --git a/packages/pvm-files/README.md b/packages/pvm-files/README.md deleted file mode 100644 index 33173907e..000000000 --- a/packages/pvm-files/README.md +++ /dev/null @@ -1 +0,0 @@ -# @pvm/files diff --git a/packages/pvm-files/cli/pvm-files.ts b/packages/pvm-files/cli/pvm-files.ts deleted file mode 100644 index 713a9cd7f..000000000 --- a/packages/pvm-files/cli/pvm-files.ts +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env node -import chalk from 'chalk' -import { getStrategiesDescriptionList } from '@pvm/pkgset/lib/strategies' -import { parseSubArgs } from '@pvm/core/lib/text/sub-args' -import getFiles from '../lib/files' - -// eslint-disable-next-line node/no-extraneous-import -import type Yargs from 'yargs' - -export const command = 'files' -export const description = 'Output files by glob in the list of packages (packages are choosing by pkgset strategies logic)' -export const builder = (yargs: Yargs.Argv) => { - return yargs - .example('$0 files -f *.stories.js', 'filter files in all packages') - .example('$0 files -f *.js -s changed -S from=v1.2.3', 'Return .js files in packages which have been changed from v1.2.3 to HEAD') - .option('files', { - alias: 'f', - desc: chalk`Glob pattern or array of patterns for result files. Returned files would be filtered by packages collected by passed strategy.`, - demandOption: true, - }) - .option('strategy', { - alias: 's', - desc: chalk`Filtering strategy. Possible strategies are: ${getStrategiesDescriptionList().join('\n\n ')}`, - default: 'all', - }) - .option('absolute', { - desc: 'Return absolute paths to file', - default: true, - type: 'boolean' as const, - }) - .option('S', { - alias: 'strategy-option', - desc: 'Pass option through to the used strategy.', - type: 'array' as const, - default: [], - coerce: parseSubArgs, - }) -} - -export const handler = main - -async function main(argv): Promise { - (await getFiles(argv.files, { ...argv, ...argv.strategyOption })) - .forEach(f => console.log(f)) -} diff --git a/packages/pvm-files/package.json b/packages/pvm-files/package.json deleted file mode 100644 index c6c386280..000000000 --- a/packages/pvm-files/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "@pvm/files", - "version": "0.0.0-stub", - "description": "Возвращает файлы по маске и стратегии", - "main": "lib/files", - "repository": "git@github.com:Tinkoff/pvm.git", - "author": "Andrey Rublev ", - "license": "Apache-2.0", - "dependencies": { - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/core": "0.0.0-stub", - "@pvm/pkgset": "0.0.0-stub", - "chalk": "^4.0.0", - "fast-glob": "^3.1.1", - "yargs": "^16.1.1" - } -} diff --git a/packages/pvm-files/plugin.ts b/packages/pvm-files/plugin.ts deleted file mode 100644 index 62e4918d5..000000000 --- a/packages/pvm-files/plugin.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { declarePlugin, provide } from '@pvm/di' -import { CLI_EXTENSION_TOKEN } from '@pvm/tokens-core' - -import * as command from './cli/pvm-files' - -export default declarePlugin({ - factory: function() { - return { - providers: [ - provide({ - provide: CLI_EXTENSION_TOKEN, - useValue: command, - multi: true, - }), - ], - } - }, -}) diff --git a/packages/pvm-gitlab/.npmignore b/packages/pvm-gitlab/.npmignore deleted file mode 100644 index e13e0d218..000000000 --- a/packages/pvm-gitlab/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -*.ts -!*.d.ts -__tests__ -__snapshots__ diff --git a/packages/pvm-gitlab/lib/api/labels/create.ts b/packages/pvm-gitlab/lib/api/labels/create.ts deleted file mode 100644 index 2c0409e9e..000000000 --- a/packages/pvm-gitlab/lib/api/labels/create.ts +++ /dev/null @@ -1,12 +0,0 @@ -import glapi from '../index' - -// https://docs.gitlab.com/ee/api/labels.html#create-a-new-label - -function createLabel(projectId, label) { - return glapi(`/projects/${encodeURIComponent(projectId)}/labels`, { - method: 'POST', - body: label, - }) -} - -export default createLabel diff --git a/packages/pvm-gitlab/lib/api/labels/labels.ts b/packages/pvm-gitlab/lib/api/labels/labels.ts deleted file mode 100644 index b616ba965..000000000 --- a/packages/pvm-gitlab/lib/api/labels/labels.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { projectPagesGen } from '../pages-gen' - -// https://docs.gitlab.com/ee/api/labels.html#list-labels -function labels(projectId, queryArgs = {}) { - return projectPagesGen(projectId, `/labels`, queryArgs) -} - -export default labels diff --git a/packages/pvm-gitlab/lib/api/mr/get.ts b/packages/pvm-gitlab/lib/api/mr/get.ts deleted file mode 100644 index 1f9bbf83a..000000000 --- a/packages/pvm-gitlab/lib/api/mr/get.ts +++ /dev/null @@ -1,11 +0,0 @@ -import glapi from '../index' -import type { UriSlug } from '../api-helpers' -import { encodeSlug } from '../api-helpers' -import type { MergeRequest } from './types' - -async function getMergeRequest(projectId: UriSlug, mrIid: number): Promise { - const { json } = await glapi(`/projects/${encodeSlug(projectId)}/merge_requests/${mrIid}`) - return json -} - -export default getMergeRequest diff --git a/packages/pvm-gitlab/lib/api/mr/list.ts b/packages/pvm-gitlab/lib/api/mr/list.ts deleted file mode 100644 index 6218c479b..000000000 --- a/packages/pvm-gitlab/lib/api/mr/list.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { projectPagesGen } from '../pages-gen' -import type { MergeRequest } from './types' - -function list(projectId, queryArgs): AsyncIterableIterator { - return projectPagesGen(projectId, `/merge_requests`, queryArgs) -} - -export default list diff --git a/packages/pvm-gitlab/lib/api/mr/notes.ts b/packages/pvm-gitlab/lib/api/mr/notes.ts deleted file mode 100644 index 217a550da..000000000 --- a/packages/pvm-gitlab/lib/api/mr/notes.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { projectPagesGen } from '../pages-gen' - -// https://docs.gitlab.com/ee/api/notes.html#list-all-merge-request-notes -function getNotes(projectId, mrIid, queryArgs = {}) { - return projectPagesGen(projectId, `/merge_requests/${mrIid}/notes`, queryArgs) -} - -export default getNotes diff --git a/packages/pvm-gitlab/lib/api/mr/update.ts b/packages/pvm-gitlab/lib/api/mr/update.ts deleted file mode 100644 index 185a966fa..000000000 --- a/packages/pvm-gitlab/lib/api/mr/update.ts +++ /dev/null @@ -1,10 +0,0 @@ -import glapi from '../index' - -function update(projectId, mrIid, attrs = {}) { - return glapi(`/projects/${encodeURIComponent(projectId)}/merge_requests/${mrIid}`, { - method: 'PUT', - body: attrs, - }) -} - -export default update diff --git a/packages/pvm-gitlab/lib/api/releases/by-releases/alter.ts b/packages/pvm-gitlab/lib/api/releases/by-releases/alter.ts deleted file mode 100644 index 20d36f053..000000000 --- a/packages/pvm-gitlab/lib/api/releases/by-releases/alter.ts +++ /dev/null @@ -1,30 +0,0 @@ -import glapi from '../../index' - -import type { AlterReleaseResult } from '../types' - -// https://docs.gitlab.com/ee/api/releases/index.html#create-a-release -async function createRelease(projectId, data): Promise { - const { json } = await glapi(`/projects/${encodeURIComponent(projectId)}/releases`, { - method: 'POST', - body: data, - }) - - return { - id: json.tag_name, - } -} - -// https://docs.gitlab.com/ee/api/releases/index.html#update-a-release -async function updateRelease(projectId, data): Promise { - const { json } = await glapi(`/projects/${encodeURIComponent(projectId)}/releases/${data.tag_name}`, { - method: 'POST', - body: data, - }) - - return { - id: json.tag_name, - } -} - -export { createRelease as create } -export { updateRelease as update } diff --git a/packages/pvm-gitlab/lib/api/releases/by-releases/list.ts b/packages/pvm-gitlab/lib/api/releases/by-releases/list.ts deleted file mode 100644 index a8ee015a3..000000000 --- a/packages/pvm-gitlab/lib/api/releases/by-releases/list.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { projectPagesGen } from '../../pages-gen' - -// https://docs.gitlab.com/ee/api/releases/index.html#list-releases -function tags(projectId, queryArgs) { - return projectPagesGen(projectId, `/releases`, queryArgs) -} - -export default tags diff --git a/packages/pvm-gitlab/lib/api/releases/by-tags/list.ts b/packages/pvm-gitlab/lib/api/releases/by-tags/list.ts deleted file mode 100644 index 5b16c3605..000000000 --- a/packages/pvm-gitlab/lib/api/releases/by-tags/list.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { releaseTags } from '../../tags/tags' -import reformat from './reformat' - -const hasReleaseDescription = (tag): boolean => { - return !!tag.release && !!tag.release.description -} - -async function * releases(projectId) { - for await (const tag of releaseTags(projectId)) { - if (hasReleaseDescription(tag)) { - yield reformat(tag) - } - } -} - -export default releases diff --git a/packages/pvm-gitlab/lib/api/releases/by-tags/reformat.ts b/packages/pvm-gitlab/lib/api/releases/by-tags/reformat.ts deleted file mode 100644 index c67fc006e..000000000 --- a/packages/pvm-gitlab/lib/api/releases/by-tags/reformat.ts +++ /dev/null @@ -1,18 +0,0 @@ - -function reformat(releaseTag) { - return { - ...releaseTag, - name: releaseTag.name, - tag_name: releaseTag.name, - description: releaseTag.release ? releaseTag.release.description : '', - created_at: releaseTag.commit.created_at, - author: {}, - assets: { - count: 0, - sources: [], - links: [], - }, - } -} - -export default reformat diff --git a/packages/pvm-gitlab/lib/api/releases/impl.ts b/packages/pvm-gitlab/lib/api/releases/impl.ts deleted file mode 100644 index 5f2193642..000000000 --- a/packages/pvm-gitlab/lib/api/releases/impl.ts +++ /dev/null @@ -1,21 +0,0 @@ -// const semver = require('semver') -// const fetchVersion = require('../version') -// -// let glVersion - -/* eslint-disable @typescript-eslint/no-var-requires */ - -async function getImpl(kind) { - const mod = require(`./by-tags/${kind}`) - return mod.default ? mod.default : mod - - // if (!glVersion) { - // glVersion = (await fetchVersion()).version - // } - - // у апи релизов есть проблемы с сортировкой - // на данный момент проще использовать tags api все равно никаких данных из releases api pvm не использует - // return semver.gte(semver.coerce(glVersion).version, '11.7.0') ? require(`./by-releases/${kind}`) : require(`./by-tags/${kind}`) -} - -export default getImpl diff --git a/packages/pvm-gitlab/lib/api/tags/create.ts b/packages/pvm-gitlab/lib/api/tags/create.ts deleted file mode 100644 index 2275e429c..000000000 --- a/packages/pvm-gitlab/lib/api/tags/create.ts +++ /dev/null @@ -1,11 +0,0 @@ -import glapi from '../index' - -// https://docs.gitlab.com/ee/api/tags.html#create-a-new-tag -function createTag(projectId, data) { - return glapi(`/projects/${encodeURIComponent(projectId)}/repository/tags`, { - method: 'POST', - body: data, - }) -} - -export default createTag diff --git a/packages/pvm-gitlab/lib/api/tags/tags.ts b/packages/pvm-gitlab/lib/api/tags/tags.ts deleted file mode 100644 index 46a15e176..000000000 --- a/packages/pvm-gitlab/lib/api/tags/tags.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { projectPagesGen } from '../pages-gen' -import { releaseTagPrefix, releaseTagFilter } from '@pvm/core/lib/tag-meta' -import type { HttpReqOptions } from '@pvm/core/lib/httpreq' -import { getConfig } from '@pvm/core/lib/config' - -// https://docs.gitlab.com/ee/api/tags.html#list-project-repository-tags -async function * tags(projectId, queryArgs, fetchOpts: HttpReqOptions = {}) { - yield * projectPagesGen(projectId, `/repository/tags`, queryArgs, fetchOpts) -} - -async function * releaseTags(projectId, fetchOpts: HttpReqOptions = {}) { - const config = await getConfig() - const tagPrefix = releaseTagPrefix(config) - // @TODO: isReleaseTag логику надо вынести выше, чтобы работало на всех типах vcs - const isReleaseTag = releaseTagFilter(config) - - const queryArgs = { - search: tagPrefix, - } - for await (const tag of tags(projectId, queryArgs, fetchOpts)) { - if (isReleaseTag(tag.name)) { - yield tag - } - } -} - -export default tags -export { - releaseTags, -} diff --git a/packages/pvm-gitlab/lib/api/version.ts b/packages/pvm-gitlab/lib/api/version.ts deleted file mode 100644 index 6ea8761e4..000000000 --- a/packages/pvm-gitlab/lib/api/version.ts +++ /dev/null @@ -1,8 +0,0 @@ -import glapi from './index' - -async function version() { - const { json } = await glapi('/version') - return json -} - -export default version diff --git a/packages/pvm-gitlab/plugin.ts b/packages/pvm-gitlab/plugin.ts deleted file mode 100644 index afba44b9d..000000000 --- a/packages/pvm-gitlab/plugin.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { CONFIG_TOKEN, PLATFORM_TOKEN } from '@pvm/tokens-core' -import { declarePlugin, provide } from '@pvm/di' -import { GitlabPlatform } from './platform' - -export default declarePlugin({ - factory: function() { - return { - providers: [ - provide({ - provide: PLATFORM_TOKEN, - useClass: GitlabPlatform, - deps: { - config: CONFIG_TOKEN, - }, - }), - ], - } - }, -}) diff --git a/packages/pvm-mattermost/.npmignore b/packages/pvm-mattermost/.npmignore deleted file mode 100644 index e13e0d218..000000000 --- a/packages/pvm-mattermost/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -*.ts -!*.d.ts -__tests__ -__snapshots__ diff --git a/packages/pvm-notifications/.npmignore b/packages/pvm-notifications/.npmignore deleted file mode 100644 index e13e0d218..000000000 --- a/packages/pvm-notifications/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -*.ts -!*.d.ts -__tests__ -__snapshots__ diff --git a/packages/pvm-notifications/README.md b/packages/pvm-notifications/README.md deleted file mode 100644 index 46f2a7be3..000000000 --- a/packages/pvm-notifications/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# @pvm/notifications - -Module used to send messages into specified messengers - -## [Configuration](../interfaces/pvm_core.Config.md#notifications) - -Configuration [defaults](../interfaces/pvm_core.Config.md#notifications) provide values -that will be used as defaults for message when `sendMessage` called. - -## Node API - -Main api entry point is [Notificator](../classes/pvm_notifications.Notificator) class. It's interface -public methods are appear to be public api. - -Example -```typescript -import { Notificator } from '@pvm/notifications' - -async function send(channel: string, content: string) { - const notificator = await Notificator.create() - notificator.sendMessage({ - channel, - content - }) -} -``` - -## CLI -``` -@cli-inline yarn pvm notification --help -``` - -### `pvm notification send` -``` -@cli-inline yarn pvm notification send --help -``` - diff --git a/packages/pvm-notifications/cli/commands/pvm-notification-send.ts b/packages/pvm-notifications/cli/commands/pvm-notification-send.ts deleted file mode 100644 index 4dfe436b7..000000000 --- a/packages/pvm-notifications/cli/commands/pvm-notification-send.ts +++ /dev/null @@ -1,66 +0,0 @@ -import fs from 'fs' -import getStdin from 'get-stdin' - -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' -import type { Message } from '@pvm/types' -import { Notificator } from '../../lib' - -export const command = 'send' -export const description = 'Send message to configured messengers' -export const builder = (yargs: Argv) => { - return yargs - .example( - `$0 notification send -m message.json`, - `Send message to messengers according to pvm configuration` - ) - .option('target', { - alias: 't', - type: 'array', - desc: 'target messenger or list of them. Possible values are: all, first-available and concrete messenger name', - }) - .option('file', { - alias: 'f', - desc: 'message json file. Available fields described in doc https://tinkoff.github.io/pvm/docs/api/modules/pvm_types#message', - }) - .option('channel', { - alias: 'c', - desc: 'channel where to send message', - }) - .option('message', { - alias: 'm', - desc: 'text for sending. Use "-" for reading from stdin. Default: "-" if there is no message nor text passed.', - }) -} -export const handler = send - -async function send(flags): Promise { - const contentParam = (!flags.file && !flags.message) ? '-' : flags.message - - let content - if (contentParam) { - content = contentParam === '-' ? await getStdin() : contentParam - } - - let messageBuild: { channel?: string, content?: string } = {} - if (flags.file) { - const messageStr = fs.readFileSync(flags.file).toString('utf8') - messageBuild = JSON.parse(messageStr) - } - - if (flags.channel) { - messageBuild.channel = flags.channel - } - - if (content) { - messageBuild.content = content - } - - const message: Message = messageBuild as Message - - const messenger = await Notificator.create() - - return messenger.sendMessage(message, { - target: flags.target ? flags.target.length === 1 ? flags.target[0] : flags.target : undefined, - }) -} diff --git a/packages/pvm-notifications/cli/pvm-notification.ts b/packages/pvm-notifications/cli/pvm-notification.ts deleted file mode 100644 index 7bd45a5a3..000000000 --- a/packages/pvm-notifications/cli/pvm-notification.ts +++ /dev/null @@ -1,12 +0,0 @@ -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' - -export const command = 'notification ' -export const description = 'Send messages to messenger(s)' -export const builder = (yargs: Argv) => { - return yargs - .commandDir('commands') - .demandCommand() - .help('--help') -} -export const handler = () => {} diff --git a/packages/pvm-notifications/package.json b/packages/pvm-notifications/package.json deleted file mode 100644 index 86edca8db..000000000 --- a/packages/pvm-notifications/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "@pvm/notifications", - "version": "0.0.0-stub", - "description": "Cli and api utilities for sending messages", - "main": "./lib", - "repository": "git@github.com:Tinkoff/pvm.git", - "author": "Mikhail Shipov ", - "license": "Apache-2.0", - "dependencies": { - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/core": "^0.0.0-stub", - "@pvm/types": "^0.0.0-stub", - "get-stdin": "^7.0.0", - "resolve-from": "^5.0.0", - "lodash.defaultsdeep": "4.6.1", - "yargs": "^16.1.1" - } -} diff --git a/packages/pvm-notifications/plugin.ts b/packages/pvm-notifications/plugin.ts deleted file mode 100644 index 987d3623c..000000000 --- a/packages/pvm-notifications/plugin.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { declarePlugin, provide } from '@pvm/di' -import { CLI_EXTENSION_TOKEN } from '@pvm/tokens-core' - -import * as command from './cli/pvm-notification' - -export default declarePlugin({ - factory: function() { - return { - providers: [ - provide({ - provide: CLI_EXTENSION_TOKEN, - useValue: command, - multi: true, - }), - ], - } - }, -}) diff --git a/packages/pvm-pkgset/.npmignore b/packages/pvm-pkgset/.npmignore deleted file mode 100644 index e13e0d218..000000000 --- a/packages/pvm-pkgset/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -*.ts -!*.d.ts -__tests__ -__snapshots__ diff --git a/packages/pvm-pkgset/README.md b/packages/pvm-pkgset/README.md deleted file mode 100644 index e7b5406bc..000000000 --- a/packages/pvm-pkgset/README.md +++ /dev/null @@ -1 +0,0 @@ -# @pvm/pkgset diff --git a/packages/pvm-pkgset/cli/pvm-pkgset.ts b/packages/pvm-pkgset/cli/pvm-pkgset.ts deleted file mode 100755 index 75f9fafc7..000000000 --- a/packages/pvm-pkgset/cli/pvm-pkgset.ts +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env node -import chalk from 'chalk' -import pprint from '../lib/pprint' -import { pkgsetFromFlags } from '../lib/pkgset' -import { getStrategiesDescriptionList } from '../lib/strategies' - -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' - -export const command = 'pkgset' -export const description = 'Shows the list of packages by the specified criterion (low-level version)' -export const builder = (yargs: Argv) => { - return yargs - .example('$0 pkgset', 'filter packages in workspaces and print "@" for each package') - .example('pvm pkgset -f %n -s changed -S from=v1.2.3', 'Print packages names which have been change from v1.2.3 to HEAD') - .option('strategy', { - desc: chalk`Filtering strategy. Possible strategies are: ${getStrategiesDescriptionList().join('\n\n ')}`, - default: 'all', - alias: 's', - }) - .option('S', { - alias: 'strategy-option', - desc: 'Pass option through to the used strategy.', - type: 'array' as const, - default: [], - }) - .option('format', { - desc: `Pretty-print the package information in a given format. Format is string, with special symbols: - %p - path to package - %n - package name - %s - package name without namespace if it's present - %v - package version - `, - default: '%n@%v', - alias: 'f', - }) -} - -export const handler = main - -async function main(flags): Promise { - for await (const line of pprint(pkgsetFromFlags(flags), flags.format)) { - console.log(line) - } -} diff --git a/packages/pvm-pkgset/lib/pkgset.ts b/packages/pvm-pkgset/lib/pkgset.ts deleted file mode 100644 index 3b7caf0a7..000000000 --- a/packages/pvm-pkgset/lib/pkgset.ts +++ /dev/null @@ -1,24 +0,0 @@ -import strategies from './strategies' -import type { Pkg } from '@pvm/core/lib/pkg' -import { parseSubArgs } from '@pvm/core/lib/text/sub-args' - -function pkgset(strategy: string, opts: Record = {}): AsyncIterable { - const strategyFn = strategies[strategy] - if (typeof strategyFn !== 'function') { - throw new Error(`no such strategy ${strategy}`) - } - - return strategyFn(opts) -} - -async function * pkgsetFromFlags(flags: { - strategy: string, - strategyOption: string[], -}): AsyncIterableIterator { - yield * pkgset(flags.strategy, parseSubArgs(flags.strategyOption)) -} - -export { - pkgset, - pkgsetFromFlags, -} diff --git a/packages/pvm-pkgset/package.json b/packages/pvm-pkgset/package.json deleted file mode 100644 index bae682741..000000000 --- a/packages/pvm-pkgset/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "@pvm/pkgset", - "version": "0.0.0-stub", - "description": "Список пакетов по тем или иным условиям", - "main": "lib/pkgset", - "repository": "git@github.com:Tinkoff/pvm.git", - "author": "Andrey Rublev ", - "license": "Apache-2.0", - "dependencies": { - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/core": "0.0.0-stub", - "@pvm/types": "0.0.0-stub", - "@pvm/repository": "0.0.0-stub", - "chalk": "^4.0.0", - "micromatch": "^3.1.10", - "semver": "^7.3.0", - "fast-glob": "^3.1.1", - "yargs": "^16.1.1" - } -} diff --git a/packages/pvm-pkgset/plugin.ts b/packages/pvm-pkgset/plugin.ts deleted file mode 100644 index 0f5e7d733..000000000 --- a/packages/pvm-pkgset/plugin.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { declarePlugin, provide } from '@pvm/di' -import { CLI_EXTENSION_TOKEN } from '@pvm/tokens-core' - -import * as command from './cli/pvm-pkgset' - -export default declarePlugin({ - factory: function() { - return { - providers: [ - provide({ - provide: CLI_EXTENSION_TOKEN, - useValue: command, - multi: true, - }), - ], - } - }, -}) diff --git a/packages/pvm-plugin-conventional-changelog/.npmignore b/packages/pvm-plugin-conventional-changelog/.npmignore deleted file mode 100644 index e13e0d218..000000000 --- a/packages/pvm-plugin-conventional-changelog/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -*.ts -!*.d.ts -__tests__ -__snapshots__ diff --git a/packages/pvm-plugin-conventional-changelog/lib/index.ts b/packages/pvm-plugin-conventional-changelog/lib/index.ts deleted file mode 100644 index 3c2286b2c..000000000 --- a/packages/pvm-plugin-conventional-changelog/lib/index.ts +++ /dev/null @@ -1,178 +0,0 @@ -import path from 'path' -import conventionalCommitsFilter from 'conventional-commits-filter' -import conventionalChangelogPresetLoader from 'conventional-changelog-preset-loader' -import conventionalChangelogWriter from 'conventional-changelog-writer' -import mergeConfig from 'conventional-changelog-core/lib/merge-config' -import streamFromArray from 'stream-from-array' -import through from 'through2' -import resolvePreset from './preset-resolver' -import { parseCommit } from './common' -import type { Commit } from 'conventional-commits-parser' -import type { PluginsApi } from '@pvm/core/lib/plugins' - -export enum conventionalChangelogReleaseTypes {'major', 'minor', 'patch'} - -function parseCommits(commits, parserOpts): Array> { - return commits.map(commit => { - const rawData = `${commit.subject}\n${commit.body}` - const parsed = parseCommit(rawData, parserOpts) - - if ('commit' in commit && commit.commit.long) { - parsed.hash = commit.commit.long - } - - return parsed - }) -} - -const commitsCache = new Map() - -function parseCommitsWithCache(commits, parserOpts): ReturnType { - if (commitsCache.has(commits)) { - return commitsCache.get(commits) - } - const parsed = parseCommits(commits, parserOpts) - commitsCache.set(commits, parsed) - return parsed -} - -/** - * Options that allowed to pass to plugin via config file - * - * Example - * ```javascript - * module.exports = { - * plugins: { - * options: { - * '@pvm/plugin-conventional-changelog': { - * ignoreReverted: false - * }, - * }, - * } - * } - * ``` - */ -export type PluginOpts = { - ignoreReverted?: boolean, - preset?: string, - config?: any, - /** - * Allow to customize release type choose behaviour - * - * .pvm.js example in which we disable version bump if all commits are of type 'chore' - * ```javascript - * module.exports = { - * update { - * default_release_type: 'none' - * }, - * plugins: { - * options: { - * '@pvm/plugin-conventional-changelog': { - * whatBump: (commits) => { - * return commits.every(c => c.type === 'chore') ? null : { level: 2 } - * }, - * }, - * }, - * } - * } - * ``` - * @param commits - */ - whatBump?: (commits: Array) => null | { level: conventionalChangelogReleaseTypes }, -} - -async function plugin(api: PluginsApi, opts: PluginOpts = {}): Promise { - const { - ignoreReverted = true, - preset: passedPreset, - config: passedConfig, - } = opts - - let presetPkg - const preset = !passedPreset && !passedConfig ? require.resolve('./preset') : passedPreset - if (preset) { - try { - presetPkg = conventionalChangelogPresetLoader(preset) - } catch (err) { - throw new Error(`Error loading "${preset}" conventional-changelog preset. Is it installed ?`) - } - } - - const config = await resolvePreset(presetPkg || passedConfig) || {} - opts.config = config - const mergedConfig = await mergeConfig(opts) - - const { recommendedBumpOpts = {} } = config - const { parserOpts: recommendedParserOpts } = recommendedBumpOpts - - const parserOpts = { - ...recommendedParserOpts, - ...mergedConfig.parserOpts, - } - - let releaseTypeBuilder - - api.provides(api.features.releaseTypeByCommits, gitCommits => { - let commits = parseCommitsWithCache(gitCommits, parserOpts) - if (ignoreReverted) { - commits = conventionalCommitsFilter(commits) - } - - releaseTypeBuilder = releaseTypeBuilder ?? (api.has(api.features.releaseTypeBuilder) ? api.run(api.features.releaseTypeBuilder) : false) - // для кастомного whatBump и билдера от плагинов мы ожидаем возвращаемого значения в формате строки releaseType или 'none' - const customWhatBump = opts.whatBump || releaseTypeBuilder - if (customWhatBump) { - return customWhatBump(commits) - } - - // recommendedBumpOpts.whatBump возвращает тип релиза в формате { result: { level: 0 | 1 | 2 } } - if (recommendedBumpOpts.whatBump) { - const result = recommendedBumpOpts.whatBump(commits) - if (result && result.level !== null) { - return conventionalChangelogReleaseTypes[result.level] - } - } - }) - - api.provides(api.features.commitsToNotes, (commits) => { - const commitsStream = streamFromArray.obj(parseCommitsWithCache(commits, parserOpts)) - const { writerOpts } = mergedConfig - writerOpts.includeDetails = false - - /* - Если репозиторий не-монорепа, то формат тегов - vX.X.X и это включает альтернативную логику включения вывода лога - Логика включения этого флага зашита в https://github.com/conventional-changelog/conventional-changelog/blob/8076d4666c2a3ea728b95bf1e4e78d4c7189b1dc/packages/conventional-changelog-core/lib/merge-config.js#L196. Логика включения коммита в - лог находится тут https://github.com/conventional-changelog/conventional-changelog/blob/8076d4666c2a3ea728b95bf1e4e78d4c7189b1dc/packages/conventional-changelog-writer/index.js#L147 - и видно, что если doFlush в false, то вывод лога регулируется наличием и валидностью version в объекте commit'а и - тут есть проблемы: - 1. Код, который проставляет версию в коммит находится в секции conventional-commit-changelog'а которая вызывается - только при генерации чейнджлога через него - 2. Pvm ставит версию в тег после генерации чейнджлога - 3. Pvm формирует релиз из всех коммитов с последнего релиза и ситуация когда может быть несколько секций в релизе - невозможна - */ - writerOpts.doFlush = true - - return new Promise((resolve, reject) => { - let result = '' - - const concatStream = through((chunk, _enc, cb) => { - result += chunk - cb() - }, cb => { - resolve(result) - cb() - }) - - commitsStream - .pipe(conventionalChangelogWriter(mergedConfig.context, writerOpts)) - .on('error', e => { - reject(e) - }) - .pipe(concatStream) - }) - }) - - api.provides(api.features.notifyScriptsPath, () => Promise.resolve(path.join(__dirname, 'notify-scripts'))) -} - -export default plugin diff --git a/packages/pvm-plugin-conventional-changelog/lib/notify-scripts/release-with-packages.ts b/packages/pvm-plugin-conventional-changelog/lib/notify-scripts/release-with-packages.ts deleted file mode 100644 index 22204583a..000000000 --- a/packages/pvm-plugin-conventional-changelog/lib/notify-scripts/release-with-packages.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { ReleasedProps, Message } from '@pvm/types' - -import { releaseMessage } from '../message-builder' - -process.on('message', async (releaseProps: ReleasedProps) => { - const message: Message = await releaseMessage(releaseProps, { - attachPackages: true, - }) - - process.send!({ - type: 'message', - message, - }) - - process.exit(0) -}) diff --git a/packages/pvm-plugin-conventional-changelog/lib/notify-scripts/release.ts b/packages/pvm-plugin-conventional-changelog/lib/notify-scripts/release.ts deleted file mode 100644 index 036d8c463..000000000 --- a/packages/pvm-plugin-conventional-changelog/lib/notify-scripts/release.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { ReleasedProps, Message } from '@pvm/types' - -import { releaseMessage } from '../message-builder' - -process.on('message', async (releaseProps: ReleasedProps) => { - const message: Message = await releaseMessage(releaseProps, { - attachPackages: false, - }) - - process.send!({ - type: 'message', - message, - }) - - process.exit(0) -}) diff --git a/packages/pvm-plugin-conventional-semantic-release/lib/index.ts b/packages/pvm-plugin-conventional-semantic-release/lib/index.ts deleted file mode 100644 index 3b1a046d1..000000000 --- a/packages/pvm-plugin-conventional-semantic-release/lib/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { Commit } from 'conventional-commits-parser' -import type { PvmReleaseType } from '@pvm/types' -import { analyzeCommits } from './analyze-commits' -import type { PluginsApi } from '@pvm/core/lib/plugins/index' -import type { Options } from './types' - -export default function plugin(api: PluginsApi, opts: Options = {}): void { - api.provides(api.features.releaseTypeBuilder, () => { - return function releaseTypeBuilder(commits: Commit[]): PvmReleaseType { - return analyzeCommits(commits, opts) - } - }) -} diff --git a/packages/pvm-plugin-http-proxy/.npmignore b/packages/pvm-plugin-http-proxy/.npmignore deleted file mode 100644 index e13e0d218..000000000 --- a/packages/pvm-plugin-http-proxy/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -*.ts -!*.d.ts -__tests__ -__snapshots__ diff --git a/packages/pvm-plugin-http-proxy/lib/index.ts b/packages/pvm-plugin-http-proxy/lib/index.ts deleted file mode 100644 index fc578a8e8..000000000 --- a/packages/pvm-plugin-http-proxy/lib/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { bootstrap } from 'global-agent' - -async function plugin(_api): Promise { - bootstrap({ - environmentVariableNamespace: '', - }) -} - -export default plugin diff --git a/packages/pvm-releases/.npmignore b/packages/pvm-releases/.npmignore deleted file mode 100644 index e13e0d218..000000000 --- a/packages/pvm-releases/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -*.ts -!*.d.ts -__tests__ -__snapshots__ diff --git a/packages/pvm-releases/README.md b/packages/pvm-releases/README.md deleted file mode 100644 index d58d75d7f..000000000 --- a/packages/pvm-releases/README.md +++ /dev/null @@ -1 +0,0 @@ -# @pvm/releases diff --git a/packages/pvm-releases/cli/pvm-releases-download.ts b/packages/pvm-releases/cli/pvm-releases-download.ts deleted file mode 100644 index fdc87e684..000000000 --- a/packages/pvm-releases/cli/pvm-releases-download.ts +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env node - -import { download, ArtifactsStorages } from '@pvm/artifacts/pub/artifacts' - -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' - -export const command = 'download' -export const description = 'Download ReleaseList artifact from remote storage' -export const builder = (yargs: Argv) => { - return yargs - .option('quiet', { - desc: `Don't print warnings`, - type: 'boolean' as const, - default: false, - }) - .option('force', { - desc: `Download an artifact even if it is not turned on`, - type: 'boolean' as const, - default: false, - }) -} - -export const handler = main - -async function main(args: Record): Promise { - await download({ - force: args.force, - quiet: args.quiet, - kind: ArtifactsStorages.ReleaseList, - }) -} diff --git a/packages/pvm-releases/cli/pvm-releases-make.ts b/packages/pvm-releases/cli/pvm-releases-make.ts deleted file mode 100644 index 271f8a5b8..000000000 --- a/packages/pvm-releases/cli/pvm-releases-make.ts +++ /dev/null @@ -1,75 +0,0 @@ -import path from 'path' -import { logger } from '@pvm/core/lib/logger' -import { getConfig } from '@pvm/core/lib/config' -import { makeReleasesFromWorkingTree } from '../lib/producers/releases-by-working-tree' -import { releaseDataMaker } from '../lib/release-data' -import { reduceReleaseList } from '../lib/release-list' -import { getUpdateState } from '@pvm/update/lib' -import { createReleaseContext } from '@pvm/update/lib/release/release-context' - -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' - -export const command = 'make' -export const description = 'Make ReleaseList artifact from git working tree' -export const builder = (yargs: Argv) => { - return yargs - .option('start-from', { - desc: 'Git reference from wich start iteration', - type: 'string' as const, - default: 'HEAD', - }) - .option('stop-at', { - desc: 'Git reference at which to stop iteration', - type: 'string' as const, - }) - .option('append-upcoming-release', { - desc: `Generate ReleasedData based on unreleased changes and append it to ReleaseList`, - type: 'boolean' as const, - default: false, - }) - .option('limit', { - desc: 'limit ReleaseList artefact according to configuration', - type: 'boolean' as const, - default: true, - }) -} - -export const handler = main - -async function main(flags: Record): Promise { - const fs = require('fs') - const cwd = process.cwd() - const config = await getConfig(cwd) - - let releaseList = await makeReleasesFromWorkingTree(cwd, { - stopAtRef: flags.stopAt, - startFrom: flags.startFrom, - }) - - if (flags.appendUpcomingRelease) { - const updateState = await getUpdateState({ - includeUncommited: true, - }) - - const releaseContext = await createReleaseContext(updateState) - if (releaseContext) { - const releaseData = await releaseDataMaker.fromReleaseContext(releaseContext) - - if (releaseData) { - releaseList.unshift(releaseData) - } - } - } - - if (flags.limit) { - logger.info('Limit ReleaseList according to corresponding configuration') - releaseList = reduceReleaseList(config, releaseList) - } - - logger.info(`Produced ${releaseList.length} releases`) - - const outputPath = path.join(cwd, config.release_list.path) - fs.writeFileSync(outputPath, JSON.stringify(releaseList)) - logger.info(`Release list saved to "${config.release_list.path}"`) -} diff --git a/packages/pvm-releases/cli/pvm-releases-probe.ts b/packages/pvm-releases/cli/pvm-releases-probe.ts deleted file mode 100644 index c870ce5b9..000000000 --- a/packages/pvm-releases/cli/pvm-releases-probe.ts +++ /dev/null @@ -1,46 +0,0 @@ -import path from 'path' -import { logger } from '@pvm/core/lib/logger' -import { releaseDataMaker } from '../lib/release-data' -import { getUpdateState } from '@pvm/update/lib' -import { createReleaseContext } from '@pvm/update/lib/release/release-context' - -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' - -export const command = 'probe' -export const description = 'Create ReleaseData artefact based on unreleased changes' -export const builder = (yargs: Argv) => { - return yargs - .option('output-path', { - desc: 'Output path for ReleaseData artefact', - type: 'string' as const, - default: 'releaseData.json', - }) -} - -export const handler = main - -async function main(flags: Record): Promise { - const fs = require('fs') - const cwd = process.cwd() - - const updateState = await getUpdateState({ - includeUncommited: true, - }) - - const releaseContext = await createReleaseContext(updateState) - if (releaseContext) { - const releaseData = await releaseDataMaker.fromReleaseContext(releaseContext, { - allowWithoutCommits: true, - emptyReleaseNotes: 'Uncommited changes', - }) - - if (releaseData) { - const outputPath = path.resolve(cwd, flags.outputPath) - fs.writeFileSync(outputPath, JSON.stringify(releaseData)) - logger.info(`ReleaseData saved to "${flags.outputPath}"`) - } else { - logger.info(`ReleaseData has not been created`) - } - } -} diff --git a/packages/pvm-releases/cli/pvm-releases-upload.ts b/packages/pvm-releases/cli/pvm-releases-upload.ts deleted file mode 100644 index 4bcb10098..000000000 --- a/packages/pvm-releases/cli/pvm-releases-upload.ts +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env node - -import { upload, ArtifactsStorages } from '@pvm/artifacts/pub/artifacts' - -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' - -export const command = 'upload' -export const description = 'Upload ReleaseList artifact to remote storage' -export const builder = (yargs: Argv) => { - return yargs - .option('quiet', { - desc: `Don't print warnings`, - type: 'boolean' as const, - default: false, - }) - .option('force', { - desc: `Upload an artifact even if it is not turned on`, - type: 'boolean' as const, - default: false, - }) -} - -export const handler = main - -async function main(args: Record): Promise { - await upload({ - force: args.force, - quiet: args.quiet, - kind: ArtifactsStorages.ReleaseList, - }) -} diff --git a/packages/pvm-releases/cli/pvm-releases.ts b/packages/pvm-releases/cli/pvm-releases.ts deleted file mode 100644 index 8e55bee5e..000000000 --- a/packages/pvm-releases/cli/pvm-releases.ts +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env node - -import * as pvmReleasesMake from './pvm-releases-make' -import * as pvmReleasesDownload from './pvm-releases-download' -import * as pvmReleasesUpload from './pvm-releases-upload' -import * as pvmReleasesProbe from './pvm-releases-probe' -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' - -export const command = 'releases ' -export const description = 'Commands for working with ReleaseList artifact' -export const builder = (yargs: Argv) => { - return yargs - .command(pvmReleasesMake) - .command(pvmReleasesDownload) - .command(pvmReleasesUpload) - .command(pvmReleasesProbe) -} - -export const handler = function() {} diff --git a/packages/pvm-releases/package.json b/packages/pvm-releases/package.json deleted file mode 100644 index 1a0f86dfe..000000000 --- a/packages/pvm-releases/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "@pvm/releases", - "version": "0.0.0-stub", - "description": "releases utilites", - "main": "lib/index.js", - "repository": "git@github.com:Tinkoff/pvm.git", - "author": "Andrey Rublev ", - "license": "Apache-2.0", - "dependencies": { - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/artifacts": "0.0.0-stub", - "@pvm/core": "0.0.0-stub", - "@pvm/pkgset": "0.0.0-stub", - "@pvm/update": "0.0.0-stub", - "bytes": "^3.1.0", - "ms": "^2.1.3", - "yargs": "^16.1.1" - }, - "devDependencies": { - "@types/bytes": "^3.1.0", - "@types/ms": "^0.7.31" - } -} diff --git a/packages/pvm-releases/plugin.ts b/packages/pvm-releases/plugin.ts deleted file mode 100644 index 8067a2a0c..000000000 --- a/packages/pvm-releases/plugin.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { declarePlugin, provide } from '@pvm/di' -import { CLI_EXTENSION_TOKEN } from '@pvm/tokens-core' - -import * as command from './cli/pvm-releases' - -export default declarePlugin({ - factory: function() { - return { - providers: [ - provide({ - provide: CLI_EXTENSION_TOKEN, - useValue: command, - multi: true, - }), - ], - } - }, -}) diff --git a/packages/pvm-repository/.npmignore b/packages/pvm-repository/.npmignore deleted file mode 100644 index e13e0d218..000000000 --- a/packages/pvm-repository/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -*.ts -!*.d.ts -__tests__ -__snapshots__ diff --git a/packages/pvm-repository/README.md b/packages/pvm-repository/README.md deleted file mode 100644 index b7693de47..000000000 --- a/packages/pvm-repository/README.md +++ /dev/null @@ -1 +0,0 @@ -# @pvm/repository diff --git a/packages/pvm-repository/package.json b/packages/pvm-repository/package.json deleted file mode 100644 index 11d4a59e4..000000000 --- a/packages/pvm-repository/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "@pvm/repository", - "version": "0.0.0-stub", - "description": "Featured, powerful and compliant package version/release manager", - "main": "lib/index.js", - "repository": "git@github.com:Tinkoff/pvm.git", - "author": "Andrey Rublev ", - "license": "Apache-2.0", - "dependencies": { - "@pvm/core": "0.0.0-stub", - "@pvm/types": "0.0.0-stub", - "@pvm/pkgset": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", - "semver": "^7.3.0" - } -} \ No newline at end of file diff --git a/packages/pvm-slack/.npmignore b/packages/pvm-slack/.npmignore deleted file mode 100644 index e13e0d218..000000000 --- a/packages/pvm-slack/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -*.ts -!*.d.ts -__tests__ -__snapshots__ diff --git a/packages/pvm-slack/lib/index.ts b/packages/pvm-slack/lib/index.ts deleted file mode 100644 index 817993dbc..000000000 --- a/packages/pvm-slack/lib/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './api' -export * from './messaging' -export { SlackClient as MessengerClient } from './client' diff --git a/packages/pvm-suffixes/.npmignore b/packages/pvm-suffixes/.npmignore deleted file mode 100644 index e13e0d218..000000000 --- a/packages/pvm-suffixes/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -*.ts -!*.d.ts -__tests__ -__snapshots__ diff --git a/packages/pvm-suffixes/README.md b/packages/pvm-suffixes/README.md deleted file mode 100644 index 9a5da74ef..000000000 --- a/packages/pvm-suffixes/README.md +++ /dev/null @@ -1 +0,0 @@ -# @pvm/suffixes diff --git a/packages/pvm-suffixes/package.json b/packages/pvm-suffixes/package.json deleted file mode 100644 index 210d6cbab..000000000 --- a/packages/pvm-suffixes/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "@pvm/suffixes", - "version": "0.0.0-stub", - "description": "Default list of release suffixes", - "main": "lib", - "repository": "git@github.com:Tinkoff/pvm.git", - "author": "Diokuz ", - "license": "Apache-2.0", - "dependencies": { - "superheroes": "^3.0.0" - } -} diff --git a/packages/pvm-template/.npmignore b/packages/pvm-template/.npmignore deleted file mode 100644 index e13e0d218..000000000 --- a/packages/pvm-template/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -*.ts -!*.d.ts -__tests__ -__snapshots__ diff --git a/packages/pvm-template/README.md b/packages/pvm-template/README.md deleted file mode 100644 index 14f27380b..000000000 --- a/packages/pvm-template/README.md +++ /dev/null @@ -1 +0,0 @@ -# @pvm/template diff --git a/packages/pvm-template/lib/index.ts b/packages/pvm-template/lib/index.ts deleted file mode 100644 index 765f17411..000000000 --- a/packages/pvm-template/lib/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { mema } from '@pvm/core/lib/memoize' -import getTemplateEnv from './env' -import { compile } from 'nunjucks' - -export const lazyCompileTemplate = mema(async (text: string) => { - const templateEnv = await getTemplateEnv() - return compile(text, templateEnv) -}) diff --git a/packages/pvm-template/package.json b/packages/pvm-template/package.json deleted file mode 100644 index 10223fd65..000000000 --- a/packages/pvm-template/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "@pvm/template", - "version": "0.0.0-stub", - "description": "Шаблонизация через nunjucks", - "main": "lib/env.js", - "repository": "git@github.com:Tinkoff/pvm.git", - "author": "Andrey Rublev ", - "license": "Apache-2.0", - "dependencies": { - "@pvm/core": "0.0.0-stub", - "nunjucks": "^3.2.0", - "resolve-from": "^5.0.0", - "chokidar": "^3.3.0" - } -} \ No newline at end of file diff --git a/packages/pvm-types/README.md b/packages/pvm-types/README.md deleted file mode 100644 index 58f67cc36..000000000 --- a/packages/pvm-types/README.md +++ /dev/null @@ -1 +0,0 @@ -# @pvm/types diff --git a/packages/pvm-types/lib/helpers.ts b/packages/pvm-types/lib/helpers.ts deleted file mode 100644 index dfaa89bbe..000000000 --- a/packages/pvm-types/lib/helpers.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type RecursivePartial = { - [P in keyof T]?: T[P] extends Record ? RecursivePartial : T[P]; -}; diff --git a/packages/pvm-types/lib/platform.ts b/packages/pvm-types/lib/platform.ts deleted file mode 100644 index 65de63272..000000000 --- a/packages/pvm-types/lib/platform.ts +++ /dev/null @@ -1,68 +0,0 @@ -import type { - AlterReleaseResult, CommitOptions, CommitResult, - CreateReleasePayload, FileCommitApi, - GetReleaseResult, MetaComment, PlatformReleaseTag, - ReleasePayload, - VcsRelease, -} from './vcs' - -export abstract class BasePlatformInterface { - currentMr: MergeRequest | null = null; - abstract requireMr(): MergeRequest; - abstract getCommitLink(commit: string): Promise; - /** Создает и тег и релиз, если тег уже есть то выбрасывается исключение */ - abstract addTagAndRelease(ref: string, tag_name: string, data: CreateReleasePayload): Promise; - /** Создает релиз на существующем теге */ - abstract createRelease(tagName: string, payload: CreateReleasePayload): Promise; - /** Возвращает релиз, если есть, для существующего тега. Результат если тега нет или нет релиза отличается по коду ответа */ - abstract getRelease(tagName: string): Promise; - /** Редактирует существующий релиз, если нет релиза или тега будет ошибка */ - abstract editRelease(tag_name: string, data: ReleasePayload): Promise; - /** Редактирует или создает релиз, тег должен существовать */ - abstract upsertRelease(tag_name: string, data: ReleasePayload): Promise; - abstract releasesIterator(): AsyncGenerator; - abstract releaseTagsIterator(): AsyncGenerator; - abstract syncAttachment(kind: string, attachment: Buffer, opts: any): Promise; - abstract beginMrAttribution(): void; - // common with AbstractVcs - abstract fetchLatestSha(refName: string): Promise; - abstract getCurrentBranch(cwd: string): string | undefined - abstract getCommitSha(): string - abstract addTag(tag_name: string, ref: string): Promise; - - abstract findMrNote(kind: string): Promise | void>; - - abstract createMrNote(body: string): Promise; - abstract updateMrNote(commentId: number | string, body: string): Promise; - - abstract getProjectLabels(): AsyncIterable<{ name: string }>; - abstract createProjectLabel(label: string, color: string): Promise; - abstract setMrLabels(labels: string[]): Promise; - - abstract getUpdateHintsByCommit(commit: string): Promise | null>; - - abstract syncText(kind: string, text: string): Promise; - - abstract ensureMrLabels(labels: string[]): Promise; -} - -export abstract class BasePlatformInterfaceWithFileCommitApi extends BasePlatformInterface implements FileCommitApi { - supportsFileCommitApi = true - - abstract addFiles(commitContext: TCommitContext, filePaths: string[]): void; - - abstract appendFile(commitContext: TCommitContext, filePath: string, content: string): void; - - abstract beginCommit(): TCommitContext; - - abstract commit(commitContext: TCommitContext, message: string, opts?: CommitOptions): Promise; - - abstract deleteFile(commitContext: TCommitContext, file_path: string): void; - - abstract rollbackCommit(commitContext: TCommitContext): Promise; - - abstract updateFile(commitContext: TCommitContext, file_path: string, content: string): void; -} diff --git a/packages/pvm-types/lib/utils.ts b/packages/pvm-types/lib/utils.ts deleted file mode 100644 index dfaa89bbe..000000000 --- a/packages/pvm-types/lib/utils.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type RecursivePartial = { - [P in keyof T]?: T[P] extends Record ? RecursivePartial : T[P]; -}; diff --git a/packages/pvm-types/package.json b/packages/pvm-types/package.json deleted file mode 100644 index db4718fd2..000000000 --- a/packages/pvm-types/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "@pvm/types", - "version": "0.0.0-stub", - "description": "Common types", - "repository": "git@github.com:Tinkoff/pvm.git", - "author": "Mikhail Shipov ", - "license": "Apache-2.0", - "main": "./lib/index.js", - "exports": { - ".": "./lib/index.js", - "./lib/env-schema.json": "./lib/env-schema.json", - "./lib/config-schema.json": "./lib/config-schema.json" - }, - "dependencies": { - "@tinkoff/dippy": "^0.8.6" - } -} diff --git a/packages/pvm-update/.npmignore b/packages/pvm-update/.npmignore deleted file mode 100644 index e13e0d218..000000000 --- a/packages/pvm-update/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -*.ts -!*.d.ts -__tests__ -__snapshots__ diff --git a/packages/pvm-update/README.md b/packages/pvm-update/README.md deleted file mode 100644 index 45d94ea0b..000000000 --- a/packages/pvm-update/README.md +++ /dev/null @@ -1 +0,0 @@ -# @pvm/update diff --git a/packages/pvm-update/cli/pvm-update-local.ts b/packages/pvm-update/cli/pvm-update-local.ts deleted file mode 100644 index 1ffefd696..000000000 --- a/packages/pvm-update/cli/pvm-update-local.ts +++ /dev/null @@ -1,18 +0,0 @@ -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' - -import * as pvmUpdate from './pvm-update' - -export const command = 'local ' -export const description = 'Enables local mode for the following command' -export const builder = (yargs: Argv) => { - return yargs - .example(`$0 local update`, `Update packages locally and don't create the commit in a remote repository`) - .middleware(argv => { - argv.local = true - return argv - }) - .command(pvmUpdate) - .demandCommand() -} -export const handler = () => {} diff --git a/packages/pvm-update/cli/pvm-update.ts b/packages/pvm-update/cli/pvm-update.ts deleted file mode 100644 index 4e5e8f8a7..000000000 --- a/packages/pvm-update/cli/pvm-update.ts +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env node -import chalk from 'chalk' -// eslint-disable-next-line node/no-extraneous-import -import type Yargs from 'yargs' -import { parseSubArgs } from '@pvm/core/lib/text/sub-args' -import * as updateMethods from '../lib/update-methods' -import { update } from '../lib' -import type { CliUpdateOpts } from '../types' -import { getConfig } from '@pvm/core/lib/config' - -export const command = 'update' -export const aliases = 'release' -export const description = 'Update packages changed since last release' -export const builder = (yargs: Yargs.Argv) => { - return yargs - .options({ - 'update-option': { - default: [], - type: 'array' as const, - alias: 'P', - description: `Options to the used update method`, - coerce(arg) { - return parseSubArgs(arg) - }, - }, - 'update-method': { - alias: 'p', - default: 'release', - description: - chalk`What we should do with changed packages. Options are: -{greenBright release} -. Do release. This is default. Commit new package versions, create release tag and store release notes. -. -. Options: -. {yellow local}: Do not push changes to the remote vcs server. -. -{greenBright dot} -. Generate graph in dot format of changed packages and print it to stdout -. -{greenBright print} -. Print changed packages -. -. Options: -. {yellow format}: String with flags - how we should print each package. For possible flags see help for pvm pkgset command. -. Default is "%n". -{greenBright md-table} -. Print packages about to release as md table. -`, - }, - 'dry-run': { - description: `Do all the job, but without any side-effect`, - type: 'boolean' as const, - }, - 'release-data-file': { - description: `Output release data to specified path`, - type: 'string' as const, - }, - 'tag-only': { - description: `Make release tag only, do not do or commit any changes to VCS`, - type: 'boolean' as const, - }, - }) - .example(`$0 update -P local`, 'update packages changed since last release, but don\'t push changes') -} - -export const handler = run - -function toCamelCase(str: string): string { - return str.replace(/-[a-z]/g, m => m.charAt(1).toUpperCase()) -} - -async function printResult(result: AsyncIterable | Iterable | string): Promise { - if (typeof result === 'string') { - console.log(result) - } else if (result[Symbol.asyncIterator]) { - for await (const line of result) { - console.log(line) - } - } else if (result[Symbol.iterator]) { - // @ts-ignore - for (const line of result) { - console.log(line) - } - } -} - -async function run(flags): Promise { - const cwd = process.cwd() - const updateMethodName = toCamelCase(flags.updateMethod) - const updateMethod = updateMethods[updateMethodName] - if (!updateMethod) { - throw new Error(`There is no "${flags.updateMethod}" update method`) - } - - if (flags.local) { - flags.P = flags.P || {} - flags.P.local = true - } - - const updateOpts: CliUpdateOpts = { - ...flags.P, - dryRun: flags.dryRun, - releaseDataFile: flags.releaseDataFile, - tagOnly: flags.tagOnly, - } - - const config = await getConfig(cwd) - config.executionContext.dryRun = flags.dryRun - config.executionContext.local = flags.local - - const result = await update(updateMethod, updateOpts) - if (result) { - // @ts-ignore - await printResult(result) - } -} diff --git a/packages/pvm-update/lib/vcs-init.ts b/packages/pvm-update/lib/vcs-init.ts deleted file mode 100644 index 763af70a7..000000000 --- a/packages/pvm-update/lib/vcs-init.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type { VcsPlatform } from '@pvm/vcs' -import getConfig from '@pvm/core/lib/config/get-config' -import { initVcsPlatform } from '@pvm/vcs' - -export interface VcsInitForUpdateOpts { - dryRun?: boolean, - local?: boolean, - vcsMode?: 'platform' | 'vcs', - cwd?: string, -} - -const vcsInstances = new Map() - -function normalizedObjectHash(rec: Record): string { - return JSON.stringify(Array.from(Object.entries(rec)).sort((a, b) => { - if (a[0] === b[0]) { - return 0 - } - if (a[0] < b[0]) { - return -1 - } - return 1 - })) -} - -export async function vcsInitForUpdate(opts: VcsInitForUpdateOpts = {}): Promise { - const cacheKey = normalizedObjectHash(opts) - - if (vcsInstances.has(cacheKey)) { - return vcsInstances.get(cacheKey)! - } - const { dryRun = false, local = false, vcsMode: vcsModeFromOpts } = opts - const config = await getConfig(opts.cwd) - const { commit_via_platform } = config.update - - const vcsMode = vcsModeFromOpts ?? commit_via_platform ? 'platform' : 'vcs' - - // initialize vcsPlatform at early stage - const vcs = await initVcsPlatform({ - dryRun, - localMode: local, - vcsMode, - }) - vcsInstances.set(cacheKey, vcs) - - return vcs -} diff --git a/packages/pvm-update/package.json b/packages/pvm-update/package.json deleted file mode 100644 index 969341981..000000000 --- a/packages/pvm-update/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "@pvm/update", - "version": "0.0.0-stub", - "description": "Updates packages in a repository", - "main": "lib/index.js", - "repository": "git@github.com:Tinkoff/pvm.git", - "author": "Andrey Rublev ", - "license": "Apache-2.0", - "dependencies": { - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/artifacts": "0.0.0-stub", - "@pvm/changelog": "0.0.0-stub", - "@pvm/core": "0.0.0-stub", - "@pvm/types": "0.0.0-stub", - "@pvm/pkgset": "0.0.0-stub", - "@pvm/releases": "0.0.0-stub", - "@pvm/repository": "0.0.0-stub", - "@pvm/notifications": "0.0.0-stub", - "@pvm/template": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", - "chalk": "^4.0.0", - "date-fns": "^2.7.0", - "ignore": "^5.1.4", - "micromatch": "^3.1.10", - "resolve-from": "^5.0.0", - "semver": "^7.3.0", - "shuffle-seed": "^1.1.6", - "uniq": "^1.0.1", - "yargs": "^16.1.1" - } -} diff --git a/packages/pvm-update/plugin.ts b/packages/pvm-update/plugin.ts deleted file mode 100644 index 60fd6156e..000000000 --- a/packages/pvm-update/plugin.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { declarePlugin, provide } from '@pvm/di' -import { CLI_EXTENSION_TOKEN } from '@pvm/tokens-core' - -import * as updateCommand from './cli/pvm-update' -import * as updateLocalCommand from './cli/pvm-update-local' - -export default declarePlugin({ - factory: function() { - return { - providers: [ - provide({ - provide: CLI_EXTENSION_TOKEN, - useValue: [ - updateCommand, - updateLocalCommand, - ], - multi: true, - }), - ], - } - }, -}) diff --git a/packages/pvm-update/types/index.ts b/packages/pvm-update/types/index.ts deleted file mode 100644 index 7e39a8b61..000000000 --- a/packages/pvm-update/types/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { UpdateState } from '../lib/update-state' -import type { PvmReleaseType, Config } from '@pvm/types' -import type { ImmutablePkgSet } from '@pvm/core/lib/pkg-set' - -import type { Vcs } from '@pvm/vcs' -import type { CliUpdateOpts } from './cli' - -export type { CliUpdateOpts, Vcs } - -export interface UpdateMethod { - run(updateState: UpdateState, vcs: Vcs, args: CliUpdateOpts): Promise, - prepare?(config: Config, vcs: Vcs): Promise, -} - -export interface ForceReleaseState { - packages: ImmutablePkgSet, - defaultReleaseType?: PvmReleaseType, -} - -export interface ReleaseContext { - name: string, - tagAnnotation: string, - releaseTag: string, - releaseNotes: string, - updateState: UpdateState, -} diff --git a/packages/pvm-vcs-fs/.npmignore b/packages/pvm-vcs-fs/.npmignore deleted file mode 100644 index e13e0d218..000000000 --- a/packages/pvm-vcs-fs/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -*.ts -!*.d.ts -__tests__ -__snapshots__ diff --git a/packages/pvm-vcs-fs/README.md b/packages/pvm-vcs-fs/README.md deleted file mode 100644 index c863908ee..000000000 --- a/packages/pvm-vcs-fs/README.md +++ /dev/null @@ -1 +0,0 @@ -# @pvm/vcs-fs diff --git a/packages/pvm-vcs-fs/lib/fs-vcs.ts b/packages/pvm-vcs-fs/lib/fs-vcs.ts deleted file mode 100644 index 4e0c85b77..000000000 --- a/packages/pvm-vcs-fs/lib/fs-vcs.ts +++ /dev/null @@ -1,70 +0,0 @@ -import fs from 'fs' -import path from 'path' -import { wdShell } from '@pvm/core/lib/shell' -import { mkdirp } from '@pvm/core/lib/fs' -import { loggerFor } from '@pvm/core/lib/logger' -import { mema } from '@pvm/core/lib/memoize' - -import type { AbstractVcs } from '@pvm/vcs/types' -import { gitFetch } from '@pvm/core/lib/git/commands' - -const log = loggerFor('pvm:fs-vcs') - -function makeFsVcs(cwd: string): AbstractVcs { - const rp = (filePath: string): string => path.resolve(cwd, filePath) - - const fsVcs: AbstractVcs = { - beginCommit(): void {}, - rollbackCommit(_: void): Promise { - return Promise.resolve() - }, - addFiles(_context, _fp) { - // noop - }, - async appendFile(_, filePath: string, content: string) { - mkdirp(path.dirname(rp(filePath))) - fs.appendFileSync(rp(filePath), content) - }, - async updateFile(_, filePath, content) { - mkdirp(path.dirname(rp(filePath))) - fs.writeFileSync(rp(filePath), content) - }, - getCurrentBranch(): string | void { - // noop - }, - async deleteFile(_, filePath) { - if (fs.existsSync(rp(filePath))) { - fs.unlinkSync(rp(filePath)) - } - }, - async fetchLatestSha(refName): Promise { - gitFetch(cwd, { repo: 'origin' }) - - return wdShell(cwd, `git rev-parse origin/${refName}`) - }, - - async commit() { - return { id: 'fake commit' } - }, - async addTag(...args) { - log.debug('NOOP: Add tag', ...args) - }, - async push() { - log.debug('NOOP: Push') - }, - dryRun() { - log.debug('NOOP: dry run') - }, - isLastAvailableRef(): boolean { - // log.info('NOOP: isLastAvailableRev') - return false - }, - getHeadRev() { - return '0000000000000000000000000000000000000000' - }, - } - - return fsVcs -} - -export const initFsVcs = mema(makeFsVcs) diff --git a/packages/pvm-vcs-fs/package.json b/packages/pvm-vcs-fs/package.json deleted file mode 100644 index 10c754a3e..000000000 --- a/packages/pvm-vcs-fs/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "@pvm/vcs-fs", - "version": "0.0.0-stub", - "description": "Vcs api for running pvm update without writings to git", - "main": "lib/fs-vcs.js", - "repository": "git@github.com:Tinkoff/pvm.git", - "author": "ext.mshipov@tinkoff.ru", - "license": "Apache-2.0", - "dependencies": { - "@pvm/core": "0.0.0-stub" - }, - "devDependencies": { - "@pvm/vcs": "0.0.0-stub" - } -} \ No newline at end of file diff --git a/packages/pvm-vcs-git/.npmignore b/packages/pvm-vcs-git/.npmignore deleted file mode 100644 index e13e0d218..000000000 --- a/packages/pvm-vcs-git/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -*.ts -!*.d.ts -__tests__ -__snapshots__ diff --git a/packages/pvm-vcs-git/README.md b/packages/pvm-vcs-git/README.md deleted file mode 100644 index 570b57e11..000000000 --- a/packages/pvm-vcs-git/README.md +++ /dev/null @@ -1 +0,0 @@ -# @pvm/vcs-git diff --git a/packages/pvm-vcs-git/lib/git-vcs.ts b/packages/pvm-vcs-git/lib/git-vcs.ts deleted file mode 100644 index 9bc77eef4..000000000 --- a/packages/pvm-vcs-git/lib/git-vcs.ts +++ /dev/null @@ -1,325 +0,0 @@ -import fs from 'fs' -import path from 'path' -import assert from 'assert' -import semver from 'semver' - -import __shell, { bindToCwd } from '@pvm/core/lib/shell' -import __runShell from '@pvm/core/lib/shell/run' -import __execShell from '@pvm/core/lib/shell/exec' -import { mkdirp, escapeFilePath } from '@pvm/core/lib/fs' -import { getConfig } from '@pvm/core/lib/config' -import { logger } from '@pvm/core/lib/logger' -import { mema } from '@pvm/core/lib/memoize' -import revParse from '@pvm/core/lib/git/rev-parse' -import { addTag, getCurrentBranchIgnoreEnv, gitFetch } from '@pvm/core/lib/git/commands' -import { getHostApi } from '@pvm/core/lib/plugins/index' -import { getGitVersion } from '@pvm/core/lib/runtime-env/versions' - -import type { AbstractVcs, AddTagOptions, CommitResult, PushOptions, CommitOptions } from '@pvm/vcs/types' -import { env } from '@pvm/core/lib/env' - -const gitlabPushWithoutKeyDesc = { - 'ru': `Вы пытаетесь отправить изменения через git на gitlab раннере. Однако, по умолчанию из гитлаб раннеров нельзя отправлять изменения через git протокол (см. https://gitlab.com/gitlab-org/gitlab-foss/-/issues/63858). - -Если операция не пройдет, сделайте следующее: -1. Создайте публичные и приватные ключи следуя инструкции описанной здесь: https://gitlab.com/help/ssh/README -2. Добавьте сгенерированный ключ на странице Settings -> CI / CD проекта. - Замечание: ключ хоть и добавляется на странице конкретного проекта, он будет доступен и для других проектов в пространстве. -3. Активируйте добавленный ключ для нужных вам проектов. Не забудьте проставить опцию "Write access allowed". -4. Добавьте переменную окружения GIT_SSH_PRIV_KEY на странице Settings -> CI / CD проекта со значением равным приватному ключу добавленному на втором шаге. - Переменную можно пометить как "protected", т.к. нужна она будет только для команды \`pvm update\`/\`pvm release\` которые обычно выполняются в master/main ветке проекта. - -После этого PVM будет использовать этот ключ для отправки изменений через git протокол.`, - '_': `You are trying to push changes through git on gitlab runner. However, by default you cannot send changes via the git protocol (see https://gitlab.com/gitlab-org/gitlab-foss/-/issues/63858). - -If the operation fails, do the following: -1. Create public and private keys following the instructions described here: https://gitlab.com/help/ssh/README. -2. Add the generated key on the Settings -> CI / Project CD page. - Note: although a key is added to a specific project page, it will be available for other projects in the space. -3. Activate the added key for the projects you need. Do not forget to check "Write access allowed" option. -4. Add environment variable GIT_SSH_PRIV_KEY on page Settings -> CI / CD of the project with value equal to private key added on the second step. - Variable can be marked as "protected" because it will be needed only for \`pvm update\`/\`pvm release\` command which are usually executed in master/main branch of the project. - -After that PVM will use this key to send changes via git protocol. -`, -} - -export interface GitCommitContext { - initialRev: string, - stashRef: string, -} - -enum PushOptionsVersion { - NOT_SUPPORTED, - LONG_KEY, - SHORT_KEY, -} - -function getPushOptionsVersion(): PushOptionsVersion { - const gitVersion = getGitVersion() - if (!gitVersion) { - return PushOptionsVersion.NOT_SUPPORTED - } - if (semver.lt(gitVersion, '2.10.0')) { - return PushOptionsVersion.NOT_SUPPORTED - } - if (semver.lt(gitVersion, '2.18.0')) { - return PushOptionsVersion.LONG_KEY - } - return PushOptionsVersion.SHORT_KEY -} - -function stringifyPushOptions(pushOptions: Map): string[] { - const pushOptionsVersion = getPushOptionsVersion() - if (pushOptionsVersion === PushOptionsVersion.NOT_SUPPORTED) { - if (pushOptions.size > 0) { - logger.error([ - `You have push options, but your git version ${getGitVersion()} doesn't support push-options.`, - `Please upgrade git to latest version. Minimum required version is 2.10.0 or better 2.18.0`, - ].join('\n')) - } - return [] - } - - const prefix = pushOptionsVersion === PushOptionsVersion.SHORT_KEY ? '-o ' : '--push-option=' - - return Array.from(pushOptions.entries()).map(([key, value]) => { - return `${prefix}"${key}${value === true ? '' : `=${value}`}"` - }) -} - -function prepareGit(cwd: string): void { - const shell = bindToCwd(cwd, __shell) - - let needDefineUserName - try { - needDefineUserName = !shell('git config user.name') - } catch (e) { - needDefineUserName = true - } - - let needDefineUserEmail - try { - needDefineUserEmail = !shell('git config user.email') - } catch (e) { - needDefineUserEmail = true - } - - if (needDefineUserName) { - shell('git config user.name "PVM Service"') - } - if (needDefineUserEmail) { - shell('git config user.email "pvm@pvm.service"') - } -} - -function makeGitVcs(cwd: string): AbstractVcs { - let isDryRun = false - - const shell = bindToCwd(cwd, __shell) - const runShell = bindToCwd(cwd, __runShell) - const execShell = bindToCwd(cwd, __execShell) - const cachedShell = mema(shell) - - let gitPrepared = false - function prepareGitMemo(): void { - if (!gitPrepared) { - prepareGit(cwd) - } - - gitPrepared = true - } - - const runGit = async (command: string) => { - prepareGitMemo() - return await runShell(command) - } - - const gitVcs: AbstractVcs = { - beginCommit(): GitCommitContext { - prepareGitMemo() - return { - initialRev: gitVcs.getHeadRev(), - stashRef: shell('git stash create'), - } - }, - async rollbackCommit(commitContext: GitCommitContext): Promise { - await runGit(`git reset --hard ${commitContext.initialRev}`) - if (commitContext.stashRef) { - await runGit(`git stash apply ${commitContext.stashRef}`) - } - }, - addFiles(_commitContext: GitCommitContext, filePaths: string[]) { - if (filePaths.length) { - return runGit(`git add ${filePaths.map(escapeFilePath).join(' ')}`) - } - return Promise.resolve() - }, - updateFile(_, filePath, content): Promise { - mkdirp(path.dirname(filePath)) - fs.writeFileSync(filePath, content) - - return runGit(`git add ${filePath}`) - }, - appendFile(_, filePath, content) { - mkdirp(path.dirname(filePath)) - fs.appendFileSync(filePath, content) - - return runGit(`git add ${filePath}`) - }, - async deleteFile(_, filePath): Promise { - if (fs.existsSync(filePath)) { - return runGit(`git rm ${filePath}`) - } - }, - getCurrentBranch(): string | void { - prepareGitMemo() - return getCurrentBranchIgnoreEnv(cwd) - }, - async commit(_, message: string, opts: CommitOptions = {}): Promise { - prepareGitMemo() - - const { branch } = opts - - const currentBranch = gitVcs.getCurrentBranch() - if (branch && currentBranch) { - assert.strictEqual(branch, currentBranch) - } - - // по крайней мере в git v2.25.0 есть бага: опция allow-empty не работает вместе с dry-run - const commitArgs = [`--file=-`] - if (opts.allowEmpty) { - commitArgs.push('--allow-empty') - } - - if (!isDryRun) { - await runShell(`git commit ${commitArgs.join(' ')}`, { input: message }) - } - - return { - id: shell('git rev-parse HEAD'), - } - }, - getHeadRev() { - prepareGitMemo() - return shell('git rev-parse HEAD') - }, - isLastAvailableRef(ref: string): boolean { - prepareGitMemo() - const rev = revParse(ref, cwd) - return cachedShell('git rev-list --max-parents=0 HEAD').indexOf(rev) !== -1 - }, - async push(opts: PushOptions = {}) { - prepareGitMemo() - const config = await getConfig(cwd) - const hostApi = await getHostApi(cwd) - const remoteBranch = gitVcs.getCurrentBranch() || config.git.push.default_branch - const remoteRepository = - opts.remote || - await hostApi.runOr('git.push_remote', '') || - 'origin' - - const pushArgs: string[] = [] - - if (isDryRun || env.PVM_EXTERNAL_DRY_RUN) { - pushArgs.push('--dry-run') - logger.info('pushing changes in dry run mode') - } - - const { pushOptions = new Map() } = opts - - if (opts.skipCi && !pushOptions.has('ci.skip')) { - pushOptions.set('ci.skip', true) - } - - pushArgs.push(...stringifyPushOptions(pushOptions)) - - if (env.PVM_TESTING_ENV) { - logger.info('skip pushing in testing env') - // @TODO: код ниже ломает тесты в условиях гитлаб раннеров ломая евент-луп - return - } - - const pushEnv: Record = { - // eslint-disable-next-line pvm/no-process-env - ...process.env, - GIT_SSL_NO_VERIFY: '1', - } - - // если задана переменная PVM_DIRECT_GIT_PUSH то скрипт не будет выполнятся в любом случае - if (!env.PVM_DIRECT_GIT_PUSH && env.CI && config.git.push.try_load_ssh_keys) { - if (!env.GIT_SSH_PRIV_KEY) { - // @TODO: i18n support - const locale = Intl.DateTimeFormat().resolvedOptions().locale.split('-')[0].toLowerCase() - const messageLocale = locale in gitlabPushWithoutKeyDesc ? locale : '_' - logger.warn(gitlabPushWithoutKeyDesc[messageLocale]) - } - const gitLoadPushCreds = path.resolve(__dirname, '../ci/git-load-push-creds.sh') - const payloadMark = '@----------ssh-agent-data----------@' - const { stdout } = await execShell(gitLoadPushCreds, { - printStdout: true, - env: { - // eslint-disable-next-line pvm/no-process-env - ...process.env, - PAYLOAD_MARK: payloadMark, - }, - }) - - const indexOfPayloadMark = stdout.indexOf(payloadMark) - if (indexOfPayloadMark !== -1) { - const payload = stdout.substr(indexOfPayloadMark).split(payloadMark)[1] - if (payload) { - const [SSH_AUTH_SOCK, SSH_AGENT_PID] = payload.trim().split(';') - if (SSH_AUTH_SOCK && SSH_AGENT_PID) { - logger.info('Successfully get ssh-agent identifiers from git-load-push-creds.sh script') - logger.debug(`SSH_AUTH_SOCK="${SSH_AUTH_SOCK}"`) - logger.debug(`SSH_AGENT_PID="${SSH_AGENT_PID}"`) - pushEnv.SSH_AUTH_SOCK = SSH_AUTH_SOCK - pushEnv.SSH_AGENT_PID = SSH_AGENT_PID - } - } - } else { - logger.error('No payload mark found produced by execution of git-load-push-creds.sh script') - } - } - - if (opts.refspec) { - await runShell(`git push ${pushArgs.join(' ')} ${remoteRepository} ${opts.refspec}`, { - env: pushEnv, - }) - } else { - await runShell(`git push ${pushArgs.join(' ')} ${remoteRepository} HEAD:${remoteBranch}`, { - env: pushEnv, - }) - if (!opts.noTags) { - await runShell(`git push ${pushArgs.join(' ')} --tags ${remoteRepository}`, { - env: pushEnv, - }) - } - } - }, - async fetchLatestSha(refName: string): Promise { - gitFetch(cwd, { repo: 'origin' }) - - return shell(`git rev-parse origin/${refName}`) - }, - - async addTag(tagName, ref, opts: AddTagOptions = {}): Promise { - prepareGitMemo() - addTag(cwd, { - tagName, - ref, - annotation: opts.annotation, - }) - }, - dryRun() { - isDryRun = true - }, - } - - return gitVcs -} - -export { prepareGit } - -export const initGitVcs = mema(makeGitVcs) diff --git a/packages/pvm-vcs-git/package.json b/packages/pvm-vcs-git/package.json deleted file mode 100644 index f7345550e..000000000 --- a/packages/pvm-vcs-git/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "@pvm/vcs-git", - "version": "0.0.0-stub", - "description": "Git layer for pvm", - "main": "lib/git-vcs.js", - "repository": "git@github.com:Tinkoff/pvm.git", - "author": "Andrey Rublev ", - "license": "Apache-2.0", - "dependencies": { - "@pvm/core": "0.0.0-stub", - "semver": "^7.3.0" - }, - "devDependencies": { - "@pvm/vcs": "0.0.0-stub" - } -} \ No newline at end of file diff --git a/packages/pvm-vcs/.npmignore b/packages/pvm-vcs/.npmignore deleted file mode 100644 index e13e0d218..000000000 --- a/packages/pvm-vcs/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -*.ts -!*.d.ts -__tests__ -__snapshots__ diff --git a/packages/pvm-vcs/README.md b/packages/pvm-vcs/README.md deleted file mode 100644 index 74fa9029a..000000000 --- a/packages/pvm-vcs/README.md +++ /dev/null @@ -1 +0,0 @@ -# @pvm/vcs diff --git a/packages/pvm-vcs/cli/pvm-vcs.ts b/packages/pvm-vcs/cli/pvm-vcs.ts deleted file mode 100644 index 484e40bb0..000000000 --- a/packages/pvm-vcs/cli/pvm-vcs.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { log } from '@pvm/core/lib/logger' -import { initVcsPlatform } from '../lib/vcs' - -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' - -async function isBranchActual(): Promise { - const vcs = await initVcsPlatform() - const currentBranch = vcs.getCurrentBranch() - if (currentBranch) { - const matches = await vcs.isRefMatchesRemoteBranch('HEAD', currentBranch) - - if (!matches) { - log(`Branch ${currentBranch} doesn't match remote one! Is it outdated ?`) - process.exitCode = 1 - } - } else { - log('No branch detected. Are you in detached head state ?') - process.exitCode = 1 - } -} - -function cliSubargsToMap(args: string[]): Map { - const map = new Map() - for (const arg of args) { - const indexOfEq = arg.indexOf('=') - if (indexOfEq === -1) { - map.set(arg, true) - } else { - const key = arg.substring(0, indexOfEq) - const value = arg.substr(indexOfEq + 1) - map.set(key, value) - } - } - return map -} - -async function push(flags): Promise { - const vcs = await initVcsPlatform({ - vcsMode: 'vcs', - }) - - await vcs.push({ - skipCi: flags.skipCi, - noTags: !flags.tags, - pushOptions: cliSubargsToMap(flags.pushOption), - refspec: flags.refspec, - }) -} - -export const command = 'vcs ' -export const description = 'cli for version control system' -export const builder = (yargs: Argv) => { - return yargs - .command( - 'is-branch-actual', - `Checks current branch is up to date with origin remote one. Exit with code 0 unless branch is stale`, - {}, - isBranchActual - ) - .command( - 'push [refspec]', - 'Push current branch & tags via vcs(git) to remote repository. If refspec is passed pushes only it.', - { - 'skip-ci': { - default: false, - type: 'boolean' as const, - description: 'Do not trigger pipeline for push refs if possible', - }, - 'tags': { - default: false, - type: 'boolean' as const, - description: 'Also push tags', - }, - 'push-option': { - alias: 'o', - type: 'array' as const, - description: `--push-option's for git push command`, - }, - }, - push - ) - .demandCommand() -} -export const handler = () => {} diff --git a/packages/pvm-vcs/lib/platform-interface.ts b/packages/pvm-vcs/lib/platform-interface.ts deleted file mode 100644 index 445626fd3..000000000 --- a/packages/pvm-vcs/lib/platform-interface.ts +++ /dev/null @@ -1,105 +0,0 @@ -import stringToColor from 'string-to-color' -import { debug, log } from '@pvm/core/lib/logger' -import type { - AlterReleaseResult, CommitOptions, CommitResult, - CreateReleasePayload, FileCommitApi, - GetReleaseResult, MetaComment, PlatformReleaseTag, - ReleasePayload, - VcsRelease, -} from '../types/index' -import { getNoteBody } from './utils' - -export abstract class PlatformInterface { - currentMr: MergeRequest | null; - abstract requireMr(): MergeRequest; - abstract getCommitLink(commit: string): Promise; - /** Создает и тег и релиз, если тег уже есть то выбрасывается исключение */ - abstract addTagAndRelease(ref: string, tag_name: string, data: CreateReleasePayload): Promise; - /** Создает релиз на существующем теге */ - abstract createRelease(tagName: string, payload: CreateReleasePayload): Promise; - /** Возвращает релиз, если есть, для существующего тега. Результат если тега нет или нет релиза отличается по коду ответа */ - abstract getRelease(tagName: string): Promise; - /** Редактирует существующий релиз, если нет релиза или тега будет ошибка */ - abstract editRelease(tag_name: string, data: ReleasePayload): Promise; - /** Редактирует или создает релиз, тег должен существовать */ - abstract upsertRelease(tag_name: string, data: ReleasePayload): Promise; - abstract releasesIterator(): AsyncGenerator; - abstract releaseTagsIterator(): AsyncGenerator; - abstract syncAttachment(kind: string, attachment: Buffer, opts: any): Promise; - abstract beginMrAttribution(): void; - // common with AbstractVcs - abstract fetchLatestSha(refName: string): Promise; - abstract getCurrentBranch(cwd: string): string | undefined - abstract getCommitSha(): string - abstract addTag(tag_name: string, ref: string): Promise; - - abstract findMrNote(kind: string): Promise | void>; - - abstract createMrNote(body: string): Promise; - abstract updateMrNote(commentId: number | string, body: string): Promise; - - abstract getProjectLabels(): AsyncIterable<{ name: string }>; - abstract createProjectLabel(label: string, color: string): Promise; - abstract setMrLabels(labels: string[]): Promise; - - abstract getUpdateHintsByCommit(commit: string): Promise | null>; - - async syncText(kind: string, text: string): Promise { - const existingNote = await this.findMrNote(kind) - - const noteBody = getNoteBody([['kind', kind], ['ref', this.getCommitSha()]], text) - - if (existingNote) { - return this.updateMrNote(existingNote.note.id, noteBody) - } else { - return this.createMrNote(noteBody) - } - } - - async ensureMrLabels(labels: string[]): Promise { - const labelsByName = Object.create(null) - for await (const label of this.getProjectLabels()) { - labelsByName[label.name] = label - } - - const newLabels: string[] = [] - - for (const line of labels) { - if (line in labelsByName) { - continue - } - const color = stringToColor(line) - debug(`creating label ${line}, color ${color}`) - - await this.createProjectLabel(line, color) - newLabels.push(line) - } - - if (newLabels.length !== 0) { - log(`Successfully created new labels: ${newLabels.join(', ')}`) - } - - return this.setMrLabels(labels) - } -} - -export abstract class PlatformInterfaceWithFileCommitApi extends PlatformInterface implements FileCommitApi { - supportsFileCommitApi = true - - abstract addFiles(commitContext: TCommitContext, filePaths: string[]): void; - - abstract appendFile(commitContext: TCommitContext, filePath: string, content: string): void; - - abstract beginCommit(): TCommitContext; - - abstract commit(commitContext: TCommitContext, message: string, opts?: CommitOptions): Promise; - - abstract deleteFile(commitContext: TCommitContext, file_path: string): void; - - abstract rollbackCommit(commitContext: TCommitContext): Promise; - - abstract updateFile(commitContext: TCommitContext, file_path, content): void; -} diff --git a/packages/pvm-vcs/lib/vcs.ts b/packages/pvm-vcs/lib/vcs.ts deleted file mode 100644 index 565464620..000000000 --- a/packages/pvm-vcs/lib/vcs.ts +++ /dev/null @@ -1,353 +0,0 @@ -import { getConfig } from '@pvm/core/lib/config' -import { inspectArgs } from '@pvm/core/lib/inspect-args' -import { logger } from '@pvm/core/lib/logger' -import { wdShell } from '@pvm/core/lib/shell' -import type { HostApi } from '@pvm/core/lib/plugins' -import { getHostApi } from '@pvm/core/lib/plugins' -import { cachedRealPath } from '@pvm/core/lib/fs' -import { initFsVcs } from '@pvm/vcs-fs' -import { initGitVcs } from '@pvm/vcs-git/lib/git-vcs' - -import type { GitCommitContext } from '@pvm/vcs-git/lib/git-vcs' -import type { - ReleasePayload, CreateReleasePayload, VcsRelease, VcsOnly, UnknownCommitContext, - AbstractVcs, AddTagOptions, CommitResult, GetReleaseResult, PushOptions, PlatformReleaseTag, -} from '../types' -import { env } from '@pvm/core/lib/env' -import { getApp } from '@pvm/core/lib/config/get-config' -import { PLATFORM_TOKEN } from '@pvm/tokens-core' - -const VcsMap = { - git: initGitVcs, - fs: initFsVcs, -} - -function detectVcsType() { - return env.PVM_VCS_TYPE || 'git' -} - -async function loadBuiltinVcs(cwd: string, customVcsType?: string): Promise { - const config = await getConfig(cwd) - const vcsType = customVcsType || (config.vcs.builtin_type === 'auto' ? detectVcsType() : config.vcs.builtin_type) - - if (!VcsMap[vcsType]) { - throw new Error(`Unsupported vcs "${vcsType}"`) - } - - const hostApi = await getHostApi(cwd) - hostApi.provideRecord('vcs', VcsMap[vcsType](cwd)) -} - -async function loadBuiltinPlatform(cwd: string): Promise { - const platform = getApp(cwd).container.get(PLATFORM_TOKEN) - - if (!platform) { - return - } - - const hostApi = await getHostApi(cwd) - - hostApi.provideClass('platform', platform) -} - -function dryRunStub(method: string, ...args: any[]): void { - logger.debug(`DRY RUN: ${method}`, `(${inspectArgs(args)})`) -} - -export interface PushError extends Error { - context: 'push', -} - -const dryRunHostApi: HostApi = { - run: dryRunStub, - runOr: dryRunStub, - plPipe: dryRunStub, - plEachSeries: dryRunStub, -} as HostApi - -interface VcsConstructorOpts { - cwd?: string, - vcsMode?: 'vcs' | 'platform', -} - -// @TODO: wrong abstraction for fs/vcs tuple -// надо либо выделить отдельный слой для vcs-файловых операций -// либо fs просто убить, и взамен него использовать local mode для любой vcs, что скорее всего предпочтительней -export class VcsPlatform implements VcsOnly { - cwd: string - isDryRun = false - hostApi: HostApi - mutHostApi: HostApi - commitContext: any = null - _isSomethingForCommit = false - _localMode = false - vcsMode: 'vcs' | 'platform' - gitVcs: AbstractVcs - - constructor(hostApi, opts: VcsConstructorOpts = {}) { - const { cwd = process.cwd(), vcsMode = 'vcs' } = opts - this.hostApi = hostApi - this.mutHostApi = hostApi - this.cwd = cwd - this.vcsMode = vcsMode - this.gitVcs = initGitVcs(cwd) - } - - dryRun() { - this.isDryRun = true - this.hostApi.run('vcs.dryRun') - this.mutHostApi = dryRunHostApi - } - - // в этом режиме никакие пуши или общения с gitlab api запрещены - // при этом работа с локальным git или fs разрешена - setLocalMode(): void { - logger.log('enable local mode for VCS') - this.vcsMode = 'vcs' - this._localMode = true - } - - gitShell(cmd: string, opts = {}): string { - return wdShell(this.cwd, cmd, opts) - } - - isSomethingForCommit(): boolean { - return this._isSomethingForCommit - } - - resetCommitContext(): void { - this.commitContext = null - this._isSomethingForCommit = false - } - - async rollbackCommit(commitContext: UnknownCommitContext): Promise { - await this.hostApi.run(`${this.vcsMode}.rollbackCommit`, commitContext) - - this.resetCommitContext() - } - - beginCommit(): UnknownCommitContext { - // FYI: upconf оперирует vcs без beginCommit - // поэтому неявный контекст созданный в _prepareCommitContext возвращаем как есть - if (!this.commitContext) { - this.commitContext = this.hostApi.run(`${this.vcsMode}.beginCommit`) - } - return this.commitContext - } - - _prepareCommitContext(): UnknownCommitContext { - this._isSomethingForCommit = true - return this.beginCommit() - } - - async addFiles(filePaths: string[]): Promise { - if (filePaths.length) { - return this.mutHostApi.run(`${this.vcsMode}.addFiles`, this._prepareCommitContext(), filePaths) - } - } - - async addPath(path: string): Promise { - const filePaths = this.gitShell(`git ls-files --cached --others "${path}"`).split('\n').filter(x => x.length !== 0) - return await this.addFiles(filePaths) - } - - async updateFile(filePath: string, content: string): Promise { - return this.mutHostApi.run(`${this.vcsMode}.updateFile`, this._prepareCommitContext(), filePath, content) - } - - async appendFile(filePath: string, content: string): Promise { - return this.mutHostApi.run(`${this.vcsMode}.appendFile`, this._prepareCommitContext(), filePath, content) - } - - async deleteFile(filePath: string): Promise { - return this.mutHostApi.run(`${this.vcsMode}.deleteFile`, this._prepareCommitContext(), filePath) - } - - async commit(message: string, opts = {}): Promise { - if (!this.isSomethingForCommit()) { - logger.log('nothing to commit') - return - } - // vcs-провайдеры сами обслуживают dry-run режим - const commitHostApi = this.vcsMode === 'vcs' ? this.hostApi : this.mutHostApi - - const result = await commitHostApi.run(`${this.vcsMode}.commit`, this.commitContext, message, opts) - this.resetCommitContext() - - // если у нас замокан commitHostApi возвращаем просто текущий коммит - if (this.isDryRun && commitHostApi === this.mutHostApi) { - return { id: this.gitVcs.getHeadRev() } - } - - // нулевой айди не обязателен здесь, но всякий случай пусть будет - return result || { id: '0000000000000000000000000000000000000000' } - } - - async push(opts: PushOptions = {}): Promise { - if (this.vcsMode === 'vcs' && !this._localMode) { - // в данном случае не подменяем на mutHostApi, который в случае dryRun просто пустышка-логгер - // т.к. конечные vcs сами должны учитывать вызов метода vcs.dryRun для последующих вызовов vcs.push - try { - await this.hostApi.run('vcs.push', opts) - } catch (e) { - (e as PushError).context = 'push' - throw e - } - } - } - - getCurrentBranch(): string | undefined { - return this.hostApi.runOr(`platform.getCurrentBranch`, undefined) - } - - isLastAvailableRef(ref: string): boolean { - return this.hostApi.run('vcs.isLastAvailableRef', ref) - } - - async addTag(tagName: string, ref: string, opts: AddTagOptions = {}): Promise { - await this.mutHostApi.run(`${this.vcsMode}.addTag`, tagName, ref, opts) - } - - async createRelease(tagName: string, data: ReleasePayload): Promise { - if (!this._localMode) { - return this.mutHostApi.run('platform.createRelease', tagName, data) - } - } - - async addTagAndRelease(ref: string, tagName: string, data: CreateReleasePayload): Promise { - if (!this._localMode) { - await this.mutHostApi.run('platform.addTagAndRelease', ref, tagName, data) - } else { - await this.addTag(tagName, ref, { - annotation: data.annotation, - }) - } - } - - async editRelease(tagName: string, data: ReleasePayload): Promise { - if (!this._localMode) { - await this.mutHostApi.run('platform.editRelease', tagName, data) - } - } - - // редактирует релиз если он есть, либо создает новый если его нет - // тег обязан существовать - async upsertRelease(tagName: string, data: ReleasePayload): Promise { - if (!this._localMode) { - await this.mutHostApi.run('platform.upsertRelease', tagName, data) - } - } - - async getRelease(tagName: string): Promise { - return this.hostApi.run('platform.getRelease', tagName) - } - - releasesIterator(): AsyncIterable { - return this.hostApi.run('platform.releasesIterator') - } - - releaseTagsIterator(): AsyncIterable { - return this.hostApi.run('platform.releaseTagsIterator') - } - - async fetchLatestSha(refName: string): Promise { - return this.hostApi.run(`${this.vcsMode}.fetchLatestSha`, refName) - } - - async syncText(kind: string, text: string): Promise { - if (!this._localMode) { - return this.mutHostApi.run('platform.syncText', kind, text) - } - } - - async syncAttachment(kind: string, attachment: Buffer, opts = {}): Promise { - if (!this._localMode) { - return this.mutHostApi.run('platform.syncAttachment', kind, attachment, opts) - } - } - - async beginMrAttribution(): Promise { - if (!this._localMode) { - return this.hostApi.run('platform.beginMrAttribution') - } - } - - async ensureMrLabels(labels: string[]): Promise { - if (!this._localMode) { - return this.mutHostApi.run('platform.ensureMrLabels', labels) - } - } - - async isRefMatchesRemoteBranch(targetRef = 'HEAD', branchName: string): Promise { - if (!branchName) { - throw new Error(`Branch name is required. Are you in detached head state ?`) - } - return this.gitShell(`git rev-parse ${targetRef}`) === await this.fetchLatestSha(branchName) - } - - async getCommitLink(commit: string): Promise { - return this.hostApi.run('platform.getCommitLink', commit) - } - - async getUpdateHintsByCommit(commit: string): Promise | null> { - if (!this._localMode) { - return this.hostApi.runOr('platform.getUpdateHintsByCommit', null, commit) - } - - return null - } -} - -interface InitVcsOpts { - cwd?: string, - dryRun?: boolean, - vcsType?: keyof typeof VcsMap, - vcsMode?: 'vcs' | 'platform', - localMode?: boolean, -} - -const vcsInstances = new Map() - -async function initVcsPlatform(opts: InitVcsOpts = {}): Promise { - const { cwd = process.cwd(), dryRun, vcsType, localMode = global.argv?.local || false, vcsMode } = opts - await loadBuiltinVcs(cwd, vcsType) - const useLocalMode = localMode || env.PVM_EXTERNAL_DRY_RUN - - // платформа может понадобится и в локальном режиме - await loadBuiltinPlatform(cwd) - const hostApi = await getHostApi(cwd) - - const vcs = new VcsPlatform(hostApi, { - cwd, - vcsMode, - }) - if (dryRun) { - vcs.dryRun() - } - - if (useLocalMode) { - vcs.setLocalMode() - } - - const cacheKey = cachedRealPath(cwd) - vcsInstances.set(cacheKey, vcs) - return vcs -} - -async function lazyInitVcs(cwd: string, opts: Omit = {}): Promise { - const vcs = vcsInstances.get(cachedRealPath(cwd)) - if (!vcs) { - return await initVcsPlatform({ - cwd, - ...opts, - }) - } - return vcs -} - -export { - initVcsPlatform, - lazyInitVcs, - initVcsPlatform as default, - VcsPlatform as Vcs, // для обратной совместимости -} diff --git a/packages/pvm-vcs/package.json b/packages/pvm-vcs/package.json deleted file mode 100644 index c02c1991b..000000000 --- a/packages/pvm-vcs/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "@pvm/vcs", - "version": "0.0.0-stub", - "description": "Abstraction layer for vcs", - "main": "lib/index", - "repository": "git@github.com:Tinkoff/pvm.git", - "author": "Andrey Rublev ", - "license": "Apache-2.0", - "dependencies": { - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/core": "0.0.0-stub", - "@pvm/vcs-git": "0.0.0-stub", - "@pvm/vcs-fs": "0.0.0-stub", - "string-to-color": "^2.2.2", - "yargs": "^16.1.1" - } -} diff --git a/packages/pvm-vcs/plugin.ts b/packages/pvm-vcs/plugin.ts deleted file mode 100644 index a58b043f9..000000000 --- a/packages/pvm-vcs/plugin.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { declarePlugin, provide } from '@pvm/di' -import { CLI_EXTENSION_TOKEN } from '@pvm/tokens-core' - -import * as command from './cli/pvm-vcs' - -export default declarePlugin({ - factory: function() { - return { - providers: [ - provide({ - provide: CLI_EXTENSION_TOKEN, - useValue: command, - multi: true, - }), - ], - } - }, -}) diff --git a/packages/pvm-vcs/types/index.ts b/packages/pvm-vcs/types/index.ts deleted file mode 100644 index a5e3c733f..000000000 --- a/packages/pvm-vcs/types/index.ts +++ /dev/null @@ -1,102 +0,0 @@ -import type { PlatformResult } from '@pvm/core/lib/shared' - -export interface VcsRelease { - name: string, - tag_name: string, - description: string, - created_at: string, - commit?: { - id: string, - }, -} - -export interface CommitResult { - id: string, -} - -export interface ReleasePayload { - name: string, - description: string, -} - -export interface CreateReleasePayload extends ReleasePayload { - annotation?: string | null, -} - -export interface CommitOptions { - branch?: string, - allowEmpty?: boolean, -} - -export interface PushOptions { - remote?: string, - refspec?: string, - skipCi?: boolean, - noTags?: boolean, - pushOptions?: Map, -} - -export interface PlatformReleaseTag { - name: string, -} - -export interface MetaComment { - metadata: Record, - content: string, - note: Note, -} - -export interface FileCommitApi { - addFiles(commitContext: TCommitContext, filePaths: string[]): void, - appendFile(commitContext: TCommitContext, filePath: string, content: string): void, - beginCommit(): TCommitContext, - rollbackCommit(commitContext: TCommitContext): Promise, - updateFile(commitContext: TCommitContext, file_path, content): void, - deleteFile(commitContext: TCommitContext, file_path: string): void, - commit(commitContext: TCommitContext, message: string, opts?: CommitOptions): Promise, -} - -export interface AbstractVcs extends FileCommitApi { - fetchLatestSha(refName: string): Promise, - addTag(tag_name: string, ref: string): Promise, - push(opts?: PushOptions): Promise, - dryRun(): void, - getCurrentBranch(): string | void, - getHeadRev(): string, - isLastAvailableRef(rev: string): boolean, -} - -export interface AlterReleaseResult { - id: string, -} - -export interface PlatformRelease { - name: string, - description: string, -} - -export interface AddTagOptions { - annotation?: string | null, -} - -export type GetReleaseResult = [PlatformResult.OK, PlatformRelease] | [PlatformResult.NOT_FOUND | PlatformResult.NO_SUCH_TAG, null] - -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface UnknownCommitContext { - _: 'unknown_cc', -} - -export interface VcsOnly { - isDryRun: boolean, - cwd: string, - beginCommit(): UnknownCommitContext, - rollbackCommit(commitContext: UnknownCommitContext): Promise, - isSomethingForCommit(): boolean, - addFiles(filePaths: string[]): Promise, - updateFile(filePath: string, content: string): Promise, - appendFile(filePath: string, content: string): Promise, - deleteFile(filePath: string): Promise, - commit(message: any, opts?: Record): Promise, - push(opts?: PushOptions): Promise, - addTag(tagName: string, ref: string, opts?: AddTagOptions): Promise, -} diff --git a/packages/pvm-viz/.npmignore b/packages/pvm-viz/.npmignore deleted file mode 100644 index e13e0d218..000000000 --- a/packages/pvm-viz/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -*.ts -!*.d.ts -__tests__ -__snapshots__ diff --git a/packages/pvm-viz/README.md b/packages/pvm-viz/README.md deleted file mode 100644 index ed43e736e..000000000 --- a/packages/pvm-viz/README.md +++ /dev/null @@ -1 +0,0 @@ -# @pvm/viz diff --git a/packages/pvm-viz/cli/pvm-viz.ts b/packages/pvm-viz/cli/pvm-viz.ts deleted file mode 100755 index ba27c30d2..000000000 --- a/packages/pvm-viz/cli/pvm-viz.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* eslint-disable no-console */ -import fs from 'fs' -import { renderDot } from '../lib' - -// eslint-disable-next-line node/no-extraneous-import -import type { Argv } from 'yargs' - -export const command = 'viz ' -export const description = 'Graphviz pvm cli wrapper' -export const builder = (yargs: Argv) => { - return yargs - .example(`$0 viz graph.dot`, 'Render dot file to stdout') -} -export const handler = main - -async function main(argv) { - argv.files.forEach(file => { - const str = fs.readFileSync(file, 'utf-8') - renderDot(str) - .then(result => { - console.log(result) - }) - .catch(err => { - process.exitCode = 1 - console.error(err) - }) - }) -} diff --git a/packages/pvm-viz/package.json b/packages/pvm-viz/package.json deleted file mode 100644 index 11281ec57..000000000 --- a/packages/pvm-viz/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "@pvm/viz", - "version": "0.0.0-stub", - "description": "cli for viz.js package", - "main": "lib/index.js", - "author": "Andrey Rublev ", - "license": "Apache-2.0", - "dependencies": { - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "viz.js": "^2.1.2", - "yargs": "^16.1.1" - } -} diff --git a/packages/pvm-viz/plugin.ts b/packages/pvm-viz/plugin.ts deleted file mode 100644 index 26724dc92..000000000 --- a/packages/pvm-viz/plugin.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { declarePlugin, provide } from '@pvm/di' -import { CLI_EXTENSION_TOKEN } from '@pvm/tokens-core' - -import * as command from './cli/pvm-viz' - -export default declarePlugin({ - factory: function() { - return { - providers: [ - provide({ - provide: CLI_EXTENSION_TOKEN, - useValue: command, - multi: true, - }), - ], - } - }, -}) diff --git a/packages/pvm/.npmignore b/packages/pvm/.npmignore index e13e0d218..6a57518a1 100644 --- a/packages/pvm/.npmignore +++ b/packages/pvm/.npmignore @@ -1,4 +1,5 @@ *.ts !*.d.ts +*.js.map __tests__ __snapshots__ diff --git a/packages/pvm/README.md b/packages/pvm/README.md index e6f135058..be9cadabd 100644 --- a/packages/pvm/README.md +++ b/packages/pvm/README.md @@ -8,4 +8,50 @@ For each subcommand help is also available (for example `yarn pvm publish --help ``` @cli-inline yarn pvm --help -``` \ No newline at end of file +``` + +## Node API + +Entrypoint to pvm functionality. Consumes user config and additional plugins list + +### Usage examples + +As node library: +```javascript +import { Pvm } from '@pvm/pvm' + +const pvm = new Pvm({ + config: './.pvm.toml', // or config object { mark_pr: { analyze_update: true } } for example, + plugins: [], // this is useful for providing preconfigured Pvm instances (examples here will be github usage where github plugin is required) + cwd: '.', // from where plugins resolving will happen + repo: '.' // by default is equal to cwd but can differ in case you want to process external repository where pvm is not installed +}) + +const pkgs = await pvm.getPkgset('all') +``` + +and as cli: +```javascript +// cli.js +import { Pvm } from '@pvm/app' +import { CLI_TOKEN } from '@pvm/pvm' +import PvmCliPlugin from '@pvm/plugin-cli' + +const pvm = new Pvm({ + config: {}, // or config object { mark_pr: { analyze_update: true } } for example, + plugins: [{ + plugin: PvmCliPlugin + }], // this is useful for providing preconfigured Pvm instances (examples here will be github usage where github plugin is required) + cwd: process.cwd(), // by default is equal `process.cwd()`. Spcify from where plugins resolving will happen + repo: process.cwd() // by default is equal to cwd but can differ in case you want to process external repository where pvm is not installed +}) + +pvm.runCli(process.argv) // will start [`yargs`](https://yargs.js.org/) with all extensions, provided by CLI_EXTENSION_TOKEN, appliend +``` + +then you can call `cli.js` file and use provided cli api +``` +> node ./cli.js --help +``` + +### \ No newline at end of file diff --git a/packages/pvm/__tests__/cli.spec.ts b/packages/pvm/__tests__/cli.spec.ts new file mode 100644 index 000000000..32f5367c8 --- /dev/null +++ b/packages/pvm/__tests__/cli.spec.ts @@ -0,0 +1,35 @@ +import { Pvm } from '../app' +import { CLI_EXTENSION_TOKEN, CLI_TOKEN } from '../tokens' +import { provide } from '../lib/di' + +describe('@pvm/cli', () => { + it('should run provided command', () => { + let outputStore = '' + const pvm = new Pvm({ + config: { + plugins_v2: [{ + plugin: () => ({ + providers: [provide({ + provide: CLI_EXTENSION_TOKEN, + useFactory: () => function testCommand(builder) { + return builder.command( + 'cli-test', + 'test command', + () => { + outputStore = 'command works!\n' + process.stdout.write(outputStore) + } + ) + }, + multi: true, + })], + }), + }], + }, + }) + + pvm.container.get(CLI_TOKEN)({ argv: ['node.exe', 'path-to-script.js', 'cli-test'] }) + + expect(outputStore).toBe('command works!\n') + }) +}) diff --git a/packages/pvm-core/lib/config/__tests__/config.spec.ts b/packages/pvm/__tests__/config.spec.ts similarity index 96% rename from packages/pvm-core/lib/config/__tests__/config.spec.ts rename to packages/pvm/__tests__/config.spec.ts index 51f528e5d..1347e2d88 100644 --- a/packages/pvm-core/lib/config/__tests__/config.spec.ts +++ b/packages/pvm/__tests__/config.spec.ts @@ -1,5 +1,5 @@ import type { Config } from '../types' -import { readEnv, migrateDeprecated } from '../get-config' +import { readEnv, migrateDeprecated } from '../app/config' describe('pvm/config', () => { it('should correctly read variables from env', () => { diff --git a/packages/pvm-core/lib/git/__tests__/600-packages.json b/packages/pvm/__tests__/git/600-packages.json similarity index 100% rename from packages/pvm-core/lib/git/__tests__/600-packages.json rename to packages/pvm/__tests__/git/600-packages.json diff --git a/packages/pvm-core/lib/git/__tests__/commands.spec.ts b/packages/pvm/__tests__/git/commands.spec.ts similarity index 87% rename from packages/pvm-core/lib/git/__tests__/commands.spec.ts rename to packages/pvm/__tests__/git/commands.spec.ts index 76565e493..c1c83fd13 100644 --- a/packages/pvm-core/lib/git/__tests__/commands.spec.ts +++ b/packages/pvm/__tests__/git/commands.spec.ts @@ -1,4 +1,4 @@ -import { extractDomain } from '../commands' +import { extractDomain } from '../../lib/git/commands' describe('extractDomain', () => { it('extractDomain should extract domain from git ssh url', () => { diff --git a/packages/pvm-core/lib/git/__tests__/git-commands.spec.ts b/packages/pvm/__tests__/git/git-commands.spec.ts similarity index 75% rename from packages/pvm-core/lib/git/__tests__/git-commands.spec.ts rename to packages/pvm/__tests__/git/git-commands.spec.ts index 8f085fd0c..f56f1480c 100644 --- a/packages/pvm-core/lib/git/__tests__/git-commands.spec.ts +++ b/packages/pvm/__tests__/git/git-commands.spec.ts @@ -1,13 +1,13 @@ -import { getTagAnnotation } from '../commands' +import initRepo from '../../../../test/initRepo' +import { writeRepo } from '../../../../test/writeRepo' +import { getTagAnnotation } from '../../lib/git/commands' import packages600 from './600-packages.json' describe('git-commands', () => { it('git annotation should handle big text', async () => { const annotation = `big release\n\n---\n${packages600.join('\n')}` - // @ts-ignore const repoPath = writeRepo({ name: 'bigann', spec: 'src/a@1.0.0' }) - // @ts-ignore const repo = await initRepo(repoPath) await repo.annotatedTag('v1.2.0', annotation) diff --git a/packages/pvm-core/lib/git/__tests__/last-release-tag.spec.ts b/packages/pvm/__tests__/git/last-release-tag.spec.ts similarity index 87% rename from packages/pvm-core/lib/git/__tests__/last-release-tag.spec.ts rename to packages/pvm/__tests__/git/last-release-tag.spec.ts index d52c8b340..1086336e8 100644 --- a/packages/pvm-core/lib/git/__tests__/last-release-tag.spec.ts +++ b/packages/pvm/__tests__/git/last-release-tag.spec.ts @@ -1,10 +1,10 @@ -import { lastReleaseTag } from '../last-release-tag' +import { lastReleaseTag } from '../../lib/git/last-release-tag' +import initRepo from '../../../../test/initRepo' describe('last-release-tag', () => { // covers PVM-144 it('should take lrt from master in case first-parent in merge commit leads to branch', async () => { - // @ts-ignore const repo = await initRepo('simple-one') await repo.tag('v0.1.0') const firstReleasedSha = repo.head diff --git a/packages/pvm-core/lib/git/__tests__/release-commits.spec.ts b/packages/pvm/__tests__/git/release-commits.spec.ts similarity index 88% rename from packages/pvm-core/lib/git/__tests__/release-commits.spec.ts rename to packages/pvm/__tests__/git/release-commits.spec.ts index 2d5c6d991..3bcb91246 100644 --- a/packages/pvm-core/lib/git/__tests__/release-commits.spec.ts +++ b/packages/pvm/__tests__/git/release-commits.spec.ts @@ -1,9 +1,9 @@ -import { getReleaseCommits, releaseCommitsAsString } from '../release-commits' +import { getReleaseCommits, releaseCommitsAsString } from '../../lib/git/release-commits' +import initRepo from '../../../../test/initRepo' describe('core/release-commits', () => { describe('getReleaseCommits', () => { it('should exclude release commits', async () => { - // @ts-ignore const repo = await initRepo('monorepo-new') await repo.tag('release-initial') repo.touch('src/a/nf', 'change a') @@ -19,7 +19,6 @@ describe('core/release-commits', () => { describe('releaseCommitsAsString', () => { it('should exclude release commits', async () => { - // @ts-ignore const repo = await initRepo('monorepo-new') repo.touch('src/a/nf', 'change a') await repo.runScript('pvm update') diff --git a/packages/pvm-core/lib/__tests__/iter.spec.ts b/packages/pvm/__tests__/iter.spec.ts similarity index 93% rename from packages/pvm-core/lib/__tests__/iter.spec.ts rename to packages/pvm/__tests__/iter.spec.ts index a91462645..cee30ce1b 100644 --- a/packages/pvm-core/lib/__tests__/iter.spec.ts +++ b/packages/pvm/__tests__/iter.spec.ts @@ -1,4 +1,4 @@ -import { drainWhileResolves, cachedIterator } from '../iter' +import { drainWhileResolves, cachedIterator } from '../lib/iter' async function * yield3andReject() { await Promise.resolve() diff --git a/packages/pvm-core/lib/__tests__/markdownify-commits.spec.ts b/packages/pvm/__tests__/markdownify-commits.spec.ts similarity index 89% rename from packages/pvm-core/lib/__tests__/markdownify-commits.spec.ts rename to packages/pvm/__tests__/markdownify-commits.spec.ts index 8ecc911ad..9d4d40e96 100644 --- a/packages/pvm-core/lib/__tests__/markdownify-commits.spec.ts +++ b/packages/pvm/__tests__/markdownify-commits.spec.ts @@ -1,6 +1,6 @@ -import markdownifyCommits from '../markdownify-commits' +import markdownifyCommits from '../lib/markdownify-commits' -function genCommits(subjects) { +function genCommits(subjects: string[]): { subject: string, body: string }[] { return subjects.map(s => { const delimIndex = s.indexOf('\n\n') const subject = delimIndex !== -1 ? s.substring(0, delimIndex) : s diff --git a/src/plugins/core/__tests__/message-builder.spec.ts b/packages/pvm/__tests__/message-builder.spec.ts similarity index 92% rename from src/plugins/core/__tests__/message-builder.spec.ts rename to packages/pvm/__tests__/message-builder.spec.ts index 1c5525c15..3ba97892a 100644 --- a/src/plugins/core/__tests__/message-builder.spec.ts +++ b/packages/pvm/__tests__/message-builder.spec.ts @@ -1,5 +1,6 @@ -import { releaseMessage } from '../messages/message-builder' -import { env } from '@pvm/core/lib/env' +import { releaseMessage } from '../lib/messages/message-builder' +import { env } from '../lib/env' +import initRepo from '../../../test/initRepo' describe('notifications/message-builder', () => { const ciPipelineUrl = env.CI_PIPELINE_URL @@ -8,7 +9,6 @@ describe('notifications/message-builder', () => { }) it('should take full tag for simple repositories', async () => { - // @ts-ignore const repo = await initRepo('simple-one') const message = releaseMessage({ @@ -23,12 +23,10 @@ describe('notifications/message-builder', () => { pvmConfig: repo.config, }) - // @ts-ignore expect(message.content).toEqual('v0.1.0 has been released') }) it('should get part of release tag in case of monorepository', async () => { - // @ts-ignore const repo = await initRepo('monorepo-new') const message = releaseMessage({ @@ -43,12 +41,10 @@ describe('notifications/message-builder', () => { pvmConfig: repo.config, }) - // @ts-ignore expect(message.content).toEqual('moon has been released') }) it('should add error info if publish failed partially', async () => { - // @ts-ignore const repo = await initRepo('monorepo-new') const message = releaseMessage({ @@ -77,7 +73,6 @@ describe('notifications/message-builder', () => { }) it('should add error info if publish fully failed', async () => { - // @ts-ignore const repo = await initRepo('monorepo-new') const message = releaseMessage({ @@ -102,7 +97,6 @@ describe('notifications/message-builder', () => { it('should add pipeline url to error title', async () => { env.CI_PIPELINE_URL = 'test' - // @ts-ignore const repo = await initRepo('monorepo-new') const message = releaseMessage({ diff --git a/src/plugins/core/__tests__/packages.spec.ts b/packages/pvm/__tests__/packages.spec.ts similarity index 77% rename from src/plugins/core/__tests__/packages.spec.ts rename to packages/pvm/__tests__/packages.spec.ts index d77a5c5c6..5a8aed451 100644 --- a/src/plugins/core/__tests__/packages.spec.ts +++ b/packages/pvm/__tests__/packages.spec.ts @@ -1,9 +1,8 @@ - -import { getPackages } from '../packages' +import initRepo from '../../../test/initRepo' +import { getPackages } from '../mechanics/packages' describe('pvm/getPackages', () => { it('dangerously_opts.always_changed_workspaces should work for changed list', async () => { - // @ts-ignore const repo = await initRepo('monorepo-new', { dangerously_opts: { always_changed_workspaces: [ @@ -12,7 +11,7 @@ describe('pvm/getPackages', () => { }, }) - const packages = await getPackages('changed', { cwd: repo.dir }) + const packages = await getPackages(repo.di, 'changed', { cwd: repo.dir }) expect(packages.map(pkg => pkg.path).sort()).toEqual([ 'src/a', @@ -21,7 +20,6 @@ describe('pvm/getPackages', () => { }) it('dangerously_opts.always_changed_workspaces should work for affected list', async () => { - // @ts-ignore const repo = await initRepo('monorepo-new', { dangerously_opts: { always_changed_workspaces: [ @@ -30,7 +28,7 @@ describe('pvm/getPackages', () => { }, }) - const packages = await getPackages('affected', { cwd: repo.dir }) + const packages = await getPackages(repo.di, 'affected', { cwd: repo.dir }) expect(packages.map(pkg => pkg.path).sort()).toEqual([ 'src/a', @@ -39,7 +37,6 @@ describe('pvm/getPackages', () => { }) it('dangerously_opts.always_changed_workspaces should work for update list', async () => { - // @ts-ignore const repo = await initRepo('monorepo-new', { dangerously_opts: { always_changed_workspaces: [ @@ -48,7 +45,7 @@ describe('pvm/getPackages', () => { }, }) - const packages = await getPackages('update', { cwd: repo.dir }) + const packages = await getPackages(repo.di, 'update', { cwd: repo.dir }) expect(packages.map(pkg => pkg.path).sort()).toEqual([ 'src/a', diff --git a/packages/pvm-core/lib/__tests__/pkg.spec.ts b/packages/pvm/__tests__/pkg.spec.ts similarity index 82% rename from packages/pvm-core/lib/__tests__/pkg.spec.ts rename to packages/pvm/__tests__/pkg.spec.ts index 9cdabb5e4..b07477693 100644 --- a/packages/pvm-core/lib/__tests__/pkg.spec.ts +++ b/packages/pvm/__tests__/pkg.spec.ts @@ -1,9 +1,9 @@ +import initRepo from '../../../test/initRepo' +import { writeRepo } from '../../../test/writeRepo' describe('pkg', () => { it('should take version from semver tag itself in case unified_versions_for covers all repo', async () => { - // @ts-ignore const repoPath = writeRepo({ name: 'indep', spec: 'src/a@1.0.0,src/b@1.0.0' }) - // @ts-ignore const repo = await initRepo(repoPath, { versioning: { unified: false, @@ -16,13 +16,11 @@ describe('pkg', () => { }) await repo.tag('v2.0.0') - expect((await repo.loadPkg('src/a')).version).toEqual('2.0.0') + expect((await repo.loadPkg('src/a'))?.version).toEqual('2.0.0') }) it('source=tag, package from second groups should not take versions from semver tag', async () => { - // @ts-ignore const repoPath = writeRepo({ name: 'abc', spec: 'src/a@1.0.0,src/b@1.0.0,src/c@1.0.0' }) - // @ts-ignore const repo = await initRepo(repoPath, { versioning: { unified: true, @@ -35,13 +33,11 @@ describe('pkg', () => { }) await repo.tag('v2.1.4') - expect((await repo.loadPkg('src/b')).version).not.toEqual('2.1.4') + expect((await repo.loadPkg('src/b'))?.version).not.toEqual('2.1.4') }) it('fallback version should not be from package for source=tag repos', async () => { - // @ts-ignore const repoPath = writeRepo({ name: 'abc', spec: 'src/a@1.0.0,src/b@1.1.2,src/c@1.0.0' }) - // @ts-ignore const repo = await initRepo(repoPath, { versioning: { unified: true, @@ -54,13 +50,11 @@ describe('pkg', () => { }) await repo.tag('v2.1.4') - expect((await repo.loadPkg('src/b')).version).not.toEqual('1.1.2') + expect((await repo.loadPkg('src/b'))?.version).not.toEqual('1.1.2') }) it(`should take version from last tag's annotations if head tags are simple ones`, async () => { - // @ts-ignore const repoPath = writeRepo({ name: 'abc', spec: 'src/a@1.0.0,src/b@1.0.0,src/c@1.0.0' }) - // @ts-ignore const repo = await initRepo(repoPath, { versioning: { unified: true, @@ -77,11 +71,10 @@ describe('pkg', () => { await repo.tag('v2.1.0') await repo.touch('src/a/nf2', 'change a again') await repo.tag('v2.1.1') - expect((await repo.loadPkg('src/b')).version).toEqual('1.1.0') + expect((await repo.loadPkg('src/b'))?.version).toEqual('1.1.0') }) it('should take initialVersion as initial from package.json in case dedicated version', async () => { - // @ts-ignore const repo = await initRepo('monorepo-new', { versioning: { unified: true, @@ -98,6 +91,6 @@ describe('pkg', () => { initialVersion: '1.20.300', }) - expect((await repo.loadPkg('src/new')).version).toEqual('1.20.300') + expect((await repo.loadPkg('src/new'))?.version).toEqual('1.20.300') }) }) diff --git a/packages/pvm-pkgset/lib/__tests__/is-root-changed.spec.ts b/packages/pvm/__tests__/pkgset/is-root-changed.spec.ts similarity index 91% rename from packages/pvm-pkgset/lib/__tests__/is-root-changed.spec.ts rename to packages/pvm/__tests__/pkgset/is-root-changed.spec.ts index db9e08254..97bd2b4ab 100644 --- a/packages/pvm-pkgset/lib/__tests__/is-root-changed.spec.ts +++ b/packages/pvm/__tests__/pkgset/is-root-changed.spec.ts @@ -1,4 +1,4 @@ -import isRootChanged from '../is-root-changed' +import isRootChanged from '../../mechanics/pkgset/is-root-changed' describe('pvm-pkgset/is-root-changed', () => { it('should correctly identify whenever root changed', () => { diff --git a/packages/pvm-pkgset/lib/strategies/__tests__/released.spec.ts b/packages/pvm/__tests__/pkgset/released.spec.ts similarity index 55% rename from packages/pvm-pkgset/lib/strategies/__tests__/released.spec.ts rename to packages/pvm/__tests__/pkgset/released.spec.ts index 09d8dfb14..34ca3563f 100644 --- a/packages/pvm-pkgset/lib/strategies/__tests__/released.spec.ts +++ b/packages/pvm/__tests__/pkgset/released.spec.ts @@ -1,23 +1,23 @@ import semver from 'semver' -import drainItems from '@pvm/core/lib/iter/drain-items' -import released from '../released' -import all from '../all' +import drainItems from '../../lib/iter/drain-items' +import released from '../../mechanics/pkgset/strategies/released' +import all from '../../mechanics/pkgset/strategies/all' +import initRepo from '../../../../test/initRepo' describe('pkgset/released', () => { it('should correctly work for file-based internally-cached versioning', async () => { - // @ts-ignore const repo = await initRepo('monostub') await repo.tag('release-initial') const versions = JSON.parse(repo.readFile('versions.json')) as Record - const currentPackages = await drainItems(all({ cwd: repo.dir })) // важная строчка, ей забиваем кеш изначально чтобы позже проверить на корректную инвалидацию + const currentPackages = await drainItems(all(repo.di, { cwd: repo.dir })) // важная строчка, ей забиваем кеш изначально чтобы позже проверить на корректную инвалидацию expect(currentPackages).toHaveLength(3) const newVersions = Object.fromEntries(Object.entries(versions).map(([pkg, version]) => [pkg, semver.inc(version, 'minor')])) await repo.writeFile('versions.json', JSON.stringify(newVersions), 'release new versions') await repo.tag('release-second') - const newPackages = await drainItems(released({ cwd: repo.dir })) + const newPackages = await drainItems(released(repo.di, { cwd: repo.dir })) expect(newPackages).toHaveLength(3) }) diff --git a/packages/pvm-pkgset/lib/__tests__/smart-paths.spec.ts b/packages/pvm/__tests__/pkgset/smart-paths.spec.ts similarity index 95% rename from packages/pvm-pkgset/lib/__tests__/smart-paths.spec.ts rename to packages/pvm/__tests__/pkgset/smart-paths.spec.ts index c6069c2f7..2f3b3a874 100644 --- a/packages/pvm-pkgset/lib/__tests__/smart-paths.spec.ts +++ b/packages/pvm/__tests__/pkgset/smart-paths.spec.ts @@ -1,5 +1,5 @@ -import { exclude } from '../smart-paths' +import { exclude } from '../../mechanics/pkgset/smart-paths' const workspaces = [ 'src/a', diff --git a/packages/pvm-repository/lib/__tests__/linter.spec.ts b/packages/pvm/__tests__/repository/linter.spec.ts similarity index 93% rename from packages/pvm-repository/lib/__tests__/linter.spec.ts rename to packages/pvm/__tests__/repository/linter.spec.ts index 2b970306b..2ea1315b1 100644 --- a/packages/pvm-repository/lib/__tests__/linter.spec.ts +++ b/packages/pvm/__tests__/repository/linter.spec.ts @@ -1,11 +1,12 @@ import fs from 'fs' import path from 'path' -import { lint } from '../linter' -import { Repository } from '../repository' -import { versioningFile } from '@pvm/core/lib/dedicated-versions-file' +import { lint } from '../../mechanics/repository/linter' +import { Repository } from '../../mechanics/repository/repository' +import { versioningFile } from '../../lib/dedicated-versions-file' +import initRepo from '../../../../test/initRepo' async function getRepository(testRepo: any): Promise { - return await Repository.init(testRepo.dir) + return await Repository.init(testRepo.di) } const fallbackVersion = '0.0.1' @@ -13,7 +14,6 @@ const fallbackVersion = '0.0.1' describe('linter', () => { describe('dedicated versions in file', () => { it('in case no version should add real version to versions file and stub version to package', async () => { - // @ts-ignore const repo = await initRepo('monostub') await repo.writeFile('src/new/package.json', JSON.stringify({ @@ -33,7 +33,6 @@ describe('linter', () => { }) it('should move real version of new package to versions file', async () => { - // @ts-ignore const repo = await initRepo('monostub') await repo.addPkg('src/new', { @@ -57,7 +56,6 @@ describe('linter', () => { }) it('should create versions file if not exists', async () => { - // @ts-ignore const repo = await initRepo('monorepo-new', { versioning: { source: 'file', @@ -82,7 +80,6 @@ describe('linter', () => { }) it('should remove unnecessary package entries from versions.json file', async () => { - // @ts-ignore const repo = await initRepo('monostub') await repo.runScript('git rm -rf src/b') @@ -103,7 +100,6 @@ describe('linter', () => { }) it('in case of existing stub version, should write non-stub version to versions file', async () => { - // @ts-ignore const repo = await initRepo('monostub') await repo.addPkg('src/new', { @@ -127,7 +123,6 @@ describe('linter', () => { }) it('should rewrite stub versions in versioning file', async () => { - // @ts-ignore const repo = await initRepo('monostub') const pvmRepo = await getRepository(repo) @@ -149,7 +144,6 @@ describe('linter', () => { describe('dedicated unified version in single tag', () => { it('should rewrite package versions to stubs', async () => { - // @ts-ignore const repo = await initRepo('monouno', { versioning: { source: 'tag', diff --git a/packages/pvm-core/lib/__tests__/semver-extra.spec.ts b/packages/pvm/__tests__/semver-extra.spec.ts similarity index 76% rename from packages/pvm-core/lib/__tests__/semver-extra.spec.ts rename to packages/pvm/__tests__/semver-extra.spec.ts index f44f30813..e1c1d147b 100644 --- a/packages/pvm-core/lib/__tests__/semver-extra.spec.ts +++ b/packages/pvm/__tests__/semver-extra.spec.ts @@ -1,4 +1,4 @@ -import { releaseTypes } from '../semver-extra' +import { releaseTypes } from '../lib/semver-extra' describe('core/semver-extra', () => { it('releasetypes/max', () => { diff --git a/packages/pvm-core/lib/__tests__/shell.spec.ts b/packages/pvm/__tests__/shell.spec.ts similarity index 82% rename from packages/pvm-core/lib/__tests__/shell.spec.ts rename to packages/pvm/__tests__/shell.spec.ts index ee2d890df..75cdb9842 100644 --- a/packages/pvm-core/lib/__tests__/shell.spec.ts +++ b/packages/pvm/__tests__/shell.spec.ts @@ -1,8 +1,8 @@ -import shell from '../shell' +import { shell } from '../lib/shell' describe('pvm-core/shell', () => { it('should throw error with exit code saved to status field if command failed', async () => { - let shellError + let shellError: any try { shell('exit 2') } catch (e) { diff --git a/packages/pvm-template/lib/__tests__/__snapshots__/templates.spec.ts.snap b/packages/pvm/__tests__/template/__snapshots__/templates.spec.ts.snap similarity index 100% rename from packages/pvm-template/lib/__tests__/__snapshots__/templates.spec.ts.snap rename to packages/pvm/__tests__/template/__snapshots__/templates.spec.ts.snap diff --git a/packages/pvm-template/lib/__tests__/templates.spec.ts b/packages/pvm/__tests__/template/templates.spec.ts similarity index 87% rename from packages/pvm-template/lib/__tests__/templates.spec.ts rename to packages/pvm/__tests__/template/templates.spec.ts index cefcc06d0..1f5031b2f 100644 --- a/packages/pvm-template/lib/__tests__/templates.spec.ts +++ b/packages/pvm/__tests__/template/templates.spec.ts @@ -1,4 +1,5 @@ -import getEnv from '../env' +import getEnv from '../../mechanics/template/env' +import initRepo from '../../../../test/initRepo' const template = `\ {%- macro showPkg(pkg) -%} @@ -12,7 +13,8 @@ const template = `\ describe('templates', () => { it('шаблонизация списков через cut', async () => { - const env = await getEnv() + const repo = await initRepo('simple-one') + const env = await getEnv(repo.config) const ctx = { success: [ @@ -44,7 +46,8 @@ describe('templates', () => { }) it('шаблонизация списков через cut, 1 пакет', async () => { - const env = await getEnv() + const repo = await initRepo('simple-one') + const env = await getEnv(repo.config) const ctx = { success: [ diff --git a/packages/pvm-core/lib/text/__tests__/text.spec.ts b/packages/pvm/__tests__/text.spec.ts similarity index 91% rename from packages/pvm-core/lib/text/__tests__/text.spec.ts rename to packages/pvm/__tests__/text.spec.ts index 6b5f96cf5..fcb1ff251 100644 --- a/packages/pvm-core/lib/text/__tests__/text.spec.ts +++ b/packages/pvm/__tests__/text.spec.ts @@ -1,5 +1,5 @@ -import { pullOutLinks, dottifyList } from '../markdown' -import { nthIndex } from '../index' +import { pullOutLinks, dottifyList } from '../lib/text/markdown' +import { nthIndex } from '../lib/text' describe('text utils', () => { it('должен форматировать линки', () => { diff --git a/packages/pvm-update/lib/__tests__/pkg-release-type.spec.ts b/packages/pvm/__tests__/update/pkg-release-type.spec.ts similarity index 58% rename from packages/pvm-update/lib/__tests__/pkg-release-type.spec.ts rename to packages/pvm/__tests__/update/pkg-release-type.spec.ts index 3b5bdf201..50d849ceb 100644 --- a/packages/pvm-update/lib/__tests__/pkg-release-type.spec.ts +++ b/packages/pvm/__tests__/update/pkg-release-type.spec.ts @@ -1,18 +1,19 @@ -import { markReleaseType } from '../pkg-release-type' -import { ChangedContext } from '../changed-context' -import type { UpdateContext } from '../update-context' -import { loadPkg } from '@pvm/core/lib/pkg' -import { UpdateState } from '../update-state' -import { Repository } from '@pvm/repository/lib' +import { markReleaseType } from '../../mechanics/update/pkg-release-type' +import { ChangedContext } from '../../mechanics/update/changed-context' +import type { UpdateContext } from '../../mechanics/update/update-context' +import { loadPkg } from '../../lib/pkg' +import { UpdateState } from '../../mechanics/update/update-state' +import { Repository } from '../../mechanics/repository' +import type { Container } from '../../lib/di' +import initRepo from '../../../../test/initRepo' -async function makeUpdateState(cwd: string, changedContext: ChangedContext, updateContext: UpdateContext): Promise { - const repo = await Repository.init(cwd) +async function makeUpdateState(di: Container, changedContext: ChangedContext, updateContext: UpdateContext): Promise { + const repo = await Repository.init(di) return new UpdateState(repo, changedContext, updateContext) } describe('pvm-update/pkg-release-type', () => { it('should respect update.release_type_overrides config', async () => { - // @ts-ignore const repo = await initRepo('monorepo-new', { update: { release_type_overrides: [ @@ -43,7 +44,7 @@ describe('pvm-update/pkg-release-type', () => { hints: {}, readHintsFile: false, } - const updateState = await makeUpdateState(repo.dir, changedContext, updateContext) + const updateState = await makeUpdateState(repo.di, changedContext, updateContext) await markReleaseType(aPkg, updateState) expect(updateState.getLikelyReleaseTypeFor(aPkg)).toEqual(null) diff --git a/packages/pvm-update/lib/__tests__/release-name.spec.ts b/packages/pvm/__tests__/update/release-name.spec.ts similarity index 86% rename from packages/pvm-update/lib/__tests__/release-name.spec.ts rename to packages/pvm/__tests__/update/release-name.spec.ts index 01943402a..97c27bc2f 100644 --- a/packages/pvm-update/lib/__tests__/release-name.spec.ts +++ b/packages/pvm/__tests__/update/release-name.spec.ts @@ -1,9 +1,9 @@ -import { addSuffixToSemverTagName } from '../release-name' +import { addSuffixToSemverTagName } from '../../mechanics/update/release-name' +import initRepo from '../../../../test/initRepo' describe('release-name', () => { describe('addSuffixToSemverTagName', () => { it('should add new suffixes', async () => { - // @ts-ignore const repo = await initRepo('simple-one', { versioning: { source: 'tag', diff --git a/packages/pvm-core/lib/utils/__tests__/array.spec.ts b/packages/pvm/__tests__/utils/array.spec.ts similarity index 94% rename from packages/pvm-core/lib/utils/__tests__/array.spec.ts rename to packages/pvm/__tests__/utils/array.spec.ts index b94303fca..ec5e1d07b 100644 --- a/packages/pvm-core/lib/utils/__tests__/array.spec.ts +++ b/packages/pvm/__tests__/utils/array.spec.ts @@ -1,4 +1,4 @@ -import { expDropRight } from '../array' +import { expDropRight } from '../../lib/utils/array' function * nGen(n: number, startFrom = 0): IterableIterator { for (let i = startFrom; i < startFrom + n; i++) { diff --git a/packages/pvm-core/lib/__tests__/versioning.spec.ts b/packages/pvm/__tests__/versioning.spec.ts similarity index 96% rename from packages/pvm-core/lib/__tests__/versioning.spec.ts rename to packages/pvm/__tests__/versioning.spec.ts index 457e1cf03..dd95a531d 100644 --- a/packages/pvm-core/lib/__tests__/versioning.spec.ts +++ b/packages/pvm/__tests__/versioning.spec.ts @@ -1,5 +1,5 @@ -import { extractVersionsFromAnnotation } from '../versioning' +import { extractVersionsFromAnnotation } from '../lib/versioning' function extractVersionsHelper(annotation: string): Record { return Object.fromEntries(extractVersionsFromAnnotation(annotation).entries()) diff --git a/packages/pvm-core/lib/__tests__/worktree.spec.ts b/packages/pvm/__tests__/worktree.spec.ts similarity index 94% rename from packages/pvm-core/lib/__tests__/worktree.spec.ts rename to packages/pvm/__tests__/worktree.spec.ts index fc72e9af7..88e157fe6 100644 --- a/packages/pvm-core/lib/__tests__/worktree.spec.ts +++ b/packages/pvm/__tests__/worktree.spec.ts @@ -1,4 +1,4 @@ -import { cwdToGitRelativity, gitToCwdRelativity } from '../git/worktree' +import { cwdToGitRelativity, gitToCwdRelativity } from '../lib/git/worktree' describe('core/worktree/cwdToGitRelativity', () => { it('should return "." if dot passed and cwd match git root', () => { diff --git a/packages/pvm-core/lib/app/__tests__/__fixtures__/non-cwd-config-and-provider/.pvm.toml b/packages/pvm/app/__tests__/__fixtures__/non-cwd-config-and-provider/.pvm.toml similarity index 100% rename from packages/pvm-core/lib/app/__tests__/__fixtures__/non-cwd-config-and-provider/.pvm.toml rename to packages/pvm/app/__tests__/__fixtures__/non-cwd-config-and-provider/.pvm.toml diff --git a/packages/pvm-core/lib/app/__tests__/__fixtures__/non-cwd-config-and-provider/package.json b/packages/pvm/app/__tests__/__fixtures__/non-cwd-config-and-provider/package.json similarity index 100% rename from packages/pvm-core/lib/app/__tests__/__fixtures__/non-cwd-config-and-provider/package.json rename to packages/pvm/app/__tests__/__fixtures__/non-cwd-config-and-provider/package.json diff --git a/packages/pvm-core/lib/app/__tests__/__fixtures__/non-cwd-config-and-provider/provider/configDefaults.toml b/packages/pvm/app/__tests__/__fixtures__/non-cwd-config-and-provider/provider/configDefaults.toml similarity index 100% rename from packages/pvm-core/lib/app/__tests__/__fixtures__/non-cwd-config-and-provider/provider/configDefaults.toml rename to packages/pvm/app/__tests__/__fixtures__/non-cwd-config-and-provider/provider/configDefaults.toml diff --git a/packages/pvm-core/lib/app/__tests__/__fixtures__/non-cwd-config-and-provider/provider/package.json b/packages/pvm/app/__tests__/__fixtures__/non-cwd-config-and-provider/provider/package.json similarity index 100% rename from packages/pvm-core/lib/app/__tests__/__fixtures__/non-cwd-config-and-provider/provider/package.json rename to packages/pvm/app/__tests__/__fixtures__/non-cwd-config-and-provider/provider/package.json diff --git a/packages/pvm/app/__tests__/__fixtures__/plugin-with-config-extension.js b/packages/pvm/app/__tests__/__fixtures__/plugin-with-config-extension.js new file mode 100644 index 000000000..edcf6f34f --- /dev/null +++ b/packages/pvm/app/__tests__/__fixtures__/plugin-with-config-extension.js @@ -0,0 +1,10 @@ +// eslint-disable-next-line import/no-extraneous-dependencies +const { declarePlugin } = require('@pvm/pvm') + +module.exports = declarePlugin({ + configExt: { + mark_pr: { + analyze_update: true, + }, + }, +}) diff --git a/packages/pvm-core/lib/app/__tests__/__fixtures__/plugin-with-config-with-plugins.js b/packages/pvm/app/__tests__/__fixtures__/plugin-with-config-with-plugins.js similarity index 58% rename from packages/pvm-core/lib/app/__tests__/__fixtures__/plugin-with-config-with-plugins.js rename to packages/pvm/app/__tests__/__fixtures__/plugin-with-config-with-plugins.js index 9466130e4..ad4ec9969 100644 --- a/packages/pvm-core/lib/app/__tests__/__fixtures__/plugin-with-config-with-plugins.js +++ b/packages/pvm/app/__tests__/__fixtures__/plugin-with-config-with-plugins.js @@ -1,4 +1,5 @@ -const { declarePlugin } = require('@pvm/di') +// eslint-disable-next-line import/no-extraneous-dependencies +const { declarePlugin } = require('@pvm/pvm') module.exports = declarePlugin({ configExt: { diff --git a/packages/pvm/app/__tests__/__fixtures__/plugin-with-options.js b/packages/pvm/app/__tests__/__fixtures__/plugin-with-options.js new file mode 100644 index 000000000..25993de50 --- /dev/null +++ b/packages/pvm/app/__tests__/__fixtures__/plugin-with-options.js @@ -0,0 +1,15 @@ +// eslint-disable-next-line import/no-extraneous-dependencies +const { declarePlugin, provide } = require('@pvm/pvm') + +module.exports = declarePlugin({ + factory(opts) { + return { + providers: [ + provide({ + provide: 'TEST_TOKEN', + useValue: opts.value, + }), + ], + } + }, +}) diff --git a/packages/pvm-core/lib/app/__tests__/__fixtures__/user-config-plugins/pvm/.pvm.toml b/packages/pvm/app/__tests__/__fixtures__/user-config-plugins/.pvm.toml similarity index 100% rename from packages/pvm-core/lib/app/__tests__/__fixtures__/user-config-plugins/pvm/.pvm.toml rename to packages/pvm/app/__tests__/__fixtures__/user-config-plugins/.pvm.toml diff --git a/packages/pvm/app/__tests__/__fixtures__/user-config-plugins/plugin.js b/packages/pvm/app/__tests__/__fixtures__/user-config-plugins/plugin.js new file mode 100644 index 000000000..ad424c684 --- /dev/null +++ b/packages/pvm/app/__tests__/__fixtures__/user-config-plugins/plugin.js @@ -0,0 +1,7 @@ +// eslint-disable-next-line import/no-extraneous-dependencies +const { declarePlugin } = require('@pvm/pvm') +module.exports = declarePlugin({ + configExt: { + test: true, + }, +}) diff --git a/packages/pvm-core/lib/app/__tests__/index.spec.ts b/packages/pvm/app/__tests__/index.spec.ts similarity index 60% rename from packages/pvm-core/lib/app/__tests__/index.spec.ts rename to packages/pvm/app/__tests__/index.spec.ts index f01c79ced..055d172d4 100644 --- a/packages/pvm-core/lib/app/__tests__/index.spec.ts +++ b/packages/pvm/app/__tests__/index.spec.ts @@ -1,8 +1,8 @@ import { Pvm } from '../index' -import { declarePlugin, provide } from '@pvm/di' +import { declarePlugin, provide } from '../../lib/di' import path from 'path' -import { CONFIG_TOKEN } from '@pvm/tokens-core' -import { Signales } from 'signales' +import { CLI_TOKEN, CONFIG_TOKEN } from '../../tokens' +import type { Config } from '../../types' describe('@pvm/container', () => { afterEach(() => { @@ -28,21 +28,6 @@ describe('@pvm/container', () => { expect(pvmContainer.container.get('test')).toBe('test value') }) - it('should handle direct factories', async () => { - const pvmContainer = new Pvm({ - plugins: [{ - plugin: () => ({ - providers: [provide({ - provide: 'test', - useValue: 'test value', - })], - }), - }], - }) - - expect(pvmContainer.container.get('test')).toBe('test value') - }) - it('should load nested plugins', async () => { const pvmContainer = new Pvm({ config: { @@ -54,8 +39,6 @@ describe('@pvm/container', () => { expect(pvmContainer.container.get(CONFIG_TOKEN)).toMatchObject({ plugins_v2: expect.arrayContaining([{ - plugin: require.resolve('@pvm/gitlab/plugin'), - }, { plugin: path.join(__dirname, '__fixtures__', 'plugin-with-config-with-plugins.js'), }, { plugin: './plugin-with-config-extension.js', @@ -102,27 +85,73 @@ describe('@pvm/container', () => { expect(pvmContainer.container.get(CONFIG_TOKEN).mark_pr.analyze_update).toBe(false) }) + it('user plugins should have ability to override di core providers', () => { + const pvmContainer = new Pvm({ + config: { + mark_pr: { + analyze_update: false, + }, + plugins_v2: [{ + plugin: declarePlugin({ + factory: () => { + return { + providers: [ + provide({ + provide: CLI_TOKEN, + useValue: { + test: true, + } as any, + }), + ], + } + }, + }), + }], + }, + }) + + expect(pvmContainer.container.get(CLI_TOKEN)).toEqual({ + test: true, + }) + }) + it('should resolve user config plugins against config directory', () => { expect(new Pvm({ - config: path.join(__dirname, '__fixtures__', 'user-config-plugins', 'pvm'), + config: path.join(__dirname, '__fixtures__', 'user-config-plugins'), cwd: path.join(__dirname, '__fixtures__', 'user-config-plugins'), // @ts-ignore }).container.get(CONFIG_TOKEN).test).toBe(true) }) - it('should resolve default plugins against core package directory', () => { - const spy = jest.spyOn(Signales.prototype, '_log') - - // eslint-disable-next-line no-new - new Pvm() - - expect(spy).toHaveBeenCalledWith(expect.stringMatching(/common-plugins[\\/]index\.js.+?loaded. Resolved from .+?packages[\\/]pvm-core/), undefined, expect.anything()) - }) + it('user config should have ability to override plugin options in default config', () => { + const pluginPath = path.join(__dirname, '__fixtures__', 'plugin-with-options.js') + class PvmExt extends Pvm { + protected getDefaultConfig(): Config { + const cfg = super.getDefaultConfig() + + cfg.plugins_v2 = cfg.plugins_v2 ?? [] + cfg.plugins_v2.push({ + plugin: pluginPath, + options: { + value: 'base value', + }, + }) + + return cfg + } + } + + const pvm = new PvmExt({ + config: { + plugins_v2: [{ + plugin: pluginPath, + options: { + value: 'overriding value', + }, + }], + }, + }) - it('should resolve provider against resolved config path', () => { - expect(new Pvm({ - cwd: path.join(__dirname, '__fixtures__', 'non-cwd-config-and-provider', 'pvm'), - // @ts-ignore - }).container.get(CONFIG_TOKEN)['test-provider']).toBe(true) + expect(pvm.container.get('TEST_TOKEN')).toBe('overriding value') }) }) diff --git a/packages/pvm-core/lib/config/get-config.ts b/packages/pvm/app/config.ts similarity index 59% rename from packages/pvm-core/lib/config/get-config.ts rename to packages/pvm/app/config.ts index b8a795046..73c3f6115 100644 --- a/packages/pvm-core/lib/config/get-config.ts +++ b/packages/pvm/app/config.ts @@ -1,40 +1,19 @@ -import fs from 'fs' import path from 'path' -import vm from 'vm' -import { URL } from 'url' import Ajv from 'ajv' import * as TOML from '@iarna/toml' import { cosmiconfigSync, defaultLoaders } from 'cosmiconfig' -import yaml from 'js-yaml' import json5 from 'json5' -import { logger } from '../logger' -import { wdShell } from '../shell/index' -import { cachedRealPath } from '../fs' -import { isPlainObject } from '../utils' -import type { PvmProviderInfo } from '../plugins/provider' -import { taggedCacheManager, CacheTag, mema } from '../memoize' - -import type { Config } from './types' -import type { RecursivePartial } from '@pvm/types' -import { getWorktreeRoot, getMainWorktreePath, cwdToGitRelativity } from '../git/worktree' -import { env } from '../env' -import { Pvm } from '../app/index' -import { CONFIG_TOKEN } from '@pvm/tokens-core' - -// with high probability this line will be invoked in any api call -// kind a hacky solution -// todo: remove in PVM-264 -import '../node-boot' - -export interface GetConfigOpts { - config?: string, -} +import { logger } from '../lib/logger' +import { wdShell } from '../lib/shell/index' +import { isPlainObject } from '../lib/utils' -const appCache = taggedCacheManager.make([CacheTag.pvmConfig]) +import type { Config, RecursivePartial } from '../types' +import { cwdToGitRelativity } from '../lib/git/worktree' +import { defaultConfig as rawDefaults } from '../pvm-defaults' -const allLoaders = { +const allLoaders: Record any> = { ...defaultLoaders, '.toml': tomlLoader, } @@ -49,22 +28,22 @@ function parseConfig(filepath: string, content: string): Record return loader(filepath, content) } -export function mergeDefaults>(a: T, b: Record): T { - const result = { ...a } +export function mergeDeep>(a: T, b: Record): T { + const result = { ...b } - Object.keys(b).forEach((key: keyof T & string) => { + Object.keys(a).forEach((key: keyof T & string) => { if (result[key] === void 0) { - if (Array.isArray(b[key])) { - result[key] = [...b[key]] as any - } else if (isPlainObject(b[key])) { - result[key] = { ...b[key] } + if (Array.isArray(a[key])) { + result[key] = [...a[key]] as any + } else if (isPlainObject(a[key])) { + result[key] = { ...a[key] } } else { - result[key] = b[key] + result[key] = a[key] } } else if (Array.isArray(a[key]) && Array.isArray(b[key])) { - result[key] = result[key].concat(b[key]) + result[key] = a[key].concat(result[key]) } else if (isPlainObject(a[key]) && isPlainObject(b[key])) { - result[key] = mergeDefaults(a[key], b[key]) + result[key] = mergeDeep(a[key], b[key]) } }) @@ -133,70 +112,17 @@ function tomlLoader(_: string, content: string): TOML.JsonMap { const moduleName = 'pvm' -const yamlLoader = (_, contents: string): any => { - return yaml.safeLoad(contents) -} - -const json5Loader = (_, contents: string): any => { +const json5Loader = (_: any, contents: string): any => { return json5.parse(contents) } -function takeOrigin(maybeUrl: string): string { - try { - return new URL(maybeUrl).origin - } catch (e) { - return '' - } -} - -const loaders = { - '.js': (filePath: string, contents: string) => { - if (/^https?:\/\//.test(filePath)) { - const script = new vm.Script(contents) - const exports = {} - const context = { - module: { - exports, - }, - exports, - } - script.runInContext(vm.createContext(context, { - name: 'pvm-config-loader', - origin: takeOrigin(filePath), - }), { - timeout: 10000, - }) - return context.module.exports // module.exports может быть перезаписан внутри скрипта, поэтому в таком виде - } else { - return require(filePath) - } - }, - '.json': (_, contents: string) => { - return JSON.parse(contents) - }, - '.yml': yamlLoader, - '.yaml': yamlLoader, - '.toml': tomlLoader, - '.json5': json5Loader, -} - -function pickLoaderAndLoad(contents: string, contentsPath: string): Record { - const extname = path.extname(contentsPath) - const loader = loaders[extname] - if (!loader) { - throw new Error(`There is no loader for "${extname}" extension`) - } - - return loader(contentsPath, contents) -} - const compiledSchemaMap = new Map() export function validateAgainstSchema(config: Config): void { let compiledSchema = compiledSchemaMap.get(config.cwd) if (!compiledSchema) { const ajv = new Ajv() - const schema = TOML.parse(require('@pvm/types/lib/config-schema.json')) + const schema = TOML.parse(require('../types/config-schema.json')) compiledSchema = ajv.compile(schema) compiledSchemaMap.set(config.cwd, compiledSchema) } @@ -309,16 +235,12 @@ export function migrateDeprecated(config: Config): void { } } -function clearConfigCacheFor(cwd: string): void { - appCache.clear(cwd) -} - export interface ConfigResult { filepath: string | null, config: RecursivePartial, } -function loadRawConfig(cwd: string, ref: string | undefined = void 0): ConfigResult { +export function loadRawConfig(cwd: string, ref: string | undefined = void 0): ConfigResult { const cosmicResult = cosmiconfigSync(moduleName, { searchPlaces: [ `.${moduleName}.json`, @@ -362,68 +284,8 @@ function loadRawConfig(cwd: string, ref: string | undefined = void 0): ConfigRes } } -export function defaultsFromProvider(provider: PvmProviderInfo): RecursivePartial | undefined { - if (provider.pkg.pvm.configDefaults) { - const configDefaultsPath = path.resolve(provider.path, provider.pkg.pvm.configDefaults) - if (!fs.existsSync(configDefaultsPath)) { - throw new Error(`configDefaults from "${provider.pkg.name}" provider path "${provider.pkg.pvm.configDefaults}" not found`) - } - const contents = fs.readFileSync(configDefaultsPath, { encoding: 'utf8' }) - return pickLoaderAndLoad(contents, configDefaultsPath) - } -} - -const cachedMainWorktreePath = mema((dir: string) => getMainWorktreePath(dir)) -const cachedWorktreeRoot = mema((dir: string) => getWorktreeRoot(dir)) - -/** - * Only for internal usage. Will be removed after full migration to single entrypoint - * @param opts - */ -function getAppImpl(opts: { - config?: string, - cwd: string, -}): Pvm { - const cwd = cachedRealPath(opts.cwd) - const worktreeRoot = cachedWorktreeRoot(cwd) - const relativeCwdPath = path.relative(worktreeRoot, cwd) - // if cwd if /package, than consider to search in /package directory in main worktree (not just in root - // because it might be not the same place as cwd) - const configLookupDir = opts.config ?? path.resolve(cachedMainWorktreePath(cwd), relativeCwdPath) - const cacheKey = { config: configLookupDir } - let app: Pvm | undefined = appCache.get(cwd, cacheKey) - if (!app) { - logger.debug(`search config from ${configLookupDir}`) - app = new Pvm({ - cwd, - config: configLookupDir, - }) - appCache.set(cwd, cacheKey, app) - } - - return app -} - -function getConfigImpl(cwd: string, opts: GetConfigOpts = {}): Config { - return getAppImpl({ cwd, config: opts.config }).container.get(CONFIG_TOKEN) -} - -function getConfig(cwd = env.PVM_CONFIG_SEARCH_FROM || process.cwd(), opts?: GetConfigOpts): Config { - return getConfigImpl(cwd, opts) +function readDefaults(): Config { + return rawDefaults as Config } -function getApp(cwd = env.PVM_CONFIG_SEARCH_FROM || process.cwd(), opts: GetConfigOpts = {}): Pvm { - return getAppImpl({ cwd, config: opts.config }) -} - -/** - * @deprecated Please use `getConfig` instead - */ -export const getConfigWithoutIncludes = getConfig - -export default getConfig -export { - getApp, - clearConfigCacheFor, - loadRawConfig, -} +export const defaultConfig = readDefaults() diff --git a/packages/pvm/app/index.ts b/packages/pvm/app/index.ts new file mode 100644 index 000000000..0e1c87f5e --- /dev/null +++ b/packages/pvm/app/index.ts @@ -0,0 +1,243 @@ +import path from 'path' +import type { PluginConfig, PluginFactory, Config, RecursivePartial, PluginDeclaration } from '../types' +import { Container, DI_TOKEN, provide } from '../lib/di' +import { CONFIG_TOKEN, CWD_TOKEN, NOTIFICATOR_TOKEN, REPOSITORY_FACTORY_TOKEN } from '../tokens' +import { + loadRawConfig, mergeDeep, + migrateDeprecated, + readEnv, + validateAgainstSchema, +} from './config' +import { defaultConfig } from '../pvm-defaults' +import { logger, loggerFor } from '../lib/logger' +import chalk from 'chalk' +import { getNewTag } from '../mechanics/add-tag/get-new-tag' +import { loadPkg } from '../lib/pkg' +import getFiles from '../mechanics/files/files' +import type { Notificator } from '../mechanics/notifications' +import { pkgset } from '../mechanics/pkgset/pkgset' +import { getPackages } from '../mechanics/packages' +import { getCurrentRelease } from '../mechanics/releases' +import type { Repository } from '../mechanics/repository' +import { getUpdateState } from '../mechanics/update' +import { download, upload } from '../mechanics/artifacts/pub/artifacts' +import { runCli } from './run-cli' +import providers from './providers' + +const log = loggerFor('pvm:app') + +export function isPlainObject(x: unknown): x is Record { + return !!x && !Array.isArray(x) && typeof x === 'object' +} + +// todo: get rid of container passing down to functions +export class Pvm { + container: Container + cwd: string + configDir: string + pluginFactories = new Map() + + constructor(opts: { + config?: RecursivePartial | string | null, + cwd?: string, + } = {}) { + const { config, cwd = process.cwd() } = opts ?? {} + + this.cwd = cwd + this.configDir = typeof config === 'string' ? config : cwd + + this.container = new Container() + + this.container.register(provide({ + provide: CWD_TOKEN, + useValue: cwd, + })) + + this.container.register(provide({ + useValue: this.container, + provide: DI_TOKEN, + })) + + providers.forEach(p => this.container.register(p)) + + this.initConfigAndPlugins(config) + } + + /** + * Runs cli. Used to start pvm as cli app. + */ + static runCli(Class: typeof Pvm, argv: string[] = process.argv): void { + return runCli(Class, argv) + } + + /** + * Return next release tag name based on previous releases + */ + public getNewTag(targetRef: string): Promise { + return getNewTag(this.container, targetRef) + } + + /** + * Returns result config which will be used in pvm + */ + public getConfig(): Config { + return this.container.get(CONFIG_TOKEN) + } + + public loadPkg(pkgPath: Parameters[1], opts: Parameters[2] = {}): ReturnType { + opts.cwd = opts.cwd ?? this.cwd + + return loadPkg(this.container.get(CONFIG_TOKEN), pkgPath, opts) + } + + public getFiles(filesGlob: string | string[], opts: Record = {}): Promise { + opts.cwd = opts.cwd ?? this.cwd + + return getFiles(this.container, filesGlob, opts) + } + + public getNotificator(): Notificator { + return this.container.get(NOTIFICATOR_TOKEN) + } + + public getPkgSet(strategy: string, opts: Record = {}): ReturnType { + opts.cwd = opts.cwd ?? this.cwd + + return pkgset(this.container, strategy, opts) + } + + public getPackages(type: Parameters[1] = 'all', opts: Parameters[2] = {}): ReturnType { + opts.cwd = opts.cwd ?? this.cwd + + return getPackages(this.container, type, opts) + } + + public getCurrentRelease(opts: Parameters[1] = {}): ReturnType { + opts.cwd = opts.cwd ?? this.cwd + + return getCurrentRelease(this.container, opts) + } + + public getRepository(ref?: string): Repository { + return this.container.get(REPOSITORY_FACTORY_TOKEN)({ ref }) + } + + public getUpdateState(opts: Parameters[1] = {}): ReturnType { + opts.cwd = opts.cwd ?? this.cwd + + return getUpdateState(this.container, opts) + } + + public downloadArtifacts(args: Parameters[1]): ReturnType { + return download(this.container, args) + } + + public uploadArtifacts(args: Parameters[1]): ReturnType { + return upload(this.container, args) + } + + /** + * Configuration sources priority (from less prioritized): + * 1. Builtin default pvm config + * 2. Constructor provided plugins + * 3. User defined config and plugins + * 4. Config from environment variables + * + * General logic is - collect config and plugins from less prioritized sources to more prioritized. Resolve + * plugins recursively in-depth from each source and deep merge them in order they resolved. Plugins + * registered in di after all configurations merged so use allowed to modify plugin configurations introduced + * at less prioritized sources. + */ + protected initConfigAndPlugins(config: RecursivePartial | string | null | undefined): void { + let nextConfigExtensions: RecursivePartial[] = [] + // Config extensions from default config itself + let nextConfig = this.getDefaultConfig() + if (nextConfig.plugins_v2) { + nextConfigExtensions = this.resolvePlugins(nextConfig.plugins_v2, path.dirname(require.resolve('../pvm-defaults'))) + nextConfig = this.mergeConfigExtensions(nextConfig, ...nextConfigExtensions) + } + + // User defined config + const userConfig: { config: RecursivePartial, filepath: string | null } = (typeof config === 'string' || !config) ? loadRawConfig(this.configDir) : { config: config ?? {}, filepath: null } + nextConfigExtensions = this.resolvePlugins(userConfig.config.plugins_v2 ?? [], this.configDir) + nextConfig = this.mergeConfigExtensions(nextConfig, ...nextConfigExtensions, userConfig.config) + + // Env config + const envConfig = readEnv() as any + const envConfigExtensions = this.resolvePlugins(envConfig.plugins_v2 ?? [], this.cwd) + nextConfig = this.mergeConfigExtensions(nextConfig, ...envConfigExtensions, envConfig) + + migrateDeprecated(nextConfig) + + validateAgainstSchema(nextConfig) + + logger.debug('config.versioning.source is', nextConfig.versioning.source) + logger.debug('config.versioning.unified_versions_for is', JSON.stringify(nextConfig.versioning.unified_versions_for)) + + this.container.register(provide({ + useValue: nextConfig, + provide: CONFIG_TOKEN, + })) + + this.registerPlugins(nextConfig) + } + + /** + * Used to extend default config when extending Pvm class and want to provide additional + * defaults for end user + */ + protected getDefaultConfig(): Config { + return { + ...defaultConfig, + cwd: this.cwd, + configLookupDir: this.configDir, + } + } + + protected mergeConfigExtensions(...configExtensions: RecursivePartial[]): Config { + return configExtensions.reduce((acc, extension) => mergeDeep(acc, extension), {} as Config) as Config + } + + protected resolvePlugins(plugins: PluginConfig[], resolveRoot: string): RecursivePartial[] { + let configExtensions: RecursivePartial[] = [] + for (const pluginConfig of plugins) { + const { factory, configExt, resolvedPath } = this.resolvePlugin(pluginConfig, resolveRoot) + + // if subsequent config extension overrides plugin config its options will be extended and + // factory override previous one + this.pluginFactories.set(pluginConfig.plugin, factory) + + log.info(chalk`plugin {blue ${resolvedPath}} loaded. Resolved from ${resolveRoot}`) + + if (configExt) { + configExtensions.push(configExt) + if (configExt.plugins_v2) { + configExtensions = configExtensions.concat(this.resolvePlugins(configExt.plugins_v2, path.dirname(resolvedPath))) + } + } + } + return configExtensions + } + + protected registerPlugins(config: Config): void { + for (const pluginConfig of config.plugins_v2) { + const factory = this.pluginFactories.get(pluginConfig.plugin) + const pluginProviders = factory ? factory(pluginConfig.options || {}).providers : [] + for (const provider of pluginProviders) { + this.container.register(provider) + } + } + } + + protected resolvePlugin(pluginConfig: PluginConfig, resolveRoot: string): { factory?: PluginFactory, configExt?: RecursivePartial, resolvedPath: string } { + if (typeof pluginConfig.plugin === 'string') { + const pluginPath = require.resolve(pluginConfig.plugin, { paths: [resolveRoot] }) + const pluginModule = require(pluginPath) + return { ...((pluginModule.__esModule ? pluginModule.default : pluginModule) as PluginDeclaration), resolvedPath: pluginPath } + } + + const opts = isPlainObject(pluginConfig.plugin) ? pluginConfig.plugin : { factory: pluginConfig.plugin } + + return { ...opts, resolvedPath: resolveRoot } + } +} diff --git a/packages/pvm/app/providers.ts b/packages/pvm/app/providers.ts new file mode 100644 index 000000000..b4e69cb76 --- /dev/null +++ b/packages/pvm/app/providers.ts @@ -0,0 +1,36 @@ +import type { Provider } from '../lib/di' +import { provide } from '../lib/di' +import { CLI_EXTENSION_TOKEN, GLOBAL_FLAGS_TOKEN, CLI_TOKEN } from '../tokens' + +import { runCli } from '../lib/cli/cli-runner' +import { GlobalFlags } from '../lib/cli/global-flags' + +import vcsProviders from '../mechanics/vcs/providers' +import changelogProviders from '../mechanics/changelog/providers' +import publishProviders from '../mechanics/publish/providers' +import platformProviders from '../mechanics/platform/providers' +import repositoryProviders from '../mechanics/repository/providers' +import notificationsProviders from '../mechanics/notifications/providers' + +export default [ + provide({ + provide: CLI_TOKEN, + useFactory({ cliExtensions, globalFlags }) { + return ({ argv }: { argv: string[] }) => runCli(cliExtensions ?? [], globalFlags, argv) + }, + deps: { + cliExtensions: { token: CLI_EXTENSION_TOKEN, optional: true, multi: true } as const, + globalFlags: GLOBAL_FLAGS_TOKEN, + }, + }), + provide({ + provide: GLOBAL_FLAGS_TOKEN, + useClass: GlobalFlags, + }), + ...vcsProviders, + ...changelogProviders, + ...publishProviders, + ...platformProviders, + ...repositoryProviders, + ...notificationsProviders, +] as [...Provider[]] diff --git a/packages/pvm-core/lib/app/required-bin-versions.ts b/packages/pvm/app/required-bin-versions.ts similarity index 91% rename from packages/pvm-core/lib/app/required-bin-versions.ts rename to packages/pvm/app/required-bin-versions.ts index e1fb7f908..3afb1b53d 100644 --- a/packages/pvm-core/lib/app/required-bin-versions.ts +++ b/packages/pvm/app/required-bin-versions.ts @@ -1,3 +1,4 @@ +// @ts-ignore import binaryVersionCheck from 'bin-version-check' const REQUIRED_CMD = [ @@ -10,7 +11,7 @@ export async function verifyRequiredBins(): Promise { for (const [cmd, versionRange] of REQUIRED_CMD) { try { await binaryVersionCheck(cmd, versionRange) - } catch (error) { + } catch (error: any) { errors.push(error.message) } } diff --git a/packages/pvm/app/run-cli.ts b/packages/pvm/app/run-cli.ts new file mode 100644 index 000000000..89dd1dd98 --- /dev/null +++ b/packages/pvm/app/run-cli.ts @@ -0,0 +1,19 @@ +import { verifyRequiredBins } from './required-bin-versions' +import { CLI_TOKEN } from '../tokens' +import type { Pvm } from './index' +import yargs from 'yargs' + +export function runCli(PvmClass: typeof Pvm, argv: string[] = process.argv) { + const cfgFromCli = yargs(argv).argv.config as string | undefined + const pvm = new PvmClass({ + config: cfgFromCli ?? process.cwd(), + }) + verifyRequiredBins().then(() => { + pvm.container.get(CLI_TOKEN)({ + argv, + }) + }).catch(e => { + console.error(e) + process.exitCode = 1 + }) +} diff --git a/packages/pvm/bin/pvm.js b/packages/pvm/bin/pvm.js index df3968769..a960b324f 100755 --- a/packages/pvm/bin/pvm.js +++ b/packages/pvm/bin/pvm.js @@ -1,5 +1,5 @@ #!/usr/bin/env node -const { getApp } = require('@pvm/core/lib/config/get-config') +const { Pvm } = require('../app') -getApp().runCli() +Pvm.runCli(Pvm) diff --git a/packages/pvm-artifacts/cli/common.ts b/packages/pvm/commands/artifacts/common.ts similarity index 68% rename from packages/pvm-artifacts/cli/common.ts rename to packages/pvm/commands/artifacts/common.ts index 4d2702e89..3c8e4e350 100644 --- a/packages/pvm-artifacts/cli/common.ts +++ b/packages/pvm/commands/artifacts/common.ts @@ -1,4 +1,4 @@ -import { ArtifactsStorages } from '../lib/storage-manager' +import { ArtifactsStorages } from '../../mechanics/artifacts/storage-manager' export const cliArtifactsChoices = Object.values(ArtifactsStorages).map(key => { return key.replace(/.[A-Z]/g, (m) => `${m.charAt(0)}-${m.substr(1)}`).toLowerCase() diff --git a/packages/pvm/commands/artifacts/pvm-artifacts-download.ts b/packages/pvm/commands/artifacts/pvm-artifacts-download.ts new file mode 100644 index 000000000..f4f2f7262 --- /dev/null +++ b/packages/pvm/commands/artifacts/pvm-artifacts-download.ts @@ -0,0 +1,34 @@ +import type { ArtifactsTransferArgs } from '../../mechanics/artifacts/pub/artifacts' +import { download } from '../../mechanics/artifacts/pub/artifacts' +import { cliArtifactsChoices } from './common' + +// eslint-disable-next-line node/no-extraneous-import +import type { Argv } from 'yargs' +import type { Container } from '../../lib/di' +import type { CommandFactory } from '../../types/cli' + +export default (di: Container): CommandFactory => builder => builder.command( + 'download ', + 'Download a given kind of artifacts from remote storage', + (yargs: Argv) => { + return yargs + .positional('kind', { + desc: 'Kind of artifact for downloading', + type: 'string' as const, + choices: cliArtifactsChoices, + }) + .option('quiet', { + desc: `Don't print warnings`, + type: 'boolean' as const, + default: false, + }) + .option('force', { + desc: `Download an artifact even if it is not turned on in config`, + type: 'boolean' as const, + default: false, + }) + }, + async function main(args): Promise { + await download(di, args as ArtifactsTransferArgs) + } +) diff --git a/packages/pvm/commands/artifacts/pvm-artifacts-upload.ts b/packages/pvm/commands/artifacts/pvm-artifacts-upload.ts new file mode 100644 index 000000000..ffc3b7b7d --- /dev/null +++ b/packages/pvm/commands/artifacts/pvm-artifacts-upload.ts @@ -0,0 +1,32 @@ +import type { ArtifactsTransferArgs } from '../../mechanics/artifacts/pub/artifacts' +import { upload } from '../../mechanics/artifacts/pub/artifacts' +import { cliArtifactsChoices } from './common' + +import type { Container } from '../../lib/di' +import type { CommandFactory } from '../../types/cli' + +export default (di: Container): CommandFactory => builder => builder.command( + 'upload ', + 'Upload a given kind of artifacts from remote storage', + (yargs) => { + return yargs + .positional('kind', { + desc: 'Kind of artifact for uploading', + type: 'string' as const, + choices: cliArtifactsChoices, + }) + .option('quiet', { + desc: `Don't print warnings`, + type: 'boolean' as const, + default: false, + }) + .option('force', { + desc: `Upload artifacts even if they are not turned on in config`, + type: 'boolean' as const, + default: false, + }) + }, + async function main(args: Record): Promise { + await upload(di, args as ArtifactsTransferArgs) + } +) diff --git a/packages/pvm/commands/artifacts/pvm-artifacts.ts b/packages/pvm/commands/artifacts/pvm-artifacts.ts new file mode 100644 index 000000000..64cf2a275 --- /dev/null +++ b/packages/pvm/commands/artifacts/pvm-artifacts.ts @@ -0,0 +1,17 @@ +import pvmArtifactsDownload from './pvm-artifacts-download' +import pvmArtifactsUpload from './pvm-artifacts-upload' + +import type { Container } from '../../lib/di' +import type { CommandFactory } from '../../types/cli' + +export default (di: Container): CommandFactory => yargs => yargs.command( + 'artifacts ', + 'Commands for working with pvm artifacts', + (yargs) => { + pvmArtifactsDownload(di)(yargs) + pvmArtifactsUpload(di)(yargs) + + return yargs + }, + function() {} +) diff --git a/packages/pvm/commands/changelog/pvm-changelog-download.ts b/packages/pvm/commands/changelog/pvm-changelog-download.ts new file mode 100644 index 000000000..37c7de532 --- /dev/null +++ b/packages/pvm/commands/changelog/pvm-changelog-download.ts @@ -0,0 +1,31 @@ +#!/usr/bin/env node + +import { download, ArtifactsStorages } from '../../mechanics/artifacts/pub/artifacts' + +import type { Container } from '../../lib/di' +import type { CommandFactory } from '../../types/cli' + +export default (di: Container): CommandFactory => builder => builder.command( + 'download', + 'Download Changelog artifacts from remote storage', + (yargs) => { + return yargs + .option('quiet', { + desc: `Don't print warnings`, + type: 'boolean' as const, + default: false, + }) + .option('force', { + desc: `Download artifacts even if they are not turned on`, + type: 'boolean' as const, + default: false, + }) + }, + async function main(args): Promise { + await download(di, { + force: args.force, + quiet: args.quiet, + kind: ArtifactsStorages.Changelogs, + }) + } +) diff --git a/packages/pvm/commands/changelog/pvm-changelog-make.ts b/packages/pvm/commands/changelog/pvm-changelog-make.ts new file mode 100644 index 000000000..2dc8ca7fc --- /dev/null +++ b/packages/pvm/commands/changelog/pvm-changelog-make.ts @@ -0,0 +1,61 @@ +import chalk from 'chalk' +import { log } from '../../lib/logger' +import { makeChangelog } from '../../mechanics/changelog' +import { StorageManager } from '../../mechanics/artifacts/storage-manager' +import { releaseDataMaker } from '../../mechanics/releases/release-data' +import { getUpdateState } from '../../mechanics/update' +import { createReleaseContext } from '../../mechanics/update/release/release-context' + +import type { ReleaseData } from '../../mechanics/releases/types' + +import type { Container } from '../../lib/di' +import { CONFIG_TOKEN } from '../../tokens' +import type { CommandFactory } from '../../types/cli' + +export default (di: Container): CommandFactory => builder => builder.command( + 'make', + 'Generate changelogs from ReleaseList artifact', + (yargs) => { + return yargs + .option('append-upcoming-release', { + desc: `Generate ReleasedData based on unreleased changes and count it in case incremental changelog renderering`, + type: 'boolean' as const, + default: false, + }) + }, + async function main(flags): Promise { + log(chalk`{yellow Generating changelog}`) + const config = di.get(CONFIG_TOKEN) + + const storageManager = new StorageManager({ + di, + }) + + const releaseListStorage = await storageManager.initFor(StorageManager.ArtifactsStorages.ReleaseList) + await releaseListStorage.download() + + let releaseData: ReleaseData | undefined + + if (flags.appendUpcomingRelease) { + const updateState = await getUpdateState(di, { + includeUncommited: true, + }) + + const releaseContext = await createReleaseContext(updateState) + if (releaseContext) { + releaseData = await releaseDataMaker.fromReleaseContext(releaseContext) + } + } + + const changelogsStorage = await storageManager.initFor(StorageManager.ArtifactsStorages.Changelogs) + + if ((config.changelog.enabled || config.changelog.for_packages.enabled)) { + await changelogsStorage.download() + await makeChangelog(di, releaseData) + } else { + log(`Changelog is not enabled. Exiting`) + } + + await storageManager.finish() + } +) diff --git a/packages/pvm/commands/changelog/pvm-changelog-upload.ts b/packages/pvm/commands/changelog/pvm-changelog-upload.ts new file mode 100644 index 000000000..42391b78e --- /dev/null +++ b/packages/pvm/commands/changelog/pvm-changelog-upload.ts @@ -0,0 +1,29 @@ +import { upload, ArtifactsStorages } from '../../mechanics/artifacts/pub/artifacts' + +import type { Container } from '../../lib/di' +import type { CommandFactory } from '../../types/cli' + +export default (di: Container): CommandFactory => builder => builder.command( + 'upload', + 'Upload Changelog artifacts to remote storage', + (yargs) => { + return yargs + .option('quiet', { + desc: `Don't print warnings`, + type: 'boolean' as const, + default: false, + }) + .option('force', { + desc: `Upload artifacts even they are not turned on`, + type: 'boolean' as const, + default: false, + }) + }, + async function main(args): Promise { + await upload(di, { + force: args.force, + quiet: args.quiet, + kind: ArtifactsStorages.Changelogs, + }) + } +) diff --git a/packages/pvm/commands/changelog/pvm-changelog.ts b/packages/pvm/commands/changelog/pvm-changelog.ts new file mode 100644 index 000000000..2ba46048e --- /dev/null +++ b/packages/pvm/commands/changelog/pvm-changelog.ts @@ -0,0 +1,21 @@ +#!/usr/bin/env node + +import pvmChangelogMake from './pvm-changelog-make' +import pvmChangelogDownload from './pvm-changelog-download' +import pvmChangelogUpload from './pvm-changelog-upload' +// eslint-disable-next-line node/no-extraneous-import +import type { Argv } from 'yargs' +import type { Container } from '../../lib/di' +import type { CommandFactory } from '../../types/cli' + +export default (di: Container): CommandFactory => builder => builder.command( + 'changelog ', + 'Commands for working with Changelog artifacts', + (builder: Argv) => { + pvmChangelogMake(di)(builder) + pvmChangelogDownload(di)(builder) + pvmChangelogUpload(di)(builder) + + return builder + } +) diff --git a/packages/pvm/commands/index.ts b/packages/pvm/commands/index.ts new file mode 100644 index 000000000..5c27498c8 --- /dev/null +++ b/packages/pvm/commands/index.ts @@ -0,0 +1,58 @@ +import { declarePlugin, provide } from '../lib/di' +import { CLI_EXTENSION_TOKEN, DI_TOKEN } from '../tokens' +import addTagCommand from './pvm-add-tag' +import artifactsCommand from './artifacts/pvm-artifacts' +import changelogCommand from './changelog/pvm-changelog' +import filesCommand from './pvm-files' +import notificationsCommand from './notifications/pvm-notification' +import pkgsetCommand from './pvm-pkgset' +import releasesCommand from './releases/pvm-releases' +import updateCommand from './update/pvm-update' +import localUpdateCommand from './update/pvm-update-local' +import vcsCommand from './pvm-vcs' +import lintCommand from './pvm-lint' +import markPrCommand from './pvm-mark-pr' +import notesCommand from './pvm-notes' +import packagesCommand from './pvm-packages' +import publishCommand from './pvm-publish' +import rewriteNotesCommand from './pvm-rewrite-notes' +import rewriteSetVersions from './pvm-set-versions' +import showCommand from './pvm-show' +import writeVersionsCommand from './pvm-write-versions' + +export default declarePlugin({ + factory: function() { + return { + providers: [ + provide({ + provide: CLI_EXTENSION_TOKEN, + useFactory: ({ di }) => [ + addTagCommand(di), + artifactsCommand(di), + changelogCommand(di), + filesCommand(di), + notificationsCommand(di), + pkgsetCommand(di), + releasesCommand(di), + updateCommand(di), + localUpdateCommand(di), + vcsCommand(di), + lintCommand(di), + markPrCommand(di), + notesCommand(di), + packagesCommand(di), + publishCommand(di), + rewriteNotesCommand(di), + rewriteSetVersions(di), + showCommand(di), + writeVersionsCommand(di), + ], + multi: true, + deps: { + di: DI_TOKEN, + }, + }), + ], + } + }, +}) diff --git a/packages/pvm/commands/notifications/pvm-notification-send.ts b/packages/pvm/commands/notifications/pvm-notification-send.ts new file mode 100644 index 000000000..7f8ff8ae5 --- /dev/null +++ b/packages/pvm/commands/notifications/pvm-notification-send.ts @@ -0,0 +1,69 @@ +import fs from 'fs' +import getStdin from 'get-stdin' + +import type { Container } from '../../lib/di' +import type { CommandFactory, Message } from '../../types' +import { NOTIFICATOR_TOKEN } from '../../tokens' + +export default (di: Container): CommandFactory => builder => builder.command( + 'send', + 'Send message to configured messengers', + (yargs) => { + return yargs + .example( + `$0 notification send -m message.json`, + `Send message to messengers according to pvm configuration` + ) + .option('target', { + alias: 't', + type: 'array', + desc: 'target messenger or list of them. Possible values are: all, first-available and concrete messenger name', + }) + .option('file', { + alias: 'f', + desc: 'message json file. Available fields described in doc https://tinkoff.github.io/pvm/docs/api/modules/pvm_pvm#message', + type: 'string', + }) + .option('channel', { + alias: 'c', + desc: 'channel where to send message', + type: 'string', + }) + .option('message', { + alias: 'm', + desc: 'text for sending. Use "-" for reading from stdin. Default: "-" if there is no message nor text passed.', + type: 'string', + }) + }, + async function send(flags): Promise { + const contentParam = (!flags.file && !flags.message) ? '-' : flags.message + + let content + if (contentParam) { + content = contentParam === '-' ? await getStdin() : contentParam + } + + let messageBuild: { channel?: string, content?: string } = {} + if (flags.file) { + const messageStr = fs.readFileSync(flags.file).toString('utf8') + messageBuild = JSON.parse(messageStr) + } + + if (flags.channel) { + messageBuild.channel = flags.channel + } + + if (content) { + messageBuild.content = content + } + + const message: Message = messageBuild as Message + + const messenger = di.get(NOTIFICATOR_TOKEN) + + const target = flags.target?.map(String) + return messenger.sendMessage(message, { + target: target ? target.length === 1 ? target[0] : target : undefined, + }) + } +) diff --git a/packages/pvm/commands/notifications/pvm-notification.ts b/packages/pvm/commands/notifications/pvm-notification.ts new file mode 100644 index 000000000..66b5b487f --- /dev/null +++ b/packages/pvm/commands/notifications/pvm-notification.ts @@ -0,0 +1,13 @@ +// eslint-disable-next-line node/no-extraneous-import +import type { Argv } from 'yargs' +import type { Container } from '../../lib/di' +import pvmNotificationSend from './pvm-notification-send' +import type { CommandFactory } from '../../types/cli' + +export default (di: Container): CommandFactory => builder => builder.command( + 'notification ', + 'Send messages to messenger(s)', + (yargs: Argv) => { + return pvmNotificationSend(di)(yargs) + } +) diff --git a/packages/pvm/commands/pvm-add-tag.ts b/packages/pvm/commands/pvm-add-tag.ts new file mode 100644 index 000000000..d64a2bf82 --- /dev/null +++ b/packages/pvm/commands/pvm-add-tag.ts @@ -0,0 +1,29 @@ +#!/usr/bin/env node + +import { log } from '../lib/logger' +import { wdShell } from '../lib/shell' +import { getNewTag } from '../mechanics/add-tag/get-new-tag' +import type { Container } from '../lib/di' +import { CONFIG_TOKEN, PLATFORM_TOKEN } from '../tokens' +import type { CommandFactory } from '../types/cli' + +async function createTag(di: Container, tag: string, ref: string) { + log(`creating tag ${tag} for ${ref} ref by platform api`) + return di.get(PLATFORM_TOKEN).addTag(tag, ref) +} + +export default (di: Container): CommandFactory => (builder) => builder.command( + 'add-tag', + 'Creates a new release tag via GitLab API based on commits made after the last release tag', + {}, + async () => { + const config = di.get(CONFIG_TOKEN) + const targetRef = wdShell(config.cwd, 'git rev-parse HEAD') + const newTag = await getNewTag(di, targetRef) + if (newTag) { + return createTag(di, newTag, targetRef) + } else { + log('new tag not calculated (see logs below)') + } + } +) diff --git a/packages/pvm/commands/pvm-files.ts b/packages/pvm/commands/pvm-files.ts new file mode 100644 index 000000000..3184273cb --- /dev/null +++ b/packages/pvm/commands/pvm-files.ts @@ -0,0 +1,44 @@ +import chalk from 'chalk' +import { getStrategiesDescriptionList } from '../mechanics/pkgset/strategies' +import { parseSubArgs } from '../lib/text/sub-args' +import getFiles from '../mechanics/files/files' + +import type { Container } from '../lib/di' +import type { CommandFactory } from '../types/cli' + +export default (di: Container): CommandFactory => builder => builder.command( + 'files', + 'Output files by glob in the list of packages (packages are choosing by pkgset strategies logic)', + (yargs) => { + return yargs + .example('$0 files -f *.stories.js', 'filter files in all packages') + .example('$0 files -f *.js -s changed -S from=v1.2.3', 'Return .js files in packages which have been changed from v1.2.3 to HEAD') + .option('files', { + alias: 'f', + desc: chalk`Glob pattern or array of patterns for result files. Returned files would be filtered by packages collected by passed strategy.`, + demandOption: true, + type: 'array', + }) + .option('strategy', { + alias: 's', + desc: chalk`Filtering strategy. Possible strategies are: ${getStrategiesDescriptionList().join('\n\n ')}`, + default: 'all', + }) + .option('absolute', { + desc: 'Return absolute paths to file', + default: true, + type: 'boolean' as const, + }) + .option('strategy-option', { + alias: 'S', + desc: 'Pass option through to the used strategy.', + type: 'array' as const, + default: [], + coerce: parseSubArgs, + }) + }, + async function main(argv): Promise { + (await getFiles(di, argv.files.map(String), { ...argv, ...argv['strategy-option'] })) + .forEach(f => console.log(f)) + } +) diff --git a/packages/pvm/commands/pvm-lint.ts b/packages/pvm/commands/pvm-lint.ts new file mode 100644 index 000000000..6ae17e370 --- /dev/null +++ b/packages/pvm/commands/pvm-lint.ts @@ -0,0 +1,31 @@ +import { Repository } from '../mechanics/repository' +import { logger } from '../lib/logger' +import { lint } from '../mechanics/repository/linter' +import type { Container } from '../lib/di' +import type { CommandFactory } from '../types/cli' + +export default (di: Container): CommandFactory => builder => builder.command( + 'lint', + 'Checks that package versions correspond to the selected settings and policies in the project.', + { + fix: { + default: false, + desc: 'Automatically fix found bugs or versions if possible', + }, + }, + async (flags) => { + const repo = await Repository.init(di) + const lintResult = lint(repo, { + fix: flags.fix, + }) + + if (!lintResult.errors.length) { + logger.info('all checks passed') + } else { + lintResult.errors.forEach(error => { + logger.error(error) + }) + process.exitCode = 1 + } + } +) diff --git a/packages/pvm/commands/pvm-mark-pr.ts b/packages/pvm/commands/pvm-mark-pr.ts new file mode 100644 index 000000000..a576d3ccf --- /dev/null +++ b/packages/pvm/commands/pvm-mark-pr.ts @@ -0,0 +1,122 @@ +#!/usr/bin/env node +import { getUpdateState } from '../mechanics/update' +import * as mdTable from '../mechanics/update/update-methods/md-table' +import * as graphDot from '../mechanics/update/update-methods/dot' +import { analyzeUpdate as analyzeUpdatedPackages } from '../mechanics/update/update-methods/analyze' +import { renderDot } from '../lib/viz' +import { renderReleaseContext, RenderTarget } from '../mechanics/changelog' +import { createReleaseContext } from '../mechanics/update/release/release-context' +import { VcsOnlyStenographer } from '../mechanics/vcs/vcs-only-stenographer' + +import type { UpdateState } from '../mechanics/update/update-state' +import type { Pkg } from '../lib/pkg' +import type { Container } from '../lib/di' +import { CONFIG_TOKEN, CWD_TOKEN, MARK_PR_HOOK_TOKEN, PLATFORM_TOKEN } from '../tokens' +import type { PlatformInterface } from '../mechanics/platform' +import type { CommandFactory } from '../types/cli' +import type { Config } from '../types' + +async function analyzeUpdate(_di: Container, platform: PlatformInterface, updateState: UpdateState): Promise { + const { warnings } = analyzeUpdatedPackages(updateState) + + if (warnings.length !== 0) { + const warningsAsList = warnings.map(warning => `- ${warning}`).join('\n') + await platform.syncText('analyze-report', ` +**Dependencies between packages after update can lead to malfunctioning when installing dependencies or building a project.** + +${warningsAsList} +` + ) + } else { + await platform.syncText('analyze-report', 'Dependencies between packages looks good.') + } +} + +async function packagesAsLabels(_di: Container, platform: PlatformInterface, updateState: UpdateState): Promise { + return platform.ensureMrLabels(Array.from(updateState.getReleasePackages().keys()).map((pkg: Pkg) => pkg.shortName)) +} + +async function packagesTable(di: Container, platform: PlatformInterface, updateState: UpdateState): Promise { + const md = await mdTable.run(di, updateState) + return platform.syncText('packages-for-release', md || 'no packages for release') +} + +async function packagesGraph(_di: Container, platform: PlatformInterface, updateState: UpdateState): Promise { + if (!updateState.isSomethingForRelease) { + return platform.syncText('packages-graph', 'no packages for release') + } + const dot = await graphDot.updateStateToDot(updateState) + const svg: string = await renderDot(dot) + await platform.syncAttachment('packages-graph', Buffer.from(svg), { + filename: 'packages-graph.svg', + }) +} + +async function attachChangelog(di: Container, platform: PlatformInterface, updateState: UpdateState): Promise { + const releaseContext = await createReleaseContext(updateState) + const changelog = releaseContext ? await renderReleaseContext(di, releaseContext, RenderTarget.markPr) : '' + return platform.syncText('changelog-for-pr', changelog) +} + +async function attachMigrationProcess(platform: PlatformInterface, cwd: string): Promise { + const vcsStenographist = new VcsOnlyStenographer(cwd) + + if (!vcsStenographist.isEmpty) { + await platform.syncText('pvm configuration migration transcript', vcsStenographist.join()) + } +} + +interface Marker { + fn(di: Container, platform: PlatformInterface, updateState: UpdateState): Promise, + confKey: keyof Config['mark_pr'], +} + +const markers: Marker[] = [ + { + fn: analyzeUpdate, + confKey: 'analyze_update', + }, + { + fn: packagesAsLabels, + confKey: 'packages_as_labels', + }, + { + fn: packagesTable, + confKey: 'packages_table', + }, + { + fn: packagesGraph, + confKey: 'packages_graph', + }, + { + fn: attachChangelog, + confKey: 'attach_changelog', + }, +] + +export default (di: Container): CommandFactory => builder => builder.command( + 'mark-pr', + `Marks merge or pull request by project labels, packages about to update, etc`, + {}, + async function main(): Promise { + const conf = di.get(CONFIG_TOKEN).mark_pr + const platform = di.get(PLATFORM_TOKEN) + const cwd = di.get(CWD_TOKEN) + await platform.beginMrAttribution() + + await attachMigrationProcess(platform, cwd) + + const updateState = await getUpdateState(di) + + for (const marker of markers) { + if (conf[marker.confKey]) { + await marker.fn(di, platform, updateState) + } + } + + await di.get({ + token: MARK_PR_HOOK_TOKEN, + optional: true, + })?.forEach(hook => hook(platform, updateState)) + } +) diff --git a/packages/pvm/commands/pvm-notes.ts b/packages/pvm/commands/pvm-notes.ts new file mode 100644 index 000000000..4f58bc19d --- /dev/null +++ b/packages/pvm/commands/pvm-notes.ts @@ -0,0 +1,44 @@ +// команда обновляет release notes для последнего тэга через vcs + +import { log } from '../lib/logger' +import { lastReleaseTag } from '../lib/git/last-release-tag' +import getPreviousRefForFirstRelease from '../lib/git/previous-ref-for-initial-release' +import { env } from '../lib/env' +import type { Container } from '../lib/di' +import { CONFIG_TOKEN, PLATFORM_TOKEN } from '../tokens' +import type { Config, CommandFactory } from '../types' + +async function findPrevRef(config: Config, targetTag: string) { + const prevRelease = lastReleaseTag(config, `${targetTag}^`) + + const prevRef = prevRelease || getPreviousRefForFirstRelease(config, targetTag) + + log(`previous release is ${prevRelease || ''}`) + + return prevRef +} + +export default (di: Container): CommandFactory => builder => builder.command( + 'notes', + 'Create release notes for latest release tag based on commit messages between tags', + {}, + async function pvmNotes() { + const config = di.get(CONFIG_TOKEN) + const targetTagName = env.CI_COMMIT_TAG || lastReleaseTag(config) + const platform = di.get(PLATFORM_TOKEN) + + if (!targetTagName) { + throw new Error('at least one tag is required for making the release') + } + + const prevRef = await findPrevRef(di.get(CONFIG_TOKEN), targetTagName) + if (prevRef) { + await platform.makeReleaseForTagName(targetTagName, prevRef, { + skipIfExists: true, + }) + + return targetTagName + } + return false + } +) diff --git a/packages/pvm/commands/pvm-packages.ts b/packages/pvm/commands/pvm-packages.ts new file mode 100644 index 000000000..379bd2f6e --- /dev/null +++ b/packages/pvm/commands/pvm-packages.ts @@ -0,0 +1,45 @@ +import pprint from '../mechanics/pkgset/pprint' +import type { PackagesType } from '../mechanics/packages' +import { getPackages } from '../mechanics/packages' +import type { Container } from '../lib/di' +import type { CommandFactory } from '../types' + +async function * iterateFromPromise(willBeList: Promise>): AsyncIterable { + const list = await willBeList + for (const item of list) { + yield item + } +} + +export default (di: Container): CommandFactory => builder => { + const packageTypes: PackagesType[] = ['about-to-update', 'update', 'changed', 'changed-since-release', 'affected', 'released', 'updated', 'all'] + return builder.command( + 'packages', + 'Shows the list of packages by the specified criterion', + { + format: { + desc: `Pretty-print the package information in a given format. Format is string, with special symbols: + %p - path to package + %n - package name + %s - package name without namespace if it's present + %v - package version`, + default: '%p', + }, + list: { + desc: 'kind of packages to show', + choices: packageTypes, + default: 'all', + }, + filter: { + desc: `filter output by "packages filter". You can filter by package names, or by package paths starting filter with "/" symbol.`, + type: 'array' as const, + default: [], + }, + }, + async function main(flags) { + for await (const line of pprint(iterateFromPromise(getPackages(di, flags.list as PackagesType, { filter: flags.filter })), flags.format)) { + console.log(line) + } + } + ) +} diff --git a/packages/pvm/commands/pvm-pkgset.ts b/packages/pvm/commands/pvm-pkgset.ts new file mode 100644 index 000000000..9ffcdf0f8 --- /dev/null +++ b/packages/pvm/commands/pvm-pkgset.ts @@ -0,0 +1,46 @@ +import chalk from 'chalk' +import pprint from '../mechanics/pkgset/pprint' +import { pkgsetFromFlags } from '../mechanics/pkgset/pkgset' +import { getStrategiesDescriptionList } from '../mechanics/pkgset/strategies' + +import type { Container } from '../lib/di' +import type { CommandFactory } from '../types' + +export default (di: Container): CommandFactory => builder => builder.command( + 'pkgset', + 'Shows the list of packages by the specified criterion (low-level version)', + (yargs) => { + return yargs + .example('$0 pkgset', 'filter packages in workspaces and print "@" for each package') + .example('pvm pkgset -f %n -s changed -S from=v1.2.3', 'Print packages names which have been change from v1.2.3 to HEAD') + .option('strategy', { + desc: chalk`Filtering strategy. Possible strategies are: ${getStrategiesDescriptionList().join('\n\n ')}`, + default: 'all', + alias: 's', + }) + .option('strategy-option', { + alias: 'S', + desc: 'Pass option through to the used strategy.', + type: 'array' as const, + default: [], + }) + .option('format', { + desc: `Pretty-print the package information in a given format. Format is string, with special symbols: + %p - path to package + %n - package name + %s - package name without namespace if it's present + %v - package version + `, + default: '%n@%v', + alias: 'f', + }) + }, + async function main(flags): Promise { + for await (const line of pprint(pkgsetFromFlags(di, { + strategy: flags['strategy'], + strategyOption: flags['strategy-option'], + }), flags.format)) { + console.log(line) + } + } +) diff --git a/packages/pvm/commands/pvm-publish.ts b/packages/pvm/commands/pvm-publish.ts new file mode 100644 index 000000000..e6103ee78 --- /dev/null +++ b/packages/pvm/commands/pvm-publish.ts @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +import { publish } from '../mechanics/publish' +import { flagsBuilder } from '../mechanics/publish/flags' +import type { Container } from '../lib/di' +import type { CommandFactory } from '../types' + +export default (di: Container): CommandFactory => builder => builder.command( + 'publish', + 'Publish packages to npm registry', + flagsBuilder(di), + + async function(flags): Promise { + const publishStats = await publish(di, flags) + + if (publishStats.error?.length) { + process.exitCode = 1 + } + } +) diff --git a/packages/pvm/commands/pvm-rewrite-notes.ts b/packages/pvm/commands/pvm-rewrite-notes.ts new file mode 100644 index 000000000..f85994789 --- /dev/null +++ b/packages/pvm/commands/pvm-rewrite-notes.ts @@ -0,0 +1,55 @@ +import { log } from '../lib/logger' +import getPreviousRefForFirstRelease from '../lib/git/previous-ref-for-initial-release' +import type { CommandFactory, PlatformReleaseTag } from '../types' +import type { Container } from '../lib/di' +import { CONFIG_TOKEN, PLATFORM_TOKEN } from '../tokens' + +export default (di: Container): CommandFactory => builder => builder.command( + 'rewrite-notes', + 'Recalculate and rewrite release notes for particular range of git tags', + { + 'skip-first': { + desc: 'Do not overwrite release notes for first release tag', + default: false, + }, + 'only-for': { + desc: 'Overwrite release notes only for defined tag', + }, + 'stop-at': { + desc: 'Stop rewriting release notes on defined tag', + }, + 'dry-run': { + desc: '`Generate notes but not persist changes to vcs', + }, + }, + + async function pvmRewriteNotes(flags) { + const platform = di.get(PLATFORM_TOKEN) + let nextReleaseTag: PlatformReleaseTag | null = null + + // идем от самого свежего к первому + for await (const releaseTag of platform.releaseTagsIterator()) { + if (nextReleaseTag && (!flags.onlyFor || flags.onlyFor === nextReleaseTag.name)) { + if (flags.stopAt === nextReleaseTag.name) { + log(`You asked me stop at ${flags.stopAt}. Stopping now`) + break + } + await platform.makeReleaseForTag(nextReleaseTag, releaseTag.name) + if (flags.onlyFor === nextReleaseTag.name) { + break + } + } + + nextReleaseTag = releaseTag + } + + if (!flags.skipFirst && nextReleaseTag && + (!flags.onlyFor || flags.onlyFor === nextReleaseTag.name) && flags.stopAt !== nextReleaseTag.name) { + const config = di.get(CONFIG_TOKEN) + await platform.makeReleaseForTag( + nextReleaseTag, + getPreviousRefForFirstRelease(config, nextReleaseTag.name) + ) + } + } +) diff --git a/packages/pvm/commands/pvm-set-versions.ts b/packages/pvm/commands/pvm-set-versions.ts new file mode 100644 index 000000000..2cf124e9b --- /dev/null +++ b/packages/pvm/commands/pvm-set-versions.ts @@ -0,0 +1,53 @@ +#!/usr/bin/env node + +import { setVersions } from '../mechanics/set-versions' +import type { Container } from '../lib/di' +import type { CommandFactory } from '../types' + +export default (di: Container): CommandFactory => builder => builder.command( + 'set-versions ', + 'Set given version for given packages', + (yargs) => { + return yargs + .example('$0 set-versions minor -p src/components/*', 'Bump version for given packages') + .example('$0 set-versions 0.0.1 -u', 'Set version 0.0.1 for all packages and also update dependencies') + .options({ + strategy: { + alias: 's', + desc: 'Which packages we should peek up in the first place. See pvm-pkgset --help for details.', + default: 'all', + }, + 'update-dependants': { + alias: 'u', + desc: 'Update dependencies for dependants as well', + default: false, + }, + 'bump-dependants': { + alias: 'b', + desc: 'Update versions for dependants', + default: false, + }, + 'strategy-option': { + alias: 'X', + desc: 'Options for used strategy', + type: 'array' as const, + }, + 'filter-path': { + alias: 'p', + desc: `Filter packages by path. Globbing is supported. You can pass this option multiple times. Example: -p "src/co-*"`, + type: 'array' as const, + }, + }) + }, + + async function main(argv): Promise { + return setVersions(di, { + bumpDependants: argv['bump-dependants'], + filterPath: argv['filter-path']?.map(String), + strategy: argv.strategy, + strategyOption: argv['strategy-option']?.map(String), + updateDependants: argv['update-dependants'], + versionOrReleaseType: argv.versionOrReleaseType as string, + }) + } +) diff --git a/packages/pvm/commands/pvm-show.ts b/packages/pvm/commands/pvm-show.ts new file mode 100644 index 000000000..a5188fcd3 --- /dev/null +++ b/packages/pvm/commands/pvm-show.ts @@ -0,0 +1,108 @@ +#!/usr/bin/env node +import * as TOML from '@iarna/toml' + +import { wdShell } from '../lib/shell' +import { logger } from '../lib/logger' +import { lastReleaseTag } from '../lib/git/last-release-tag' +import { releaseCommitsAsString } from '../lib/git/release-commits' +import sinceLastRelease from '../mechanics/update/strategies/since-last-release' + +import type { Argv } from 'yargs' +import type { Container } from '../lib/di' +import { CONFIG_TOKEN, HOST_API_TOKEN } from '../tokens' +import type { CommandFactory } from '../types' + +function pprint(val: any): void { + if (val === void 0) { + return + } + let pval = val + if (Array.isArray(pval)) { + pval = val.join('\n') + } else if (typeof val === 'object' && val) { + pval = JSON.stringify(val) + } + console.log(pval) +} + +function asyncPrint(di: Container, fn: (di: Container, flags: F) => Promise) { + return (flags: F) => { + return Promise.resolve(fn(di, flags)) + .then(result => { + pprint(result) + }) + .catch(e => { + process.exitCode = 1 + logger.error(e) + }) + } +} + +async function resolveLastReleaseTag(di: Container): Promise { + const config = di.get(CONFIG_TOKEN) + return lastReleaseTag(config) +} + +async function printChangelog(di: Container, flags: F) { + const config = di.get(CONFIG_TOKEN) + const release = flags.release + let targetRef = release + const latestReleaseTag = lastReleaseTag(config, release) + const cwd = config.cwd + + if (wdShell(cwd, `git rev-list -1 ${latestReleaseTag}`) === wdShell(cwd, `git rev-list -1 ${release}`)) { + targetRef = `${release}^` + } + + const hostApi = di.get(HOST_API_TOKEN) + + const changedContext = await sinceLastRelease(di, targetRef, { + cwd, + }) + + return hostApi.commitsToNotes(changedContext.commits) +} + +async function releaseCommitsCommand(di: Container, args: F): Promise { + const config = di.get(CONFIG_TOKEN) + return releaseCommitsAsString(config, { + target: args.release, + format: args.format, + }) +} + +async function showConfig(di: Container): Promise { + const config = di.get(CONFIG_TOKEN) + return TOML.stringify(config as { [key: string]: any }) +} + +export default (di: Container): CommandFactory => builder => builder.command( + 'show ', + 'show various information for repository', + (yargs: Argv) => { + return yargs + .command(['last-release-tag', 'lrt'], `show name of latest release tag`, {}, asyncPrint(di, resolveLastReleaseTag)) + .command('changelog', 'show changelog for last/given release', { + release: { + desc: 'Specify ref of release for release-commits command', + default: 'HEAD', + type: 'string', + }, + }, asyncPrint(di, printChangelog)) + .command(['release-commits', 'rc'], 'show commit titles for last/given release', { + release: { + desc: 'Specify ref of release for release-commits command. Defaults to HEAD', + default: 'HEAD', + type: 'string', + }, + format: { + desc: 'Specify pretty print format for release-commits command', + default: '%s', + type: 'string', + }, + }, asyncPrint(di, releaseCommitsCommand)) + .command('config', 'show current config', {}, asyncPrint(di, showConfig)) + }, + + function() {} +) diff --git a/packages/pvm/commands/pvm-vcs.ts b/packages/pvm/commands/pvm-vcs.ts new file mode 100644 index 000000000..6b593345f --- /dev/null +++ b/packages/pvm/commands/pvm-vcs.ts @@ -0,0 +1,88 @@ +import { log } from '../lib/logger' + +import type { Container } from '../lib/di' +import { PLATFORM_TOKEN, VCS_PLATFORM_FACTORY_TOKEN, VCS_PLATFORM_TOKEN } from '../tokens' +import type { CommandFactory } from '../types' + +function cliSubargsToMap(args: string[]): Map { + const map = new Map() + for (const arg of args) { + const indexOfEq = arg.indexOf('=') + if (indexOfEq === -1) { + map.set(arg, true) + } else { + const key = arg.substring(0, indexOfEq) + const value = arg.substr(indexOfEq + 1) + map.set(key, value) + } + } + return map +} + +export default (di: Container): CommandFactory => builder => builder.command( + 'vcs ', + 'cli for version control system', + (yargs) => { + return yargs + .command( + 'is-branch-actual', + `Checks current branch is up to date with origin remote one. Exit with code 0 unless branch is stale`, + {}, + async function isBranchActual(): Promise { + const vcs = await di.get(VCS_PLATFORM_TOKEN) + const platform = await di.get(PLATFORM_TOKEN) + const currentBranch = platform.getCurrentBranch() + if (currentBranch) { + const matches = await vcs.isRefMatchesRemoteBranch('HEAD', currentBranch) + + if (!matches) { + log(`Branch ${currentBranch} doesn't match remote one! Is it outdated ?`) + process.exitCode = 1 + } + } else { + log('No branch detected. Are you in detached head state ?') + process.exitCode = 1 + } + } + ) + .command( + 'push [refspec]', + 'Push current branch & tags via vcs(git) to remote repository. If refspec is passed pushes only it.', + { + 'skip-ci': { + default: false, + type: 'boolean' as const, + description: 'Do not trigger pipeline for push refs if possible', + }, + 'tags': { + default: false, + type: 'boolean' as const, + description: 'Also push tags', + }, + 'push-option': { + alias: 'o', + type: 'array' as const, + description: `--push-option's for git push command`, + default: [] as string[], + }, + refspec: { + type: 'string' as const, + }, + }, + async function push(flags): Promise { + const vcs = di.get(VCS_PLATFORM_FACTORY_TOKEN)({ + vcsMode: 'vcs', + }) + + await vcs.push({ + skipCi: flags['skip-ci'], + noTags: !flags.tags, + pushOptions: cliSubargsToMap(flags['push-option']), + refspec: flags.refspec, + }) + } + + ) + .demandCommand() + } +) diff --git a/packages/pvm/commands/pvm-write-versions.ts b/packages/pvm/commands/pvm-write-versions.ts new file mode 100644 index 000000000..8bbaff1ca --- /dev/null +++ b/packages/pvm/commands/pvm-write-versions.ts @@ -0,0 +1,19 @@ +#!/usr/bin/env node +import { setVersions } from '../mechanics/set-versions' +import type { Container } from '../lib/di' +import type { CommandFactory } from '../types' + +export default (di: Container): CommandFactory => builder => builder.command( + 'write-versions', + `Replace stub versions in package.json's with actual one's from versions file or from release tag. Alias for 'pvm set-versions none -u -s all'`, + function(): Promise { + return setVersions(di, { + strategy: 'all', + versionOrReleaseType: 'none', + bumpDependants: false, + filterPath: [], + strategyOption: [], + updateDependants: true, + }) + } +) diff --git a/packages/pvm/commands/releases/pvm-releases-download.ts b/packages/pvm/commands/releases/pvm-releases-download.ts new file mode 100644 index 000000000..ff45adea5 --- /dev/null +++ b/packages/pvm/commands/releases/pvm-releases-download.ts @@ -0,0 +1,31 @@ +#!/usr/bin/env node + +import { download, ArtifactsStorages } from '../../mechanics/artifacts/pub/artifacts' + +import type { Container } from '../../lib/di' +import type { CommandFactory } from '../../types/cli' + +export default (di: Container): CommandFactory => builder => builder.command( + 'download', + 'Download ReleaseList artifact from remote storage', + (yargs) => { + return yargs + .option('quiet', { + desc: `Don't print warnings`, + type: 'boolean' as const, + default: false, + }) + .option('force', { + desc: `Download an artifact even if it is not turned on`, + type: 'boolean' as const, + default: false, + }) + }, + async function main(args): Promise { + await download(di, { + force: args.force, + quiet: args.quiet, + kind: ArtifactsStorages.ReleaseList, + }) + } +) diff --git a/packages/pvm/commands/releases/pvm-releases-make.ts b/packages/pvm/commands/releases/pvm-releases-make.ts new file mode 100644 index 000000000..b58823f1f --- /dev/null +++ b/packages/pvm/commands/releases/pvm-releases-make.ts @@ -0,0 +1,74 @@ +import path from 'path' +import { logger } from '../../lib/logger' +import { makeReleasesFromWorkingTree } from '../../mechanics/releases/producers/releases-by-working-tree' +import { releaseDataMaker } from '../../mechanics/releases/release-data' +import { reduceReleaseList } from '../../mechanics/releases/release-list' +import { getUpdateState } from '../../mechanics/update' +import { createReleaseContext } from '../../mechanics/update/release/release-context' + +import type { Container } from '../../lib/di' +import { CONFIG_TOKEN, CWD_TOKEN } from '../../tokens' +import type { CommandFactory } from '../../types' + +export default (di: Container): CommandFactory => builder => builder.command( + 'make', + 'Make ReleaseList artifact from git working tree', + (yargs) => { + return yargs + .option('start-from', { + desc: 'Git reference from wich start iteration', + type: 'string' as const, + default: 'HEAD', + }) + .option('stop-at', { + desc: 'Git reference at which to stop iteration', + type: 'string' as const, + }) + .option('append-upcoming-release', { + desc: `Generate ReleasedData based on unreleased changes and append it to ReleaseList`, + type: 'boolean' as const, + default: false, + }) + .option('limit', { + desc: 'limit ReleaseList artefact according to configuration', + type: 'boolean' as const, + default: true, + }) + }, + async function main(flags): Promise { + const fs = require('fs') + const cwd = di.get(CWD_TOKEN) + const config = di.get(CONFIG_TOKEN) + + let releaseList = await makeReleasesFromWorkingTree(di, { + stopAtRef: flags['stop-at'], + startFrom: flags['start-from'], + }) + + if (flags.appendUpcomingRelease) { + const updateState = await getUpdateState(di, { + includeUncommited: true, + }) + + const releaseContext = await createReleaseContext(updateState) + if (releaseContext) { + const releaseData = await releaseDataMaker.fromReleaseContext(releaseContext) + + if (releaseData) { + releaseList.unshift(releaseData) + } + } + } + + if (flags.limit) { + logger.info('Limit ReleaseList according to corresponding configuration') + releaseList = reduceReleaseList(config, releaseList) + } + + logger.info(`Produced ${releaseList.length} releases`) + + const outputPath = path.join(cwd, config.release_list.path) + fs.writeFileSync(outputPath, JSON.stringify(releaseList)) + logger.info(`Release list saved to "${config.release_list.path}"`) + } +) diff --git a/packages/pvm/commands/releases/pvm-releases-probe.ts b/packages/pvm/commands/releases/pvm-releases-probe.ts new file mode 100644 index 000000000..02b50bf7b --- /dev/null +++ b/packages/pvm/commands/releases/pvm-releases-probe.ts @@ -0,0 +1,45 @@ +import path from 'path' +import { logger } from '../../lib/logger' +import { releaseDataMaker } from '../../mechanics/releases/release-data' +import { getUpdateState } from '../../mechanics/update' +import { createReleaseContext } from '../../mechanics/update/release/release-context' + +import type { Container } from '../../lib/di' +import type { CommandFactory } from '../../types' + +export default (di: Container): CommandFactory => builder => builder.command( + 'probe', + 'Create ReleaseData artefact based on unreleased changes', + (yargs) => { + return yargs + .option('output-path', { + desc: 'Output path for ReleaseData artefact', + type: 'string' as const, + default: 'releaseData.json', + }) + }, + async function main(flags): Promise { + const fs = require('fs') + const cwd = process.cwd() + + const updateState = await getUpdateState(di, { + includeUncommited: true, + }) + + const releaseContext = await createReleaseContext(updateState) + if (releaseContext) { + const releaseData = await releaseDataMaker.fromReleaseContext(releaseContext, { + allowWithoutCommits: true, + emptyReleaseNotes: 'Uncommited changes', + }) + + if (releaseData) { + const outputPath = path.resolve(cwd, flags['output-path']) + fs.writeFileSync(outputPath, JSON.stringify(releaseData)) + logger.info(`ReleaseData saved to "${flags.outputPath}"`) + } else { + logger.info(`ReleaseData has not been created`) + } + } + } +) diff --git a/packages/pvm/commands/releases/pvm-releases-upload.ts b/packages/pvm/commands/releases/pvm-releases-upload.ts new file mode 100644 index 000000000..29c3ab4f9 --- /dev/null +++ b/packages/pvm/commands/releases/pvm-releases-upload.ts @@ -0,0 +1,30 @@ +import { upload, ArtifactsStorages } from '../../mechanics/artifacts/pub/artifacts' + +import type { Container } from '../../lib/di' +import type { CommandFactory } from '../../types' + +export default (di: Container): CommandFactory => builder => builder.command( + 'upload', + 'Upload ReleaseList artifact to remote storage', + (yargs) => { + return yargs + .option('quiet', { + desc: `Don't print warnings`, + type: 'boolean' as const, + default: false, + }) + .option('force', { + desc: `Upload an artifact even if it is not turned on`, + type: 'boolean' as const, + default: false, + }) + }, + + async function main(args: Record): Promise { + await upload(di, { + force: args.force, + quiet: args.quiet, + kind: ArtifactsStorages.ReleaseList, + }) + } +) diff --git a/packages/pvm/commands/releases/pvm-releases.ts b/packages/pvm/commands/releases/pvm-releases.ts new file mode 100644 index 000000000..b40403916 --- /dev/null +++ b/packages/pvm/commands/releases/pvm-releases.ts @@ -0,0 +1,19 @@ +import pvmReleasesMake from './pvm-releases-make' +import pvmReleasesDownload from './pvm-releases-download' +import pvmReleasesUpload from './pvm-releases-upload' +import pvmReleasesProbe from './pvm-releases-probe' +import type { Container } from '../../lib/di' +import type { CommandFactory } from '../../types' + +export default (di: Container): CommandFactory => builder => builder.command( + 'releases ', + 'Commands for working with ReleaseList artifact', + (yargs) => { + pvmReleasesMake(di)(yargs) + pvmReleasesDownload(di)(yargs) + pvmReleasesUpload(di)(yargs) + pvmReleasesProbe(di)(yargs) + + return yargs + } +) diff --git a/packages/pvm-update/cli/hints_file.txt b/packages/pvm/commands/update/hints_file.txt similarity index 100% rename from packages/pvm-update/cli/hints_file.txt rename to packages/pvm/commands/update/hints_file.txt diff --git a/packages/pvm/commands/update/pvm-update-local.ts b/packages/pvm/commands/update/pvm-update-local.ts new file mode 100644 index 000000000..a4522d75c --- /dev/null +++ b/packages/pvm/commands/update/pvm-update-local.ts @@ -0,0 +1,24 @@ +// eslint-disable-next-line node/no-extraneous-import +import type { Container } from '../../lib/di' + +import pvmUpdate from './pvm-update' +import { GLOBAL_FLAGS_TOKEN } from '../../tokens' +import type { CommandFactory } from '../../types/cli' + +export default (di: Container): CommandFactory => (yargs) => yargs.command( + 'local ', + 'Enables local mode for the following command', + (yargs) => { + const nextYargs = yargs + .example(`$0 local update`, `Update packages locally and don't create the commit in a remote repository`) + .middleware((argv) => { + const globalFlags = di.get(GLOBAL_FLAGS_TOKEN) + globalFlags.setFlag('localMode', true) + return argv + }) + .demandCommand() + + return pvmUpdate(di)(nextYargs) + }, + () => {} +) diff --git a/packages/pvm/commands/update/pvm-update.ts b/packages/pvm/commands/update/pvm-update.ts new file mode 100644 index 000000000..b76a2aad9 --- /dev/null +++ b/packages/pvm/commands/update/pvm-update.ts @@ -0,0 +1,113 @@ +#!/usr/bin/env node +import chalk from 'chalk' +// eslint-disable-next-line node/no-extraneous-import +import { parseSubArgs } from '../../lib/text/sub-args' +import { + updateMethods, +} from '../../mechanics/update/update-methods/index' +import { update } from '../../mechanics/update/index' +import type { CliUpdateOpts } from '../../mechanics/update/types' +import type { Container } from '../../lib/di' +import { GLOBAL_FLAGS_TOKEN } from '../../tokens' +import type { CommandFactory } from '../../types/cli' + +function toCamelCase(str: string): string { + return str.replace(/-[a-z]/g, m => m.charAt(1).toUpperCase()) +} + +async function printResult(result: AsyncIterable | Iterable | string): Promise { + if (typeof result === 'string') { + console.log(result) + } else if (Symbol.asyncIterator in result) { + for await (const line of result) { + console.log(line) + } + } else if (Symbol.iterator in result) { + // @ts-ignore + for (const line of result) { + console.log(line) + } + } +} + +export default (di: Container): CommandFactory => (yargs) => yargs.command( + ['update', 'relase'], + 'Update packages changed since last release', + (yargs) => { + return yargs + .options({ + 'update-option': { + default: [], + type: 'array' as const, + alias: 'P', + description: `Options to the used update method`, + coerce(arg: string[]) { + return parseSubArgs(arg) + }, + }, + 'update-method': { + alias: 'p', + default: 'release', + type: 'string' as const, + description: + chalk`What we should do with changed packages. Options are: +{greenBright release} +. Do release. This is default. Commit new package versions, create release tag and store release notes. +. +. Options: +. {yellow local}: Do not push changes to the remote vcs server. +. +{greenBright dot} +. Generate graph in dot format of changed packages and print it to stdout +. +{greenBright print} +. Print changed packages +. +. Options: +. {yellow format}: String with flags - how we should print each package. For possible flags see help for pvm pkgset command. +. Default is "%n". +{greenBright md-table} +. Print packages about to release as md table. +`, + }, + 'dry-run': { + description: `Do all the job, but without any side-effect`, + type: 'boolean' as const, + }, + 'release-data-file': { + description: `Output release data to specified path`, + type: 'string' as const, + }, + 'tag-only': { + description: `Make release tag only, do not do or commit any changes to VCS`, + type: 'boolean' as const, + }, + }) + .example(`$0 update -P local`, 'update packages changed since last release, but don\'t push changes') + }, + async function run(flags): Promise { + const updateMethodName = toCamelCase(flags['update-method']) + const updateMethod = updateMethods[updateMethodName] + if (!updateMethod) { + throw new Error(`There is no "${flags['update-method']}" update method`) + } + + const globalFlags = di.get(GLOBAL_FLAGS_TOKEN) + const dryRun = globalFlags.getFlag('dryRun') + const local = globalFlags.getFlag('localMode') + + const updateOpts: CliUpdateOpts = { + ...flags['update-option'] as Record, + dryRun, + local, + releaseDataFile: flags['release-data-file'], + tagOnly: flags['tag-only'], + } + + const result = await update(di, updateMethod, updateOpts) + if (result) { + // @ts-ignore + await printResult(result) + } + } +) diff --git a/packages/pvm-core/env-defaults.ts b/packages/pvm/env-defaults.ts similarity index 67% rename from packages/pvm-core/env-defaults.ts rename to packages/pvm/env-defaults.ts index 99722267f..98209f5ec 100644 --- a/packages/pvm-core/env-defaults.ts +++ b/packages/pvm/env-defaults.ts @@ -1,4 +1,4 @@ -import type { Env } from '@pvm/types' +import type { Env } from './types' export const envDefaults: Env = { SLACK_API_URL: 'https://slack.com/api', diff --git a/packages/pvm/index.ts b/packages/pvm/index.ts new file mode 100644 index 000000000..fed99e352 --- /dev/null +++ b/packages/pvm/index.ts @@ -0,0 +1,22 @@ +export { Pvm } from './app' +export * from './tokens' +export * from './types' + +export * from './mechanics/vcs' +export * from './mechanics/platform' +export * from './mechanics/notifications' + +export { env, checkEnv } from './lib/env' +export * from './lib/di' +export * from './lib/tag-meta' +export * from './lib/git/commands' +export * from './lib/utils/string' +export * from './lib/shell' +export * from './lib/logger' +export * from './app/config' +export * from './lib/httpreq' +export * from './lib/vcs-meta' +export * from './lib/text/markdown' +export * from './lib/interop' +export * from './lib/messages/message-builder' +export * from './lib/text/jira' diff --git a/packages/pvm-core/lib/behaviors/no-packages-in-mug.ts b/packages/pvm/lib/behaviors/no-packages-in-mug.ts similarity index 100% rename from packages/pvm-core/lib/behaviors/no-packages-in-mug.ts rename to packages/pvm/lib/behaviors/no-packages-in-mug.ts diff --git a/packages/pvm-core/lib/class-helpers.ts b/packages/pvm/lib/class-helpers.ts similarity index 81% rename from packages/pvm-core/lib/class-helpers.ts rename to packages/pvm/lib/class-helpers.ts index eb28c8456..3dbad1010 100644 --- a/packages/pvm-core/lib/class-helpers.ts +++ b/packages/pvm/lib/class-helpers.ts @@ -1,20 +1,20 @@ const cacheKey = Symbol.for('_cached_props') // eslint-disable-next-line @typescript-eslint/ban-types -export function lazyCallee(targetProto: object, propKey: string, desc: PropertyDescriptor): void { +export function lazyCallee(targetProto: any, propKey: string, desc: PropertyDescriptor): void { const descKey: 'get' | 'value' = desc.get ? 'get' : 'value' const getter = desc[descKey] if (typeof getter !== 'function') { throw new TypeError(`lazyCallee applied on non-function property ${propKey}`) } - targetProto[`_lazyReset_${propKey}`] = function() { + targetProto[`_lazyReset_${propKey}`] = function(this: any) { const cacheMap: Map = this[cacheKey] if (cacheMap) { cacheMap.delete(propKey) } } - desc[descKey] = function(...args) { + desc[descKey] = function(...args: any[]) { if (args.length !== 0) { throw new Error(`lazyCallee can't operate on function with arguments`) } diff --git a/src/plugins/core/cli-runner.ts b/packages/pvm/lib/cli/cli-runner.ts similarity index 80% rename from src/plugins/core/cli-runner.ts rename to packages/pvm/lib/cli/cli-runner.ts index 72aeda404..d7cb21400 100644 --- a/src/plugins/core/cli-runner.ts +++ b/packages/pvm/lib/cli/cli-runner.ts @@ -1,35 +1,38 @@ #!/usr/bin/env node import assert from 'assert' import Yargs from 'yargs/yargs' +// @ts-ignore import { hideBin } from 'yargs/helpers' -import '@pvm/core/lib/node-boot' + +import '../node-boot' import type { Argv } from 'yargs' -import type { CLI_EXTENSION_TOKEN } from '@pvm/tokens-core' +import type { CLI_EXTENSION_TOKEN } from '../../tokens' +import type { GlobalFlags } from './global-flags' +import type { ExtractTokenType } from '../../lib/di' -function initCommands(yargs: Argv, commands: Array) { - commands.forEach(command => { - if (Array.isArray(command)) { - command.forEach(c => yargs.command(c)) +function initCommands(yargs: Argv, commandBuilders: ExtractTokenType[]) { + commandBuilders.forEach(builder => { + if (Array.isArray(builder)) { + builder.forEach(b => b(yargs)) } else { - yargs.command(command) + builder(yargs) } }) return yargs } -export function runCli(commands: Array, argv: string[]) { +export function runCli(commands: Array, globalFlags: GlobalFlags, argv: string[]) { + if (Yargs(argv).argv.dryRun) { + globalFlags.setFlag('dryRun', true) + } const yargs = initCommands(Yargs(hideBin(argv)), commands) .command('help ', 'Get help for subcommand', {}, (argv) => { initCommands(Yargs([(argv as Record).subcommand, '--help']), commands) .wrap(120) .showHelp('info') }) - .middleware((argv) => { - global.argv = argv - return argv - }) .demandCommand() .strict() .wrap(100) @@ -67,8 +70,8 @@ export function runCli(commands: Array, argv: string patchYargsOptions(yargs).parse() } -function hasExplicitType(opt): boolean { - return opt.boolean || opt.number || opt.string || opt.array || opt.type +function hasExplicitType(opt: { boolean?: boolean, number?: boolean, string?: boolean, array?: boolean, type?: string }): boolean { + return opt.boolean || opt.number || opt.string || opt.array || !!opt.type } function guessType(value: any): 'boolean' | 'number' | 'array' | 'string' | undefined { @@ -96,6 +99,7 @@ function patchYargsOptions(yargs: Argv, runSelfTest = true): Argv { opt.type = derivedType } } + // @ts-ignore return originalOption.call(yargs, key, opt) } } diff --git a/packages/pvm/lib/cli/global-flags.ts b/packages/pvm/lib/cli/global-flags.ts new file mode 100644 index 000000000..327a0fd78 --- /dev/null +++ b/packages/pvm/lib/cli/global-flags.ts @@ -0,0 +1,23 @@ +import { env } from '../env' +import { logger } from '../logger' + +type Flags = { + dryRun: boolean, + localMode: boolean, +} + +export class GlobalFlags { + protected flags: Flags = { + dryRun: env.PVM_EXTERNAL_DRY_RUN === 'true', + localMode: false, + } + + setFlag(flag: T, value: Flags[T]): void { + logger.log(`enable global "${flag}" mode`) + this.flags[flag] = value + } + + getFlag(flag: T): Flags[T] { + return this.flags[flag] + } +} diff --git a/packages/pvm-core/lib/consts.ts b/packages/pvm/lib/consts.ts similarity index 100% rename from packages/pvm-core/lib/consts.ts rename to packages/pvm/lib/consts.ts diff --git a/packages/pvm-core/lib/dedicated-versions-file.ts b/packages/pvm/lib/dedicated-versions-file.ts similarity index 98% rename from packages/pvm-core/lib/dedicated-versions-file.ts rename to packages/pvm/lib/dedicated-versions-file.ts index b8d2e3c92..1f9f43b24 100644 --- a/packages/pvm-core/lib/dedicated-versions-file.ts +++ b/packages/pvm/lib/dedicated-versions-file.ts @@ -6,7 +6,7 @@ import { loggerFor } from './logger' import { indexFile } from './git/commands' import revParse from './git/rev-parse' -import type { Config } from './config' +import type { Config } from '../types' import type { Pkg } from './pkg' import { cwdToGitRelativity } from './git/worktree' @@ -37,7 +37,7 @@ function loadDedicatedVersionsMap(config: Config, ref: string | undefined): Reco versioningCache.set(cacheKey, result) return result } - } catch (e) { + } catch (e: any) { logger.debug(`Could not find or parse versions file "${source_file}" in ref "${ref}"`, e.message) } diff --git a/packages/pvm/lib/di/index.ts b/packages/pvm/lib/di/index.ts new file mode 100644 index 000000000..e47ddfbd3 --- /dev/null +++ b/packages/pvm/lib/di/index.ts @@ -0,0 +1,12 @@ +import type { Config, PluginFactory, RecursivePartial } from '../../types' + +export * from '@tinkoff/dippy' + +export function declarePlugin(opts: { factory: PluginFactory }): { name: string, factory: PluginFactory} +export function declarePlugin(opts: { configExt: RecursivePartial }): { name: string, configExt: RecursivePartial } +export function declarePlugin(opts: { configExt: RecursivePartial, factory: PluginFactory} | { factory: PluginFactory} | { configExt: RecursivePartial}): { name: string, configExt?: RecursivePartial, factory?: PluginFactory} { + return { + name: __filename, + ...opts, + } +} diff --git a/packages/pvm-core/lib/env.ts b/packages/pvm/lib/env.ts similarity index 95% rename from packages/pvm-core/lib/env.ts rename to packages/pvm/lib/env.ts index c1f03601e..8ba8f5359 100644 --- a/packages/pvm-core/lib/env.ts +++ b/packages/pvm/lib/env.ts @@ -1,9 +1,9 @@ import Ajv from 'ajv' import chalk from 'chalk' -import EnvJsonSchema from '@pvm/types/lib/env-schema.json' +import EnvJsonSchema from '../types/env-schema.json' import type { ValidateFunction } from 'ajv' -import type { Env } from '@pvm/types' +import type { Env } from '../types' import { envDefaults } from '../env-defaults' let envsCache: Env diff --git a/packages/pvm-core/lib/fs.ts b/packages/pvm/lib/fs.ts similarity index 90% rename from packages/pvm-core/lib/fs.ts rename to packages/pvm/lib/fs.ts index 5143676ac..7a7a640c1 100644 --- a/packages/pvm-core/lib/fs.ts +++ b/packages/pvm/lib/fs.ts @@ -1,5 +1,5 @@ import fs from 'fs' -import { mema } from './memoize/mema' +import { mema } from './memoize' export function mkdirp(dir: string): void { if (!fs.existsSync(dir)) { diff --git a/packages/pvm-core/lib/git/commands.ts b/packages/pvm/lib/git/commands.ts similarity index 98% rename from packages/pvm-core/lib/git/commands.ts rename to packages/pvm/lib/git/commands.ts index 9c7e12c0c..6c71501e7 100644 --- a/packages/pvm-core/lib/git/commands.ts +++ b/packages/pvm/lib/git/commands.ts @@ -1,5 +1,6 @@ import path from 'path' import fs from 'fs' +// @ts-ignore import parseRepositoryUrl from '@hutson/parse-repository-url' import gitUrlParse from 'git-url-parse' import { wdShell } from '../shell' @@ -8,10 +9,10 @@ import revParse from './rev-parse' import { CacheTag, taggedCacheManager, wdmemoize } from '../memoize' import { releaseTagFilter } from '../tag-meta' -import type { Config } from '../config' +import type { Config } from '../../types' import { mergeBase } from './merge-base' import { env } from '../env' -import { nthIndex } from '../text/index' +import { nthIndex } from '../text' import { gitToCwdRelativity } from './worktree' export { @@ -205,12 +206,6 @@ export function getOldestDescendantCommitRef(cwd: string, currentBranch: string return noReleaseRef } -export interface AddTagOptions { - tagName: string, - ref: string, - annotation?: string | null, -} - export function deleteTag(cwd: string, tagName: string): void { // eslint-disable-next-line pvm/no-direct-git-tag wdShell(cwd, `git tag -d ${tagName}`) @@ -218,7 +213,11 @@ export function deleteTag(cwd: string, tagName: string): void { taggedCacheManager.clear(cwd, [CacheTag.gitFetchTags]) } -export function addTag(cwd: string, { tagName, ref, annotation }: AddTagOptions): void { +export function addTag(cwd: string, { tagName, ref, annotation }: { + tagName: string, + ref: string, + annotation?: string | null, +}): void { if (!annotation) { // eslint-disable-next-line pvm/no-direct-git-tag wdShell(cwd, `git tag ${tagName} ${ref}`) diff --git a/packages/pvm-core/lib/git/commits.ts b/packages/pvm/lib/git/commits.ts similarity index 93% rename from packages/pvm-core/lib/git/commits.ts rename to packages/pvm/lib/git/commits.ts index 1b58ef9fd..0b7e8e6db 100644 --- a/packages/pvm-core/lib/git/commits.ts +++ b/packages/pvm/lib/git/commits.ts @@ -1,6 +1,6 @@ import log from './log' import { logger } from '../logger' -import type { Commit } from '@pvm/types' +import type { Commit } from '../../types' interface CommitsOptions { _?: string[], diff --git a/packages/pvm-core/lib/git/last-release-tag.ts b/packages/pvm/lib/git/last-release-tag.ts similarity index 98% rename from packages/pvm-core/lib/git/last-release-tag.ts rename to packages/pvm/lib/git/last-release-tag.ts index a15ae6341..45d62c854 100644 --- a/packages/pvm-core/lib/git/last-release-tag.ts +++ b/packages/pvm/lib/git/last-release-tag.ts @@ -2,7 +2,7 @@ import { isReleaseTag, releaseTagMask } from '../tag-meta' import { shellOr, shell } from '../shell' import revParse from './rev-parse' import { taggedCacheManager, CacheTag } from '../memoize' -import type { Config } from '../config' +import type { Config } from '../../types' import { env } from '../env' import { gitFetch } from './commands' @@ -33,7 +33,7 @@ function lastMatchedTagImpl(cwd: string, mask: string, target: string | void = v // как правило если оба есть и отличаются, firstParentTag будет более старым shell(`git merge-base --is-ancestor "${firstParentTag}" "${nonFPTag}"`, { cwd }) return nonFPTag - } catch (e) { + } catch (e: any) { if (e.status !== 1) { throw e } diff --git a/packages/pvm-core/lib/git/last-tag.ts b/packages/pvm/lib/git/last-tag.ts old mode 100755 new mode 100644 similarity index 89% rename from packages/pvm-core/lib/git/last-tag.ts rename to packages/pvm/lib/git/last-tag.ts index 52175a658..de3423ecd --- a/packages/pvm-core/lib/git/last-tag.ts +++ b/packages/pvm/lib/git/last-tag.ts @@ -1,6 +1,6 @@ #!/usr/bin/env node -import shell from '../shell' +import { shell } from '../shell' const lastTag = (opts = void 0): string => { try { diff --git a/packages/pvm-core/lib/git/log.ts b/packages/pvm/lib/git/log.ts similarity index 81% rename from packages/pvm-core/lib/git/log.ts rename to packages/pvm/lib/git/log.ts index c7f2e966e..70cdf6c65 100644 --- a/packages/pvm-core/lib/git/log.ts +++ b/packages/pvm/lib/git/log.ts @@ -1,8 +1,10 @@ +// @ts-ignore import gitLog from 'git-log-parser' // @TODO рассмотреть git-raw-commits, возможно он будет пошустрее +// @ts-ignore import through from 'through2' -import { error } from '../logger' +import { logger } from '../logger' -import type { Commit } from '@pvm/types' +import type { Commit } from '../../types' import type { SpawnOptions } from 'child_process' // format: https://github.com/bendrucker/git-log-parser#logparseconfig-options---streamcommits @@ -12,7 +14,7 @@ function log(opts: Record, spawnOpts: SpawnOptions | undefined = vo gitLog.parse(opts, spawnOpts) .on('error', reject) - .pipe(through.obj((commit, _enc, cb) => { + .pipe(through.obj((commit: Commit, _enc: unknown, cb: (p: any) => void) => { commits.push(commit) cb(null) }).on('finish', () => { @@ -28,7 +30,7 @@ if (require.main === module) { console.log(commits) }) .catch(e => { - error(e) + logger.error(e) process.exitCode = 1 }) } diff --git a/packages/pvm-core/lib/git/merge-base.ts b/packages/pvm/lib/git/merge-base.ts similarity index 96% rename from packages/pvm-core/lib/git/merge-base.ts rename to packages/pvm/lib/git/merge-base.ts index 1c44dfddf..a1e2b348c 100644 --- a/packages/pvm-core/lib/git/merge-base.ts +++ b/packages/pvm/lib/git/merge-base.ts @@ -4,7 +4,7 @@ import { env } from '../env' export function mergeBase(cwd: string, from: string, to: string): string { try { return wdShell(cwd, `git merge-base ${from} ${to}`) - } catch (e) { + } catch (e: any) { const message = [e.message] let gitDepthDesc = '.' if (env.GIT_DEPTH) { diff --git a/packages/pvm-core/lib/git/named-diff.ts b/packages/pvm/lib/git/named-diff.ts similarity index 88% rename from packages/pvm-core/lib/git/named-diff.ts rename to packages/pvm/lib/git/named-diff.ts index eb9f4bb6f..3178c991e 100644 --- a/packages/pvm-core/lib/git/named-diff.ts +++ b/packages/pvm/lib/git/named-diff.ts @@ -1,5 +1,5 @@ import { wdShell } from '../shell' -import type { DiffStats, NamedDiff } from '@pvm/types' +import type { DiffStats, NamedDiff } from '../../types' import { gitToCwdRelativity } from './worktree' export interface NamedDiffShellOpts { @@ -7,7 +7,9 @@ export interface NamedDiffShellOpts { } function namedDiff(revArgs: string, shellOpts: NamedDiffShellOpts): NamedDiff { - const nameStats = wdShell(shellOpts.cwd, `git diff --name-status ${revArgs}`).split('\n') + const nameStats = wdShell(shellOpts.cwd, `git diff --name-status ${revArgs}`, { + maxBuffer: 1024 * 1024 * 10, + }).split('\n') const result = Object.create(null) for (const line of nameStats) { diff --git a/packages/pvm-core/lib/git/pkg-commits.ts b/packages/pvm/lib/git/pkg-commits.ts similarity index 86% rename from packages/pvm-core/lib/git/pkg-commits.ts rename to packages/pvm/lib/git/pkg-commits.ts index cbafbf90c..5cb13a7e5 100644 --- a/packages/pvm-core/lib/git/pkg-commits.ts +++ b/packages/pvm/lib/git/pkg-commits.ts @@ -1,6 +1,6 @@ import gitCommits from './commits' import type { Pkg } from '../pkg' -import type { Commit } from '@pvm/types' +import type { Commit } from '../../types' async function pkgCommits(pkg: Pkg, from: string, to: string): Promise { return gitCommits(pkg.pvmConfig.cwd, from, to, { diff --git a/packages/pvm-core/lib/behaviors/previous-ref-for-initial-release.ts b/packages/pvm/lib/git/previous-ref-for-initial-release.ts similarity index 81% rename from packages/pvm-core/lib/behaviors/previous-ref-for-initial-release.ts rename to packages/pvm/lib/git/previous-ref-for-initial-release.ts index 6b9cd1a37..cbf37f7ef 100644 --- a/packages/pvm-core/lib/behaviors/previous-ref-for-initial-release.ts +++ b/packages/pvm/lib/git/previous-ref-for-initial-release.ts @@ -1,5 +1,5 @@ -import { wdShell } from '../shell' -import type { Config } from '../config' +import { wdShell } from '../shell/index' +import type { Config } from '../../types' function getPreviousRefForFirstRelease(config: Config, targetRef: string): string { const { no_release_ref } = config.update diff --git a/packages/pvm-core/lib/git/release-commits.ts b/packages/pvm/lib/git/release-commits.ts similarity index 68% rename from packages/pvm-core/lib/git/release-commits.ts rename to packages/pvm/lib/git/release-commits.ts index 9793465c2..4fc6af6c0 100644 --- a/packages/pvm-core/lib/git/release-commits.ts +++ b/packages/pvm/lib/git/release-commits.ts @@ -1,11 +1,8 @@ -import type { Config } from '../config' -import { getConfig } from '../config' +import type { Config, Commit } from '../../types' import { prevReleaseTag } from './last-release-tag' import { releaseMark } from '../consts' import { wdShell } from '../shell' import getCommits from './commits' -import type { Commit } from '@pvm/types' -import { logger } from '../logger' interface ReleaseCommitsOpts { target?: string, @@ -66,28 +63,3 @@ export async function getReleaseCommits(config: Config, target = 'HEAD'): Promis }) } } - -async function testMain() { - const config = await getConfig(process.cwd()) - const commits = await getReleaseCommits(config) - if (commits) { - // console.info(require('util').inspect(commits, false, 2, true)) - if (commits.length) { - console.info(commits.map(c => c.subject).join('\n')) - } else { - console.info('-- no commits --') - } - } else { - console.info(' -- no release refs --') - } - // console.info('---') - // console.info(releaseCommitsAsString(config)) -} - -if (require.main === module) { - testMain() - .catch(e => { - logger.fatal(e) - process.exitCode = 1 - }) -} diff --git a/packages/pvm-core/lib/git/release-tag-for.ts b/packages/pvm/lib/git/release-tag-for.ts similarity index 89% rename from packages/pvm-core/lib/git/release-tag-for.ts rename to packages/pvm/lib/git/release-tag-for.ts index 7b878c880..025bd6afe 100644 --- a/packages/pvm-core/lib/git/release-tag-for.ts +++ b/packages/pvm/lib/git/release-tag-for.ts @@ -1,5 +1,5 @@ import { releaseTagFilter } from '../tag-meta' -import type { Config } from '../config' +import type { Config } from '../../types' import { getTagsPointsAt } from './commands' // релизный тэг на заданной ревизии diff --git a/packages/pvm-core/lib/git/rev-parse.ts b/packages/pvm/lib/git/rev-parse.ts similarity index 100% rename from packages/pvm-core/lib/git/rev-parse.ts rename to packages/pvm/lib/git/rev-parse.ts diff --git a/packages/pvm-core/lib/git/version.ts b/packages/pvm/lib/git/version.ts similarity index 100% rename from packages/pvm-core/lib/git/version.ts rename to packages/pvm/lib/git/version.ts diff --git a/packages/pvm-core/lib/git/worktree.ts b/packages/pvm/lib/git/worktree.ts similarity index 98% rename from packages/pvm-core/lib/git/worktree.ts rename to packages/pvm/lib/git/worktree.ts index 0aed4d690..937dd775f 100644 --- a/packages/pvm-core/lib/git/worktree.ts +++ b/packages/pvm/lib/git/worktree.ts @@ -1,4 +1,4 @@ -import { shell } from '../index' +import { shell } from '../shell' import { logger } from '../logger' import path from 'path' import { mema } from '../memoize' diff --git a/packages/pvm-core/lib/hints-file.ts b/packages/pvm/lib/hints-file.ts similarity index 91% rename from packages/pvm-core/lib/hints-file.ts rename to packages/pvm/lib/hints-file.ts index 95af36e36..763934d80 100644 --- a/packages/pvm-core/lib/hints-file.ts +++ b/packages/pvm/lib/hints-file.ts @@ -4,11 +4,11 @@ import * as TOML from '@iarna/toml' import { isValidReleaseType } from './semver-extra' import { wdShell } from './shell' -import type { UpdateHints } from '@pvm/types' -import type { Config } from './config' +import type { UpdateHints, Config } from '../types' + import { cwdToGitRelativity } from './git/worktree' -function err(path, message): Error { +function err(path: string, message: string): Error { return new Error(`[hints-file]: ${path ? `(${path})` : ''} ${message}`) } @@ -17,16 +17,16 @@ export interface Validator { key: string, } -function makeValidator(key, fn): Validator { +function makeValidator(key: string, fn: (config: Config, hints: UpdateHints, api: { err: (message: string) => Error }, hintValue: any) => void): Validator { const api = { - err(message) { + err(message: string) { return err(key, message) }, key, } return { - run: (config, hints) => { + run: (config, hints: Record) => { fn(config, hints, api, hints[key]) }, key, @@ -59,7 +59,7 @@ const validateReleaseTypes = makeValidator('release-types', (_, hints, api) => { } }) -const validateUpdateDependants = makeValidator('update-dependants-for', (config, hints, api) => { +const validateUpdateDependants = makeValidator('update-dependants-for', (config: Config, hints: UpdateHints, api) => { const { dependants_release_type, update_dependants, diff --git a/packages/pvm-core/lib/httpreq.ts b/packages/pvm/lib/httpreq.ts similarity index 90% rename from packages/pvm-core/lib/httpreq.ts rename to packages/pvm/lib/httpreq.ts index 21cfff20c..d4e8285c4 100644 --- a/packages/pvm-core/lib/httpreq.ts +++ b/packages/pvm/lib/httpreq.ts @@ -36,7 +36,7 @@ function extractErrorMessage(jsonData: any, rawData: string): string { return cutText(JSON.stringify(jsonData), 190) } -export default function request(urlString: string, opts: HttpReqOptions = {}): Promise> { +export function httpreq(urlString: string, opts: HttpReqOptions = {}): Promise> { const url = new URL(urlString) const { headers = {}, method = 'GET' } = opts logger.debug(`making http ${method} request to ${urlString}`) @@ -131,20 +131,20 @@ const defaultRetryCodes = [ 429, ] -function wait(ms): Promise { +function wait(ms: number): Promise { return new Promise(resolve => { setTimeout(resolve, ms) }) } -export async function requestWithRetries(requestFn: () => any, retryOpts: { retryCodes?: number[], timeouts?: number[] } = {}, retryIndex = 0) { +export async function requestWithRetries Promise>(requestFn: T, retryOpts: { retryCodes?: number[], timeouts?: number[] } = {}, retryIndex = 0): Promise> { const { timeouts = defaultRetryTimeouts, retryCodes = defaultRetryCodes, } = retryOpts try { return await requestFn() - } catch (e) { + } catch (e: any) { // retry later if (retryCodes.indexOf(e.statusCode) !== -1) { const timeout = timeouts[retryIndex] diff --git a/packages/pvm/lib/index.ts b/packages/pvm/lib/index.ts deleted file mode 100644 index 303462f2e..000000000 --- a/packages/pvm/lib/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { Pvm } from '@pvm/core/lib/app' -export * from '@pvm/plugin-core/packages' diff --git a/packages/pvm-core/lib/inspect-args.ts b/packages/pvm/lib/inspect-args.ts similarity index 100% rename from packages/pvm-core/lib/inspect-args.ts rename to packages/pvm/lib/inspect-args.ts diff --git a/packages/pvm-core/lib/interop.ts b/packages/pvm/lib/interop.ts similarity index 65% rename from packages/pvm-core/lib/interop.ts rename to packages/pvm/lib/interop.ts index 3efe705cf..1faff69a4 100644 --- a/packages/pvm-core/lib/interop.ts +++ b/packages/pvm/lib/interop.ts @@ -1,8 +1,8 @@ -export function getDefault(mod) { +export function getDefault(mod: any) { return (mod && mod.__esModule) ? mod.default || mod : mod } -export function requireDefault(path) { +export function requireDefault(path: string) { // eslint-disable-next-line @typescript-eslint/no-var-requires return getDefault(require(path)) } diff --git a/packages/pvm-core/lib/is-monorepo.ts b/packages/pvm/lib/is-monorepo.ts similarity index 100% rename from packages/pvm-core/lib/is-monorepo.ts rename to packages/pvm/lib/is-monorepo.ts diff --git a/packages/pvm-core/lib/iter/cached-iteration.ts b/packages/pvm/lib/iter/cached-iteration.ts similarity index 90% rename from packages/pvm-core/lib/iter/cached-iteration.ts rename to packages/pvm/lib/iter/cached-iteration.ts index e1204ad4f..a8c1fd4ab 100644 --- a/packages/pvm-core/lib/iter/cached-iteration.ts +++ b/packages/pvm/lib/iter/cached-iteration.ts @@ -12,8 +12,8 @@ type AsyncIterableGetter = () => AsyncIterable const asyncIterablesCache = new Map, IterationStatus>() function iterateCached(getAsyncIterator: AsyncIterableGetter, ctx: any): AsyncIterableIterator { - let resolveFinished - let rejectFinished + let resolveFinished: (value?: unknown) => void + let rejectFinished: (e: Error) => void const makeInitialStatus = (): IterationStatus => { const willFinished: Promise = new Promise((resolve, reject) => { @@ -37,7 +37,7 @@ function iterateCached(getAsyncIterator: AsyncIterableGetter, ctx: any): A asyncIterablesCache.set(getAsyncIterator, status) } - async function * cachedIterator() { + async function * cachedIterator(): AsyncGenerator { if (status.finished) { for (const item of status.items) { yield item @@ -52,7 +52,7 @@ function iterateCached(getAsyncIterator: AsyncIterableGetter, ctx: any): A status.items.push(value) yield value } - } catch (e) { + } catch (e: any) { status.error = e throw e } finally { diff --git a/packages/pvm-core/lib/iter/collect-items.ts b/packages/pvm/lib/iter/collect-items.ts similarity index 100% rename from packages/pvm-core/lib/iter/collect-items.ts rename to packages/pvm/lib/iter/collect-items.ts diff --git a/packages/pvm-core/lib/iter/drain-items.ts b/packages/pvm/lib/iter/drain-items.ts similarity index 100% rename from packages/pvm-core/lib/iter/drain-items.ts rename to packages/pvm/lib/iter/drain-items.ts diff --git a/packages/pvm-core/lib/iter/index.ts b/packages/pvm/lib/iter/index.ts similarity index 97% rename from packages/pvm-core/lib/iter/index.ts rename to packages/pvm/lib/iter/index.ts index a6f6f3267..648191ad5 100644 --- a/packages/pvm-core/lib/iter/index.ts +++ b/packages/pvm/lib/iter/index.ts @@ -22,7 +22,7 @@ async function drainWhileResolves(asyncIterable: AsyncIterable): Promise(asyncIterable: AsyncIterable): AsyncIterableI break } yield [value, null] - } catch (e) { + } catch (e: any) { yield [void 0, e] break } diff --git a/packages/pvm-core/lib/iter/take-first.ts b/packages/pvm/lib/iter/take-first.ts similarity index 100% rename from packages/pvm-core/lib/iter/take-first.ts rename to packages/pvm/lib/iter/take-first.ts diff --git a/packages/pvm-core/lib/logger.ts b/packages/pvm/lib/logger.ts similarity index 85% rename from packages/pvm-core/lib/logger.ts rename to packages/pvm/lib/logger.ts index 752bf72c3..d01bbee79 100644 --- a/packages/pvm-core/lib/logger.ts +++ b/packages/pvm/lib/logger.ts @@ -11,7 +11,7 @@ if (!logLevel) { logLevel = /pvm/.test(DEBUG) ? 'debug' : 'info' } -const secretKeys = ['GL_TOKEN', 'GITLAB_TOKEN', 'GITHUB_TOKEN', 'GITHUB_AUTH'] +const secretKeys: Array = ['GL_TOKEN', 'GITLAB_TOKEN', 'GITHUB_TOKEN', 'GITHUB_AUTH'] const secrets = secretKeys.reduce((acc, key) => { const secret = env[key] @@ -49,6 +49,4 @@ export const logger = new Signales({ }) export const loggerFor = (scope: string) => logger.scope(scope) -export const debug = logger.debug.bind(logger) -export const error = logger.error.bind(logger) export const log = logger.log.bind(logger) diff --git a/packages/pvm-core/lib/markdownify-commits.ts b/packages/pvm/lib/markdownify-commits.ts similarity index 90% rename from packages/pvm-core/lib/markdownify-commits.ts rename to packages/pvm/lib/markdownify-commits.ts index 6b009be8f..a5f3fc638 100644 --- a/packages/pvm-core/lib/markdownify-commits.ts +++ b/packages/pvm/lib/markdownify-commits.ts @@ -2,14 +2,12 @@ import padLines from './text/pad-lines' import { issueToMdLink } from './text/jira' import { stripServiceLabels } from './text/commits' -import type { Commit } from '@pvm/types' - function fixBody(body: string): string { // больше чем две пустые строки заставляют markdown оборвать контекст элемента списка return body.replace(/\n(?:\s*\n){2,}/gm, '\n\n') } -function markdownifyCommits(commits: Commit[], opts: Record = {}): string { +function markdownifyCommits(commits: { subject: string, body: string }[], opts: Record = {}): string { const { // какие коммиты выкидываем ignorePatterns = [ @@ -27,7 +25,7 @@ function markdownifyCommits(commits: Commit[], opts: Record = {}): const doList = commits.length > 1 return commits.reduce((acc, commit) => { - const needIgnore = ignorePatterns.some(ignoreReStr => { + const needIgnore = ignorePatterns.some((ignoreReStr: string) => { const ignoreRe = eval(ignoreReStr) // eslint-disable-line no-eval return ignoreRe.test(commit.subject) diff --git a/packages/pvm-core/lib/memoize/index.ts b/packages/pvm/lib/memoize/index.ts similarity index 100% rename from packages/pvm-core/lib/memoize/index.ts rename to packages/pvm/lib/memoize/index.ts diff --git a/packages/pvm-core/lib/memoize/mema.ts b/packages/pvm/lib/memoize/mema.ts similarity index 100% rename from packages/pvm-core/lib/memoize/mema.ts rename to packages/pvm/lib/memoize/mema.ts diff --git a/packages/pvm-core/lib/memoize/tagged-cache-manager.ts b/packages/pvm/lib/memoize/tagged-cache-manager.ts similarity index 100% rename from packages/pvm-core/lib/memoize/tagged-cache-manager.ts rename to packages/pvm/lib/memoize/tagged-cache-manager.ts diff --git a/src/plugins/core/messages/message-builder.ts b/packages/pvm/lib/messages/message-builder.ts similarity index 91% rename from src/plugins/core/messages/message-builder.ts rename to packages/pvm/lib/messages/message-builder.ts index 65bd40842..366e9c48a 100644 --- a/src/plugins/core/messages/message-builder.ts +++ b/packages/pvm/lib/messages/message-builder.ts @@ -1,11 +1,11 @@ // This file refers to those that you can freely copy to your own project. -import type { Message, ReleasedProps, Commit, PublishedStats } from '@pvm/types' -import { issueToMdLink } from '@pvm/core/lib/text/jira' -import { stripServiceLabels } from '@pvm/core/lib/text/commits' -import { isGenericTagUsed } from '@pvm/core/lib/tag-meta' -import { padLines } from '@pvm/core/lib/text' +import type { Message, ReleasedProps, Commit, PublishedStats } from '../../types' +import { issueToMdLink } from '../text/jira' +import { stripServiceLabels } from '../text/commits' +import { isGenericTagUsed } from '../tag-meta' +import { padLines } from '../text' -import { env } from '@pvm/core/lib/env' +import { env } from '../env' function cutText(text: string, maxLen: number): string { return text.length <= maxLen ? text : text.substr(0, maxLen) @@ -78,7 +78,7 @@ export function defaultMessageBodyWrapper({ body, releaseLink, releaseName, pack body: string, releaseLink: string | null, releaseName: string, - packagesStats: PublishedStats + packagesStats: PublishedStats, }) { let header = releaseLink || releaseName diff --git a/src/plugins/core/messages/notify-scripts/release-with-packages.ts b/packages/pvm/lib/messages/notify-scripts/release-with-packages.ts similarity index 86% rename from src/plugins/core/messages/notify-scripts/release-with-packages.ts rename to packages/pvm/lib/messages/notify-scripts/release-with-packages.ts index f631a7fba..f8e8dea3c 100644 --- a/src/plugins/core/messages/notify-scripts/release-with-packages.ts +++ b/packages/pvm/lib/messages/notify-scripts/release-with-packages.ts @@ -1,5 +1,5 @@ // This file refers to those that you can freely copy to your own project. -import type { ReleasedProps } from '@pvm/types' +import type { ReleasedProps } from '../../../types' import { releaseMessage } from '../message-builder' process.on('message', (releaseProps: ReleasedProps) => { diff --git a/src/plugins/core/messages/notify-scripts/release.ts b/packages/pvm/lib/messages/notify-scripts/release.ts similarity index 86% rename from src/plugins/core/messages/notify-scripts/release.ts rename to packages/pvm/lib/messages/notify-scripts/release.ts index 665f2ddf3..3c1362631 100644 --- a/src/plugins/core/messages/notify-scripts/release.ts +++ b/packages/pvm/lib/messages/notify-scripts/release.ts @@ -1,5 +1,5 @@ // This file refers to those that you can freely copy to your own project. -import type { ReleasedProps } from '@pvm/types' +import type { ReleasedProps } from '../../../types' import { releaseMessage } from '../message-builder' process.on('message', (releaseProps: ReleasedProps) => { diff --git a/src/plugins/core/messages/notify-scripts/stale.ts b/packages/pvm/lib/messages/notify-scripts/stale.ts similarity index 91% rename from src/plugins/core/messages/notify-scripts/stale.ts rename to packages/pvm/lib/messages/notify-scripts/stale.ts index 460e3a07e..0d63756eb 100644 --- a/src/plugins/core/messages/notify-scripts/stale.ts +++ b/packages/pvm/lib/messages/notify-scripts/stale.ts @@ -1,5 +1,5 @@ // This file refers to those that you can freely copy to your own project. -import type { ReleasedProps } from '@pvm/types' +import type { ReleasedProps } from '../../../types' import { buildMessage } from '../message-builder' process.on('message', (releaseProps: ReleasedProps) => { diff --git a/packages/pvm-core/lib/node-boot.ts b/packages/pvm/lib/node-boot.ts similarity index 92% rename from packages/pvm-core/lib/node-boot.ts rename to packages/pvm/lib/node-boot.ts index 6b545e43c..494e78b1c 100644 --- a/packages/pvm-core/lib/node-boot.ts +++ b/packages/pvm/lib/node-boot.ts @@ -1,9 +1,10 @@ -import { error, logger } from './logger' -import shell from './shell' +import { logger } from './logger' +import { shell } from './shell' import { env } from './env' import { gitFetch } from './git/commands' import path from 'path' import fs from 'fs' +// @ts-ignore import ini from 'ini' function readNpmRc(cwd: string): string { @@ -16,14 +17,14 @@ const { version } = require('../package.json') let booted = false -const fail = (e) => { +const fail = (e: Error) => { logger.fatal(e) process.exitCode = 1 } nodeBoot() -function beforeExitCallback(exitCode): void { +function beforeExitCallback(exitCode: number): void { if (typeof exitCode === 'undefined') { logger.fatal('Deadlock detected!') process.exitCode = 1 @@ -52,7 +53,7 @@ function nodeBoot(): void { try { gitFetch(cwd) } catch (e) { - error(e) + logger.error(e) } } diff --git a/packages/pvm-core/lib/now.ts b/packages/pvm/lib/now.ts similarity index 100% rename from packages/pvm-core/lib/now.ts rename to packages/pvm/lib/now.ts diff --git a/packages/pvm-core/lib/packages/sort-by-release.ts b/packages/pvm/lib/packages/sort-by-release.ts similarity index 89% rename from packages/pvm-core/lib/packages/sort-by-release.ts rename to packages/pvm/lib/packages/sort-by-release.ts index cf91b5efa..49aaa512b 100644 --- a/packages/pvm-core/lib/packages/sort-by-release.ts +++ b/packages/pvm/lib/packages/sort-by-release.ts @@ -1,6 +1,6 @@ import { cmpReleaseTypes } from '../semver-extra' -import type { SemverReleaseType } from '@pvm/types' +import type { SemverReleaseType } from '../../types' import type { Pkg } from '../pkg' function sortByRelease(packages: Iterable, resolveReleaseTypeFor: (p: Pkg) => SemverReleaseType | null): Pkg[] { diff --git a/packages/pvm-core/lib/pkg-map.ts b/packages/pvm/lib/pkg-map.ts similarity index 100% rename from packages/pvm-core/lib/pkg-map.ts rename to packages/pvm/lib/pkg-map.ts diff --git a/packages/pvm-core/lib/pkg-match.ts b/packages/pvm/lib/pkg-match.ts similarity index 100% rename from packages/pvm-core/lib/pkg-match.ts rename to packages/pvm/lib/pkg-match.ts diff --git a/packages/pvm-core/lib/pkg-set.ts b/packages/pvm/lib/pkg-set.ts similarity index 100% rename from packages/pvm-core/lib/pkg-set.ts rename to packages/pvm/lib/pkg-set.ts diff --git a/packages/pvm-core/lib/pkg.ts b/packages/pvm/lib/pkg.ts similarity index 96% rename from packages/pvm-core/lib/pkg.ts rename to packages/pvm/lib/pkg.ts index 1a2c2e4f6..a62e21c1e 100644 --- a/packages/pvm-core/lib/pkg.ts +++ b/packages/pvm/lib/pkg.ts @@ -3,7 +3,7 @@ import fs from 'fs' import fastDeepEqual from 'fast-deep-equal' import { isSemverTagUsed, pkgTagMask, splitTag, stripPkgNamespace, isStubVersion, extractVersionFromSemverTag } from './tag-meta' -import defaultConfig from './config/defaults' +import { defaultConfig } from '../app/config' import { wdShell } from './shell' import isMonorepo from './is-monorepo' import { cachedRealPath } from './fs' @@ -15,8 +15,8 @@ import { isPkgFromMainUnifiedGroup, searchAnnotatedVersionInDepth } from './vers import { clone } from 'rfc6902/util' import revParse from './git/rev-parse' -import type { Config } from './config' -import type { PkgAppliedMeta, PkgDeps, PkgMeta } from '@pvm/types' +import type { Config, PkgAppliedMeta, PkgDeps, PkgMeta } from '../types' + import { cwdToGitRelativity } from './git/worktree' const logger = loggerFor('pvm:pkg') @@ -53,12 +53,12 @@ const allOwnDepsKeys = [ 'dependencies', 'devDependencies', 'optionalDependencies', -] +] as const const allDepsKeys = [ ...allOwnDepsKeys, 'peerDependencies', -] +] as const export interface PkgCreateOpts { indent?: number, @@ -244,14 +244,14 @@ export class Pkg { return false } - if (config.tagging.release_tag_package) { - return this.name === config.tagging.release_tag_package - } - if (config.versioning.unified) { return isPkgFromMainUnifiedGroup(this._config, this) } + if (config.tagging.release_tag_package) { + return this.name === config.tagging.release_tag_package + } + return true } @@ -315,10 +315,10 @@ export class Pkg { } // возвращает в каких ключах (dependencies, devDependencies, ...) есть переданная зависимость - getDepKeys(pkgName: string): string[] { - const result: string[] = [] + getDepKeys(pkgName: string): Array { + const result: Array = [] for (const depKey of allDepsKeys) { - if (this.meta[depKey] && pkgName in this.meta[depKey]) { + if (this.meta[depKey]?.[pkgName]) { result.push(depKey) } } @@ -365,10 +365,11 @@ export interface PkgDiff { export class AppliedPkg extends Pkg { protected _newDeps: Map = new Map() - meta: PkgAppliedMeta + override meta: PkgAppliedMeta constructor(pkgPath: string, manifest: PkgAppliedMeta, opts: PkgCreateOpts = {}) { super(pkgPath, manifest, opts) + this.meta = manifest } setNewDeps(newDeps: Map) { @@ -376,8 +377,8 @@ export class AppliedPkg extends Pkg { for (const [pkgName, depVersion] of newDeps) { const depKeys = this.getDepKeys(pkgName) for (const depKey of depKeys) { - const semverPrefix = detectRangePrefix(this.meta[depKey][pkgName]) - this.meta[depKey][pkgName] = `${semverPrefix}${depVersion}` + const semverPrefix = detectRangePrefix(this.meta[depKey]![pkgName]) + this.meta[depKey]![pkgName] = `${semverPrefix}${depVersion}` } } } diff --git a/packages/pvm-core/lib/read-lines.ts b/packages/pvm/lib/read-lines.ts similarity index 96% rename from packages/pvm-core/lib/read-lines.ts rename to packages/pvm/lib/read-lines.ts index 7f39db94e..749a640f0 100644 --- a/packages/pvm-core/lib/read-lines.ts +++ b/packages/pvm/lib/read-lines.ts @@ -12,7 +12,7 @@ async function * readLines(opts: ReadLinesOptions = {}) { let lingeringLine = '' let lines: string[] = [] - let resolver + let resolver: (res?: boolean) => void process.stdin.on('data', function(chunk) { lines = (chunk as unknown as string).split(splitter) diff --git a/packages/pvm-core/lib/runtime-env/versions.ts b/packages/pvm/lib/runtime-env/versions.ts similarity index 92% rename from packages/pvm-core/lib/runtime-env/versions.ts rename to packages/pvm/lib/runtime-env/versions.ts index 20053e232..e04871612 100644 --- a/packages/pvm-core/lib/runtime-env/versions.ts +++ b/packages/pvm/lib/runtime-env/versions.ts @@ -3,7 +3,7 @@ import { cwdShell } from '../shell' const semverRe = /\d+\.\d+\.\d+/ export function makeSemverGetter(cmd: string): () => string | undefined { - let versionCached + let versionCached: string | undefined return () => { if (!versionCached) { diff --git a/packages/pvm-core/lib/semver-extra.ts b/packages/pvm/lib/semver-extra.ts similarity index 97% rename from packages/pvm-core/lib/semver-extra.ts rename to packages/pvm/lib/semver-extra.ts index 654a5724b..0e3494167 100644 --- a/packages/pvm-core/lib/semver-extra.ts +++ b/packages/pvm/lib/semver-extra.ts @@ -1,5 +1,5 @@ import semver from 'semver' -import type { PvmReleaseType } from '@pvm/types' +import type { PvmReleaseType } from '../types' export const releaseTypesInAscendingOrder: PvmReleaseType[] = ['none', 'prerelease', 'prepatch', 'patch', 'preminor', 'minor', 'premajor', 'major'] diff --git a/packages/pvm-core/lib/shared.ts b/packages/pvm/lib/shared.ts similarity index 100% rename from packages/pvm-core/lib/shared.ts rename to packages/pvm/lib/shared.ts diff --git a/packages/pvm-core/lib/shell/exec.ts b/packages/pvm/lib/shell/exec.ts similarity index 94% rename from packages/pvm-core/lib/shell/exec.ts rename to packages/pvm/lib/shell/exec.ts index 16d8a70b4..2466b8180 100644 --- a/packages/pvm-core/lib/shell/exec.ts +++ b/packages/pvm/lib/shell/exec.ts @@ -1,5 +1,5 @@ import { spawn } from 'child_process' -import type { ExecShellOptions } from '@pvm/types' +import type { ExecShellOptions } from '../../types' interface ShellError extends Error { code: number | null, @@ -7,7 +7,7 @@ interface ShellError extends Error { stderr: string, } -interface ExecResult { +export interface ExecResult { stdout: string, stderr: string, } diff --git a/packages/pvm-core/lib/shell/index.ts b/packages/pvm/lib/shell/index.ts similarity index 96% rename from packages/pvm-core/lib/shell/index.ts rename to packages/pvm/lib/shell/index.ts index 5fbea46a9..189c45b2c 100644 --- a/packages/pvm-core/lib/shell/index.ts +++ b/packages/pvm/lib/shell/index.ts @@ -2,7 +2,7 @@ import type { ExecSyncOptions, SpawnSyncReturns } from 'child_process' import { spawnSync } from 'child_process' import { logger } from '../logger' -let lastLoggedCommand +let lastLoggedCommand: string export class ShellError extends Error { stderr: string | Buffer = '' @@ -103,6 +103,3 @@ export function shellOr(def: string, cmd: string, opts: ExecSyncOptions = {}): s return def } } - -// @deprecated import cwdShell or wdShell instead -export default shell diff --git a/packages/pvm-core/lib/shell/run.ts b/packages/pvm/lib/shell/run.ts similarity index 84% rename from packages/pvm-core/lib/shell/run.ts rename to packages/pvm/lib/shell/run.ts index 4f8729988..151c15d73 100644 --- a/packages/pvm-core/lib/shell/run.ts +++ b/packages/pvm/lib/shell/run.ts @@ -1,8 +1,8 @@ // как shell, только не захватываем вывод рисуя все как есть import { spawn } from 'child_process' -import type { StdioOptions } from 'child_process' +import type { StdioOptions, ChildProcess } from 'child_process' -import type { RunShellOptions } from '@pvm/types' +import type { RunShellOptions } from '../../types' import WritableStream = NodeJS.WritableStream import { env } from '../env' @@ -21,22 +21,24 @@ export interface RunShellError extends Error { function stdioSmartHandler(stdio: StdioOptions) { stdio = stdioAsArray(stdio) - const streamNames = ['stdin', 'stdout', 'stderr'] - const replacedStreams: Record = {} + const streamNames = ['stdin', 'stdout', 'stderr'] as const + const replacedStreams: Record<'stdin' | 'stdout' | 'stderr', WritableStream> = {} as any stdio = stdio.map((maybeStream, i) => { // keep stdin as is if (i === 0) { return maybeStream } + // @ts-ignore + // todo: fix types if (typeof maybeStream === 'object' && maybeStream !== null && typeof maybeStream['write'] === 'function' && !('fd' in maybeStream)) { replacedStreams[streamNames[i]] = maybeStream as unknown as WritableStream return 'pipe' } return maybeStream }) - const handler = (child) => { - for (const [name, stream] of Object.entries(replacedStreams)) { - child[name].on('data', data => { + const handler = (child: ChildProcess) => { + for (const [name, stream] of Object.entries(replacedStreams) as Array<['stdin' | 'stdout' | 'stderr', WritableStream]>) { + child[name]?.on('data', (data: string) => { stream.write(data) }) } diff --git a/packages/pvm-core/lib/tag-meta.ts b/packages/pvm/lib/tag-meta.ts similarity index 96% rename from packages/pvm-core/lib/tag-meta.ts rename to packages/pvm/lib/tag-meta.ts index ef3c88bd6..8b4940be6 100644 --- a/packages/pvm-core/lib/tag-meta.ts +++ b/packages/pvm/lib/tag-meta.ts @@ -1,6 +1,6 @@ import isMonorepo from './is-monorepo' import type { Pkg } from './pkg' -import type { Config } from './config' +import type { Config } from '../types' import { isFlatArraysEqual } from './utils' export const pkgTagRe = /-v\d+\.\d+\.\d+/ @@ -46,7 +46,7 @@ export function makeUnifiedReleaseTagTest(config: Config): (tagName: string) => } } -export function releaseTagFilter(config: Config): (string) => boolean { +export function releaseTagFilter(config: Config): (s: string) => boolean { return isGenericTagUsed(config) ? makeUnifiedReleaseTagTest(config) : isSemverTag } diff --git a/packages/pvm-core/lib/text/commits.ts b/packages/pvm/lib/text/commits.ts similarity index 57% rename from packages/pvm-core/lib/text/commits.ts rename to packages/pvm/lib/text/commits.ts index ad5d25b01..5aebee6ff 100644 --- a/packages/pvm-core/lib/text/commits.ts +++ b/packages/pvm/lib/text/commits.ts @@ -1,4 +1,7 @@ -import { tags as serviceLabelPatterns } from '../analyzer/simple' +const isPatchRe = /^(fix|patch):/i +const isMajorRe = /^BREAKING CHANGE:/ + +const serviceLabelPatterns = [isPatchRe, isMajorRe] export function stripServiceLabels(text: string): string { return serviceLabelPatterns.reduce((acc, labelRe) => { diff --git a/packages/pvm-core/lib/text/index.ts b/packages/pvm/lib/text/index.ts similarity index 100% rename from packages/pvm-core/lib/text/index.ts rename to packages/pvm/lib/text/index.ts diff --git a/packages/pvm-core/lib/text/jira.ts b/packages/pvm/lib/text/jira.ts similarity index 100% rename from packages/pvm-core/lib/text/jira.ts rename to packages/pvm/lib/text/jira.ts diff --git a/packages/pvm-core/lib/text/markdown.ts b/packages/pvm/lib/text/markdown.ts similarity index 77% rename from packages/pvm-core/lib/text/markdown.ts rename to packages/pvm/lib/text/markdown.ts index bfd6e0df9..e704d8190 100644 --- a/packages/pvm-core/lib/text/markdown.ts +++ b/packages/pvm/lib/text/markdown.ts @@ -7,11 +7,11 @@ export function pullOutLinks(text: string): string { }) } -export function replaceLinks(text: string, replacer): string { +export function replaceLinks(text: string, replacer: ((substr: string, subj: string, link: string) => string)): string { return text.replace(mrkdwnLinkRe, replacer) } -const escapeRe = (s) => { +const escapeRe = (s: string) => { return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&') } diff --git a/packages/pvm-core/lib/text/pad-lines.ts b/packages/pvm/lib/text/pad-lines.ts similarity index 100% rename from packages/pvm-core/lib/text/pad-lines.ts rename to packages/pvm/lib/text/pad-lines.ts diff --git a/packages/pvm-core/lib/text/plural.ts b/packages/pvm/lib/text/plural.ts similarity index 100% rename from packages/pvm-core/lib/text/plural.ts rename to packages/pvm/lib/text/plural.ts diff --git a/packages/pvm-core/lib/text/sub-args.ts b/packages/pvm/lib/text/sub-args.ts similarity index 100% rename from packages/pvm-core/lib/text/sub-args.ts rename to packages/pvm/lib/text/sub-args.ts diff --git a/packages/pvm-core/lib/text/template.ts b/packages/pvm/lib/text/template.ts similarity index 65% rename from packages/pvm-core/lib/text/template.ts rename to packages/pvm/lib/text/template.ts index a939627bf..18d0293e8 100644 --- a/packages/pvm-core/lib/text/template.ts +++ b/packages/pvm/lib/text/template.ts @@ -1,7 +1,7 @@ const valueRe = /{([^}]+)}/g -function replace(str, values, def = '') { +function replace(str: string, values: Record, def = '') { return str.replace(valueRe, (_, name) => { return values[name] || def }) diff --git a/packages/pvm-core/lib/utils.ts b/packages/pvm/lib/utils.ts similarity index 79% rename from packages/pvm-core/lib/utils.ts rename to packages/pvm/lib/utils.ts index d5b2956c6..5b2d69b4d 100644 --- a/packages/pvm-core/lib/utils.ts +++ b/packages/pvm/lib/utils.ts @@ -3,6 +3,8 @@ import chalk from 'chalk' import type { Pkg as PkgType } from './pkg' import type { SignaleType } from 'signales' import { env } from './env' +import { logger } from './logger' +import { inspectArgs } from './inspect-args' export function isFlatArraysEqual(left: T[], right: T[]): boolean { if (left.length !== right.length) { @@ -90,3 +92,24 @@ export function handleDifferentComparisonRefs(logger: SignaleType, storedPkg: Pk } logger.error(chalk`Incorrect comparison of two packages with same name {blue ${storedPkg.name}} but constructed from different refs {yellow ${storedPkg.ref}} and {yellow ${providedPkg.ref}}`) } + +export function logDryRun(_target: { dryRun: boolean }, propName: string, descriptor: TypedPropertyDescriptor): void { + const method = descriptor.value! + descriptor.value = function(this: { dryRun: boolean }, ...args: any[]) { + if (this.dryRun) { + logger.debug(`DRY RUN: ${propName}`, `(${inspectArgs(args)})`) + } + + return method.call(this, ...args) + } +} + +export function typedObjectKeys>(obj: T): Array { + const keys: Array = [] + + for (const k of Object.keys(obj)) { + keys.push(k) + } + + return keys +} diff --git a/packages/pvm-core/lib/utils/array.ts b/packages/pvm/lib/utils/array.ts similarity index 100% rename from packages/pvm-core/lib/utils/array.ts rename to packages/pvm/lib/utils/array.ts diff --git a/packages/pvm-core/lib/utils/cmd.ts b/packages/pvm/lib/utils/cmd.ts similarity index 100% rename from packages/pvm-core/lib/utils/cmd.ts rename to packages/pvm/lib/utils/cmd.ts diff --git a/packages/pvm-core/lib/utils/pprint.ts b/packages/pvm/lib/utils/pprint.ts similarity index 100% rename from packages/pvm-core/lib/utils/pprint.ts rename to packages/pvm/lib/utils/pprint.ts diff --git a/packages/pvm-core/lib/utils/string.ts b/packages/pvm/lib/utils/string.ts similarity index 100% rename from packages/pvm-core/lib/utils/string.ts rename to packages/pvm/lib/utils/string.ts diff --git a/packages/pvm-core/lib/vcs-meta.ts b/packages/pvm/lib/vcs-meta.ts similarity index 100% rename from packages/pvm-core/lib/vcs-meta.ts rename to packages/pvm/lib/vcs-meta.ts diff --git a/packages/pvm-core/lib/versioning.ts b/packages/pvm/lib/versioning.ts similarity index 98% rename from packages/pvm-core/lib/versioning.ts rename to packages/pvm/lib/versioning.ts index 5b3ac47f1..1b8c2827e 100644 --- a/packages/pvm-core/lib/versioning.ts +++ b/packages/pvm/lib/versioning.ts @@ -6,7 +6,7 @@ import { logger } from './logger' import { releaseMark } from './consts' import gitRevParse from './git/rev-parse' -import type { Config } from './config' +import type { Config } from '../types' import type { Pkg } from './pkg' export function isReleaseCommit(cwd: string, ref: string): boolean { diff --git a/packages/pvm-viz/lib/index.ts b/packages/pvm/lib/viz/index.ts similarity index 91% rename from packages/pvm-viz/lib/index.ts rename to packages/pvm/lib/viz/index.ts index e6b12c3f5..3e4ab6b44 100644 --- a/packages/pvm-viz/lib/index.ts +++ b/packages/pvm/lib/viz/index.ts @@ -1,4 +1,6 @@ +// @ts-ignore import Viz from 'viz.js' +// @ts-ignore import { Module, render } from 'viz.js/full.render.js' let viz = new Viz({ Module, render }) diff --git a/packages/pvm-core/lib/workspaces.ts b/packages/pvm/lib/workspaces.ts similarity index 94% rename from packages/pvm-core/lib/workspaces.ts rename to packages/pvm/lib/workspaces.ts index 305a4af16..7d4f56b48 100644 --- a/packages/pvm-core/lib/workspaces.ts +++ b/packages/pvm/lib/workspaces.ts @@ -4,8 +4,9 @@ import glob from 'fast-glob' import micromatch from 'micromatch' import { wdShell } from './shell' import { cwdToGitRelativity } from './git/worktree' +import type { PkgMeta } from '../types' -function getPkgDirPatterns(pkg): string[] { +function getPkgDirPatterns(pkg: PkgMeta): string[] { const { workspaces = [] } = pkg if (Array.isArray(workspaces)) { @@ -34,7 +35,7 @@ enum WorkspacePatternsStatus { type WorkspacesPatternsResult = [WorkspacePatternsStatus.Ok | WorkspacePatternsStatus.EndResult, string[]] -function workspacePatternsFromManifest(pkg): WorkspacesPatternsResult { +function workspacePatternsFromManifest(pkg: PkgMeta): WorkspacesPatternsResult { if (!pkg) { return [WorkspacePatternsStatus.EndResult, []] } diff --git a/packages/pvm-add-tag/lib/get-new-tag.ts b/packages/pvm/mechanics/add-tag/get-new-tag.ts similarity index 58% rename from packages/pvm-add-tag/lib/get-new-tag.ts rename to packages/pvm/mechanics/add-tag/get-new-tag.ts index 085b56631..dd3f63c52 100644 --- a/packages/pvm-add-tag/lib/get-new-tag.ts +++ b/packages/pvm/mechanics/add-tag/get-new-tag.ts @@ -1,12 +1,14 @@ -import { lastReleaseTag } from '@pvm/core/lib/git/last-release-tag' -import { log } from '@pvm/core/lib/logger' -import { wdShell } from '@pvm/core/lib/shell' -import { getUpdateState } from '@pvm/update' -import { createReleaseContext } from '@pvm/update/lib/release/release-context' +import { lastReleaseTag } from '../../lib/git/last-release-tag' +import { log } from '../../lib/logger' +import { wdShell } from '../../lib/shell' +import { getUpdateState } from '../update' +import { createReleaseContext } from '../update/release/release-context' -import type { Config } from '@pvm/core/lib/config' +import type { Container } from '../../lib/di' +import { CONFIG_TOKEN } from '../../tokens' -export async function getNewTag(config: Config, targetRef = 'HEAD'): Promise { +export async function getNewTag(di: Container, targetRef = 'HEAD'): Promise { + const config = di.get(CONFIG_TOKEN) const lastRelease = lastReleaseTag(config, targetRef) const lastRevision = lastRelease ? wdShell(config.cwd, `git rev-list -1 ${lastRelease}`) : null @@ -17,7 +19,7 @@ export async function getNewTag(config: Config, targetRef = 'HEAD'): Promise { const workingDir = tempy.directory({ prefix: 'pvm' }) - this.workingDir = workingDir + this._workingDir = workingDir logger.info(`Initialized worktree at "${workingDir}" for branch "${this.branch}"`) const artifactsExistsLocally = isBranchExists(this.cwd, this.branch) const artifactsExistsRemote = isRemoteBranchExists(this.cwd, this.branch) @@ -97,7 +119,11 @@ export class GitBranchStorage implements StorageImpl { } async uploadPath(localPath: string, remoteDest: string): Promise { - const gitVcs = initGitVcs(this.workingDir) + const gitVcs = new GitVcs({ + cwd: this.workingDir, + config: this.config, + resolvePushRemote: this.resolvePushRemote, + }) const commitContext = await gitVcs.beginCommit() const sourcePath = path.join(this.cwd, localPath) diff --git a/packages/pvm-artifacts/lib/backend/vcs-storage.ts b/packages/pvm/mechanics/artifacts/backend/vcs-storage.ts similarity index 74% rename from packages/pvm-artifacts/lib/backend/vcs-storage.ts rename to packages/pvm/mechanics/artifacts/backend/vcs-storage.ts index 450504f09..4a373b30c 100644 --- a/packages/pvm-artifacts/lib/backend/vcs-storage.ts +++ b/packages/pvm/mechanics/artifacts/backend/vcs-storage.ts @@ -1,12 +1,10 @@ -import type { VcsPlatform } from '@pvm/vcs/lib' import type { StorageImpl } from '../storage.h' +import type { VcsPlatform } from '../../vcs' export class VcsStorage implements StorageImpl { - vcs: VcsPlatform - - constructor(vcs: VcsPlatform) { - this.vcs = vcs + // eslint-disable-next-line no-useless-constructor + constructor(protected vcs: VcsPlatform) { } async init(): Promise { diff --git a/packages/pvm-artifacts/lib/frontend/changelogs.ts b/packages/pvm/mechanics/artifacts/frontend/changelogs.ts similarity index 100% rename from packages/pvm-artifacts/lib/frontend/changelogs.ts rename to packages/pvm/mechanics/artifacts/frontend/changelogs.ts diff --git a/packages/pvm-artifacts/lib/frontend/release-list.ts b/packages/pvm/mechanics/artifacts/frontend/release-list.ts similarity index 100% rename from packages/pvm-artifacts/lib/frontend/release-list.ts rename to packages/pvm/mechanics/artifacts/frontend/release-list.ts diff --git a/packages/pvm-artifacts/pub/artifacts.ts b/packages/pvm/mechanics/artifacts/pub/artifacts.ts similarity index 64% rename from packages/pvm-artifacts/pub/artifacts.ts rename to packages/pvm/mechanics/artifacts/pub/artifacts.ts index b376828a5..6d0fe6e94 100644 --- a/packages/pvm-artifacts/pub/artifacts.ts +++ b/packages/pvm/mechanics/artifacts/pub/artifacts.ts @@ -1,8 +1,8 @@ import chalk from 'chalk' -import initVcs from '@pvm/vcs' -import { logger } from '@pvm/core/lib/logger' -import { getConfig } from '@pvm/core/lib/config' -import { StorageManager, ArtifactsStorages } from '../lib/storage-manager' +import { logger } from '../../../lib/logger' +import { StorageManager, ArtifactsStorages } from '../storage-manager' +import type { Container } from '../../../lib/di' +import { CONFIG_TOKEN } from '../../../tokens' export interface ArtifactsTransferArgs { force?: boolean, @@ -12,18 +12,12 @@ export interface ArtifactsTransferArgs { export type TransferDirection = 'upload' | 'download' -async function transfer(__args: ArtifactsTransferArgs, direction: TransferDirection): Promise { +async function transfer(di: Container, __args: ArtifactsTransferArgs, direction: TransferDirection): Promise { const { kind, quiet = false, force = false } = __args - const cwd = process.cwd() - const config = await getConfig(cwd) - const vcs = await initVcs({ - vcsType: 'fs', - cwd, - }) + const config = di.get(CONFIG_TOKEN) const storageManager = new StorageManager({ - config, - vcs, + di, }) const storageType = StorageManager.castStorageType(kind) @@ -49,12 +43,12 @@ async function transfer(__args: ArtifactsTransferArgs, direction: TransferDirect } } -async function upload(args: ArtifactsTransferArgs): Promise { - await transfer(args, 'upload' as const) +async function upload(di: Container, args: ArtifactsTransferArgs): Promise { + await transfer(di, args, 'upload' as const) } -async function download(args: ArtifactsTransferArgs): Promise { - await transfer(args, 'download' as const) +async function download(di: Container, args: ArtifactsTransferArgs): Promise { + await transfer(di, args, 'download' as const) } export { diff --git a/packages/pvm-artifacts/lib/storage-manager.ts b/packages/pvm/mechanics/artifacts/storage-manager.ts similarity index 92% rename from packages/pvm-artifacts/lib/storage-manager.ts rename to packages/pvm/mechanics/artifacts/storage-manager.ts index 8b705cdd9..49c4e28ed 100644 --- a/packages/pvm-artifacts/lib/storage-manager.ts +++ b/packages/pvm/mechanics/artifacts/storage-manager.ts @@ -1,9 +1,10 @@ import type { InitStorageDeps, Storage } from './storage' -import type { StorageDef, Config } from '@pvm/core/lib/config/types' +import type { StorageDef, Config } from '../../types' import { ChangelogsStorage } from './frontend/changelogs' import { ReleaseListStorage } from './frontend/release-list' import { instatiateStorage } from './storage' -import { loggerFor } from '@pvm/core/lib/logger' +import { loggerFor } from '../../lib/logger' +import { CONFIG_TOKEN } from '../../tokens' const logger = loggerFor('pvm:artifacts') @@ -53,7 +54,8 @@ export class StorageManager { } async initFor(artifactsStorage: S): Promise> { - const { config } = this.initStorageDeps + const { di } = this.initStorageDeps + const config = di.get(CONFIG_TOKEN) switch (artifactsStorage) { case ArtifactsStorages.ReleaseList: { const result = await this.init(ReleaseListStorage, config.release_list.storage) diff --git a/packages/pvm-artifacts/lib/storage.h.ts b/packages/pvm/mechanics/artifacts/storage.h.ts similarity index 100% rename from packages/pvm-artifacts/lib/storage.h.ts rename to packages/pvm/mechanics/artifacts/storage.h.ts diff --git a/packages/pvm-artifacts/lib/storage.ts b/packages/pvm/mechanics/artifacts/storage.ts similarity index 81% rename from packages/pvm-artifacts/lib/storage.ts rename to packages/pvm/mechanics/artifacts/storage.ts index 9843532d2..c4bf9884e 100644 --- a/packages/pvm-artifacts/lib/storage.ts +++ b/packages/pvm/mechanics/artifacts/storage.ts @@ -2,12 +2,13 @@ import path from 'path' import { GitBranchStorage } from './backend/git-branch-storage' import { VcsStorage } from './backend/vcs-storage' import { ExternalStorage } from './backend/external-storage' -import { loggerFor } from '@pvm/core/lib/logger' +import { loggerFor } from '../../lib/logger' + +import type { Config, StorageDef } from '../../types' -import type { Config } from '@pvm/core/lib/config' -import type { StorageDef } from '@pvm/core/lib/config/types' -import type { VcsPlatform } from '@pvm/vcs' import type { StorageImpl } from './storage.h' +import type { Container } from '../../lib/di' +import { CONFIG_TOKEN, GLOBAL_FLAGS_TOKEN, VCS_PLATFORM_TOKEN } from '../../tokens' const finalizedMap = new WeakMap() const storagesPool = new Map() @@ -15,12 +16,13 @@ const storagesPool = new Map() const logger = loggerFor('pvm:artifacts') export interface InitStorageDeps { - vcs: VcsPlatform, - config: Config, + di: Container, } export interface StorageOpts { config: Config, + dryRun: boolean, + localMode: boolean, type: StorageDef['type'], destPrefix?: string, } @@ -29,12 +31,16 @@ export class Storage { destPrefix?: string storage: StorageImpl config: Config + dryRun: boolean + localMode: boolean type: StorageDef['type'] logger = logger constructor(storage: StorageImpl, opts: StorageOpts) { this.storage = storage this.config = opts.config + this.dryRun = opts.dryRun + this.localMode = opts.localMode this.destPrefix = opts.destPrefix this.type = opts.type } @@ -64,8 +70,8 @@ export class Storage { if (!this.finalized) { const remotePath = this.destPrefix ? path.join(this.destPrefix, localPath) : localPath logger.info(`Upload "${localPath}" to "${remotePath}"`) - if (this.config.executionContext.dryRun || this.config.executionContext.local) { - logger.info(`skip uploading due to ${this.config.executionContext.dryRun ? 'dry run' : 'local mode'}`) + if (this.dryRun || this.localMode) { + logger.info(`skip uploading due to ${this.dryRun ? 'dry run' : 'local mode'}`) return } return await this.storage.uploadPath(localPath, remotePath) @@ -78,7 +84,7 @@ export class Storage { if (!this.finalized) { const remotePath = this.destPrefix ? path.join(this.destPrefix, wantedLocalPath) : wantedLocalPath logger.info(`Download "${remotePath}" to "${wantedLocalPath}"`) - if (this.config.executionContext.dryRun) { + if (this.dryRun) { logger.info('skip downloading due to dry run') return } @@ -91,12 +97,9 @@ export class Storage { function createStorageImpl(deps: InitStorageDeps, storageDef: StorageDef): StorageImpl { if (storageDef.type === 'repo') { - return new VcsStorage(deps.vcs) + return new VcsStorage(deps.di.get(VCS_PLATFORM_TOKEN)) } else if (storageDef.type === 'branch') { - return new GitBranchStorage({ - cwd: deps.config.cwd, - branch: storageDef.branch, - }) + return new GitBranchStorage({ di: deps.di, branch: storageDef.branch }) } else if (storageDef.type === 'external') { return new ExternalStorage() } @@ -118,9 +121,12 @@ async function lazyInitStorageImpl(deps: InitStorageDeps, storageDef: StorageDef export async function instatiateStorage(StorageKlass: S, deps: InitStorageDeps, storageDef: StorageDef): Promise> { const storage = await lazyInitStorageImpl(deps, storageDef) + const globalFlags = deps.di.get(GLOBAL_FLAGS_TOKEN) return new StorageKlass(storage, { type: storageDef.type, - config: deps.config, + config: deps.di.get(CONFIG_TOKEN), + dryRun: globalFlags.getFlag('dryRun'), + localMode: globalFlags.getFlag('localMode'), destPrefix: storageDef.type !== 'external' ? storageDef.dest : undefined, }) as unknown as InstanceType } diff --git a/packages/pvm-changelog/lib/indent-headings.ts b/packages/pvm/mechanics/changelog/indent-headings.ts similarity index 100% rename from packages/pvm-changelog/lib/indent-headings.ts rename to packages/pvm/mechanics/changelog/indent-headings.ts diff --git a/packages/pvm-changelog/lib/index.ts b/packages/pvm/mechanics/changelog/index.ts similarity index 56% rename from packages/pvm-changelog/lib/index.ts rename to packages/pvm/mechanics/changelog/index.ts index aea41ffa9..bcf2ded4e 100644 --- a/packages/pvm-changelog/lib/index.ts +++ b/packages/pvm/mechanics/changelog/index.ts @@ -1,27 +1,24 @@ import fs from 'fs' +import { mkdirp } from '../../lib/fs' import path from 'path' import frontMatter from 'front-matter' -import resolveFrom from 'resolve-from' -import { requireDefault } from '@pvm/core/lib' -import { loggerFor } from '@pvm/core/lib/logger' -import { getConfig } from '@pvm/core/lib/config' -import { getHostApi } from '@pvm/core/lib/plugins' -import { mkdirp } from '@pvm/core/lib/fs' -import pkgsetAll from '@pvm/pkgset/lib/strategies/all' -import { lazyCompileTemplate } from '@pvm/template/lib' -import provideBuiltinRenderers from './provide-builtin-renderers' +import { loggerFor } from '../../lib/logger' + +import pkgsetAll from '../pkgset/strategies/all' +import { lazyCompileTemplate } from '../template' import { pkgChangelogPath } from './rules' -import { releaseDataMaker } from '@pvm/releases/lib/release-data' -import { wdmemoize, CacheTag } from '@pvm/core/lib/memoize' -import { prevReleaseTag } from '@pvm/core/lib/git/last-release-tag' -import { wdShell } from '@pvm/core/lib/shell' - -import type { Pkg } from '@pvm/core/lib/pkg' -import type { ReleaseContext } from '@pvm/update/types' -import type { Config } from '@pvm/core/lib/config' -import type { Renderer, IncrementalRenderer } from '../types' -import type { ReleaseData } from '@pvm/releases/types' -import { cwdToGitRelativity } from '@pvm/core/lib/git/worktree' +import { releaseDataMaker } from '../releases/release-data' +import { prevReleaseTag } from '../../lib/git/last-release-tag' +import { wdShell } from '../../lib/shell' + +import type { Pkg } from '../../lib/pkg' +import type { ReleaseContext } from '../update/types' +import type { Config } from '../../types' +import type { Renderer, IncrementalRenderer } from './types' +import type { ReleaseData } from '../releases/types' +import { cwdToGitRelativity } from '../../lib/git/worktree' +import type { Container } from '../../lib/di' +import { CHANGELOG_RENDERERS_MAP, CONFIG_TOKEN, GLOBAL_FLAGS_TOKEN } from '../../tokens' const logger = loggerFor('pvm:changelog') @@ -30,49 +27,21 @@ export enum RenderTarget { markPr, } -export async function getRendererPure(cwd: string, rendererTarget: RenderTarget = RenderTarget.changelog): Promise { - const config = await getConfig(cwd) - await provideBuiltinRenderers(config.cwd) +export async function getRenderer(di: Container, rendererTarget: RenderTarget = RenderTarget.changelog): Promise { + const config = di.get(CONFIG_TOKEN) + const renderersMap = di.get(CHANGELOG_RENDERERS_MAP) const { renderer } = rendererTarget === RenderTarget.changelog ? config.changelog : config.mark_pr - const hostApi = await getHostApi(config.cwd) - - let RendererClass: new() => Renderer | IncrementalRenderer - - switch (renderer.type) { - case 'builtin.list': - case 'builtin.list-with-packages': - RendererClass = hostApi.getOr(`changelog.${renderer.type}`, null) - break - case 'commonjs': { - const filePath = resolveFrom(config.cwd, renderer.path) - RendererClass = requireDefault(filePath) - if (!RendererClass) { - throw new Error(`Renderer not found at ${renderer.path}, check your pvm settings.`) - } - break - } - case 'by-plugin': { - if (!renderer.providesPath.startsWith('changelog.')) { - throw new Error(`renderer.providesPath for type "by-plugin" should starts with "changelog." but got "${renderer.providesPath}" instead.`) - } - RendererClass = hostApi.getOr(renderer.providesPath, null) - if (!RendererClass) { - throw new Error(`There are no plugins who provides "${renderer.providesPath}" entry.`) - } - break - } - } - if (typeof RendererClass !== 'function') { - throw new Error(`Changelog renderer should be class, but got ${typeof RendererClass}. config.changelog.renderer.type is "${config.changelog.renderer.type}"`) + const rendererInstance = renderersMap[renderer.type] + + if (!rendererInstance) { + throw new Error(`Changelog renderer should be defined`) } - return new RendererClass() + return rendererInstance } -export const getRenderer = wdmemoize(getRendererPure, [CacheTag.pvmConfig]) - export interface ChangelogContents { body: string, attributes: Record, @@ -98,17 +67,17 @@ function readChangelog(changelogPath: string): ChangelogContents { return frontMatter(content) } -export async function renderReleaseContext(releaseContext: ReleaseContext, renderTarget: RenderTarget, forPkg: Pkg | void = void 0): Promise { - const { cwd } = releaseContext.updateState.repo - const renderer = await getRenderer(cwd, renderTarget) +export async function renderReleaseContext(di: Container, releaseContext: ReleaseContext, renderTarget: RenderTarget, forPkg: Pkg | void = void 0): Promise { + const renderer = await getRenderer(di, renderTarget) const releaseData = await releaseDataMaker.fromReleaseContext(releaseContext) return renderer.render(releaseData ? [releaseData] : [], forPkg?.name) } -async function getReleasesRenderer(config: Config, releaseData?: ReleaseData): Promise<(contents: ChangelogContents, forPkg?: Pkg) => Promise> { +async function getReleasesRenderer(di: Container, releaseData?: ReleaseData): Promise<(contents: ChangelogContents, forPkg?: Pkg) => Promise> { + const config = di.get(CONFIG_TOKEN) return async (contents: ChangelogContents, forPkg: Pkg | undefined = void 0): Promise => { - const renderer = await getRenderer(config.cwd) + const renderer = await getRenderer(di) const conf = forPkg ? config.changelog.for_packages : config.changelog const isIncremental = 'append' in renderer @@ -141,7 +110,7 @@ async function getReleasesRenderer(config: Config, releaseData?: ReleaseData): P } if ((needToRenderReleaseList || !contents.frontmatter) && conf.front_matter) { - const template = await lazyCompileTemplate(conf.front_matter) + const template = await lazyCompileTemplate(config, conf.front_matter) contents.frontmatter = template.render({ pkg: forPkg, }) @@ -183,46 +152,51 @@ function isPkgNew(config: Config, pkg: Pkg): boolean { return false } -async function mainChangelog(config: Config, releaseData?: ReleaseData): Promise { - const renderReleases = await getReleasesRenderer(config, releaseData) +async function mainChangelog(di: Container, releaseData?: ReleaseData): Promise { + const renderReleases = await getReleasesRenderer(di, releaseData) + const config = di.get(CONFIG_TOKEN) const contents = readChangelog(path.join(config.cwd, config.changelog.path)) return renderReleases(contents) } -async function packagesChangelog(config: Config, releaseData?: ReleaseData): Promise { +async function packagesChangelog(di: Container, releaseData?: ReleaseData): Promise { const pkgsetOpts = { includeRoot: false, } - const renderReleases = await getReleasesRenderer(config, releaseData) + const renderReleases = await getReleasesRenderer(di, releaseData) - for await (const pkg of pkgsetAll(pkgsetOpts)) { + for await (const pkg of pkgsetAll(di, pkgsetOpts)) { logger.debug(`update changelog for ${pkg.name}`) + const config = di.get(CONFIG_TOKEN) + const dryRun = di.get(GLOBAL_FLAGS_TOKEN).getFlag('dryRun') const changelogAbsPath = pkgChangelogPath(config, pkg) const contents = readChangelog(changelogAbsPath) mkdirp(path.dirname(changelogAbsPath)) const result = await renderReleases(contents, pkg) - if (!config.executionContext.dryRun) { + if (!dryRun) { fs.writeFileSync(changelogAbsPath, result) } } } -async function makeChangelog(config: Config, releaseData?: ReleaseData): Promise { +async function makeChangelog(di: Container, releaseData?: ReleaseData): Promise { + const config = di.get(CONFIG_TOKEN) + const dryRun = di.get(GLOBAL_FLAGS_TOKEN).getFlag('dryRun') const conf = config.changelog mkdirp(path.dirname(conf.path)) - const result = await mainChangelog(config, releaseData) - if (!config.executionContext.dryRun) { + const result = await mainChangelog(di, releaseData) + if (!dryRun) { fs.writeFileSync(conf.path, result) } if (conf.for_packages.enabled) { - await packagesChangelog(config, releaseData) + await packagesChangelog(di, releaseData) } } diff --git a/packages/pvm-changelog/lib/md/grouped-table.tsi b/packages/pvm/mechanics/changelog/md/grouped-table.tsi similarity index 95% rename from packages/pvm-changelog/lib/md/grouped-table.tsi rename to packages/pvm/mechanics/changelog/md/grouped-table.tsi index 4a4a26701..4aa074eab 100644 --- a/packages/pvm-changelog/lib/md/grouped-table.tsi +++ b/packages/pvm/mechanics/changelog/md/grouped-table.tsi @@ -1,5 +1,5 @@ import { parse as parseMeta } from 'markdown-meta' -import { splitTag, fsEscape } from '@pvm/core/lib/tag-meta' +import { splitTag, fsEscape } from '@pvm/pvm' import TableBuilder, { TableBuilderOpts } from '../table-builder' import remark from '../remark' import groupReleases from '../group-releases' diff --git a/packages/pvm-changelog/lib/md/list-with-packages.ts b/packages/pvm/mechanics/changelog/md/list-with-packages.ts similarity index 93% rename from packages/pvm-changelog/lib/md/list-with-packages.ts rename to packages/pvm/mechanics/changelog/md/list-with-packages.ts index 70d7bcde7..123c16b80 100644 --- a/packages/pvm-changelog/lib/md/list-with-packages.ts +++ b/packages/pvm/mechanics/changelog/md/list-with-packages.ts @@ -1,7 +1,7 @@ import formatDate from 'date-fns/format' import indentHeadings from '../indent-headings' -import type { IncrementalRenderer } from '../../types' -import type { ReleaseData } from '@pvm/releases/types' +import type { IncrementalRenderer } from '../types' +import type { ReleaseData } from '../../releases/types' export interface ListWithPackagesOptions { date_format: string, @@ -35,7 +35,7 @@ class ListWithPackagesRenderer implements IncrementalRenderer { const createdAt = new Date(release.created_at) let heading - if ('pkgIdentity' in release) { + if (forPkg) { const pkg = release.packages.find(pkgData => pkgData.name === forPkg) if (!pkg) { return null diff --git a/packages/pvm-changelog/lib/md/list.md b/packages/pvm/mechanics/changelog/md/list.md similarity index 100% rename from packages/pvm-changelog/lib/md/list.md rename to packages/pvm/mechanics/changelog/md/list.md diff --git a/packages/pvm-changelog/lib/md/list.ts b/packages/pvm/mechanics/changelog/md/list.ts similarity index 94% rename from packages/pvm-changelog/lib/md/list.ts rename to packages/pvm/mechanics/changelog/md/list.ts index 5f3157f28..9d98790af 100644 --- a/packages/pvm-changelog/lib/md/list.ts +++ b/packages/pvm/mechanics/changelog/md/list.ts @@ -1,7 +1,7 @@ import formatDate from 'date-fns/format' import indentHeadings from '../indent-headings' -import type { IncrementalRenderer } from '../../types' -import type { ReleaseData } from '@pvm/releases/types' +import type { IncrementalRenderer } from '../types' +import type { ReleaseData } from '../../releases/types' export interface ListOptions { date_format: string, diff --git a/packages/pvm-changelog/lib/md/table.tsi b/packages/pvm/mechanics/changelog/md/table.tsi similarity index 95% rename from packages/pvm-changelog/lib/md/table.tsi rename to packages/pvm/mechanics/changelog/md/table.tsi index 1995c8e4c..41ff8a4e5 100644 --- a/packages/pvm-changelog/lib/md/table.tsi +++ b/packages/pvm/mechanics/changelog/md/table.tsi @@ -1,4 +1,4 @@ -import { splitTag } from '@pvm/core/lib/tag-meta' +import { splitTag } from '@pvm/pvm' import TableBuilder from '../table-builder' import remark from '../remark' import { ReleaseLike } from '../../types' diff --git a/packages/pvm/mechanics/changelog/providers.ts b/packages/pvm/mechanics/changelog/providers.ts new file mode 100644 index 000000000..40f86720d --- /dev/null +++ b/packages/pvm/mechanics/changelog/providers.ts @@ -0,0 +1,38 @@ +import { provide, createToken } from '../../lib/di' +import ListRenderer from './md/list' +import ListWithPackagesRenderer from './md/list-with-packages' +import type { IncrementalRenderer } from './types' +import { CHANGELOG_CUSTOM_RENDERER, CHANGELOG_RENDERERS_MAP } from '../../tokens' + +export const CHANGELOG_BUILTIN_LIST_RENDERER = createToken('CHANGELOG_RENDERER') +export const CHANGELOG_BUILTIN_LIST_WITH_PACKAGES_RENDERER = createToken('CHANGELOG_BUILTIN_LIST_WITH_PACKAGES_RENDERER') + +export default [ + provide({ + provide: CHANGELOG_BUILTIN_LIST_RENDERER, + useClass: ListRenderer, + }), + provide({ + provide: CHANGELOG_BUILTIN_LIST_WITH_PACKAGES_RENDERER, + useClass: ListWithPackagesRenderer, + }), + provide({ + provide: CHANGELOG_RENDERERS_MAP, + useFactory({ + listRenderer, + listWithPackagesRenderer, + customRenderer, + }) { + return { + 'builtin.list': listRenderer, + 'builtin.list-with-packages': listWithPackagesRenderer, + 'custom': customRenderer, + } + }, + deps: { + listRenderer: CHANGELOG_BUILTIN_LIST_RENDERER, + listWithPackagesRenderer: CHANGELOG_BUILTIN_LIST_WITH_PACKAGES_RENDERER, + customRenderer: { token: CHANGELOG_CUSTOM_RENDERER, optional: true }, + }, + }), +] diff --git a/packages/pvm-changelog/lib/remark.ts b/packages/pvm/mechanics/changelog/remark.ts similarity index 96% rename from packages/pvm-changelog/lib/remark.ts rename to packages/pvm/mechanics/changelog/remark.ts index f50343cf8..4e23e9c93 100644 --- a/packages/pvm-changelog/lib/remark.ts +++ b/packages/pvm/mechanics/changelog/remark.ts @@ -1,4 +1,6 @@ +// @ts-ignore import { Remarkable } from 'remarkable' +// @ts-ignore import { linkify } from 'remarkable/linkify' const remark = new Remarkable({ diff --git a/packages/pvm-changelog/lib/rules.ts b/packages/pvm/mechanics/changelog/rules.ts similarity index 73% rename from packages/pvm-changelog/lib/rules.ts rename to packages/pvm/mechanics/changelog/rules.ts index 210e9182a..b9ed66682 100644 --- a/packages/pvm-changelog/lib/rules.ts +++ b/packages/pvm/mechanics/changelog/rules.ts @@ -1,8 +1,8 @@ import path from 'path' -import { fsEscape } from '@pvm/core/lib/tag-meta' +import { fsEscape } from '../../lib/tag-meta' -import type { Pkg } from '@pvm/core/lib/pkg' -import type { Config } from '@pvm/core/lib/config' +import type { Pkg } from '../../lib/pkg' +import type { Config } from '../../types' export function pkgChangelogPath(config: Config, pkg: Pkg): string { const conf = config.changelog diff --git a/packages/pvm-changelog/lib/table-builder.ts b/packages/pvm/mechanics/changelog/table-builder.ts similarity index 98% rename from packages/pvm-changelog/lib/table-builder.ts rename to packages/pvm/mechanics/changelog/table-builder.ts index eaf48ac5b..1c93cddfa 100644 --- a/packages/pvm-changelog/lib/table-builder.ts +++ b/packages/pvm/mechanics/changelog/table-builder.ts @@ -1,4 +1,4 @@ -import now from '@pvm/core/lib/now' +import now from '../../lib/now' export interface TableBuilderOpts { locale: string, diff --git a/packages/pvm-changelog/types/index.ts b/packages/pvm/mechanics/changelog/types/index.ts similarity index 80% rename from packages/pvm-changelog/types/index.ts rename to packages/pvm/mechanics/changelog/types/index.ts index e6d25291e..0876f98e3 100644 --- a/packages/pvm-changelog/types/index.ts +++ b/packages/pvm/mechanics/changelog/types/index.ts @@ -1,4 +1,4 @@ -import type { ReleaseData } from '@pvm/releases/types' +import type { ReleaseData } from '../../releases/types' export interface Renderer { render(releases: Iterable, forPkg?: string): string, diff --git a/packages/pvm-files/lib/files.ts b/packages/pvm/mechanics/files/files.ts similarity index 62% rename from packages/pvm-files/lib/files.ts rename to packages/pvm/mechanics/files/files.ts index 14b2de4e1..bb6dbb253 100644 --- a/packages/pvm-files/lib/files.ts +++ b/packages/pvm/mechanics/files/files.ts @@ -1,19 +1,20 @@ -import { pkgset } from '@pvm/pkgset' +import { pkgset } from '../pkgset/pkgset' import glob from 'fast-glob' -import drainItems from '@pvm/core/lib/iter/drain-items' -import type { Pkg } from '@pvm/core/lib/pkg' -import { getWorkspacesSync } from '@pvm/core/lib/workspaces' -import isRootChanged from '@pvm/pkgset/lib/is-root-changed' +import drainItems from '../../lib/iter/drain-items' +import type { Pkg } from '../../lib/pkg' +import { getWorkspacesSync } from '../../lib/workspaces' +import isRootChanged from '../pkgset/is-root-changed' import path from 'path' +import type { Container } from '../../lib/di' function normalizePath(p: string): string { return p.replace(/\\/g, '/') } -export default async function getFiles(filesGlob: string | string[], opts: Record): Promise { +export default async function getFiles(di: Container, filesGlob: string | string[], opts: Record): Promise { const { cwd = process.cwd(), absolute, strategy, ...rest } = opts const workspaces = getWorkspacesSync(cwd).sort() - const pkgs = await drainItems(pkgset(strategy, { cwd, ...rest })) + const pkgs = await drainItems(pkgset(di, strategy, { cwd, ...rest })) const pkgsWithoutRoot = pkgs.filter(pkg => pkg.path !== '.') const rootIsTouched = pkgsWithoutRoot.length !== pkgs.length const files = glob.sync(filesGlob, { diff --git a/packages/pvm-notifications/lib/abstract-messenger-client.ts b/packages/pvm/mechanics/notifications/abstract-messenger-client.ts similarity index 87% rename from packages/pvm-notifications/lib/abstract-messenger-client.ts rename to packages/pvm/mechanics/notifications/abstract-messenger-client.ts index 1c504420f..4c9334026 100644 --- a/packages/pvm-notifications/lib/abstract-messenger-client.ts +++ b/packages/pvm/mechanics/notifications/abstract-messenger-client.ts @@ -1,7 +1,7 @@ -import type { Config } from '@pvm/core/lib/config' -import type { Message, MessengerClientConfig } from '@pvm/types' +import type { Config, Message, MessengerClientConfig } from '../../types' + import { logger } from './logger' -import defaultsDeep from 'lodash.defaultsdeep' +import defaultsDeep from 'lodash/defaultsDeep' export abstract class AbstractMessengerClient { // eslint-disable-next-line no-useless-constructor diff --git a/packages/pvm-notifications/lib/index.ts b/packages/pvm/mechanics/notifications/index.ts similarity index 100% rename from packages/pvm-notifications/lib/index.ts rename to packages/pvm/mechanics/notifications/index.ts diff --git a/packages/pvm-notifications/lib/logger.ts b/packages/pvm/mechanics/notifications/logger.ts similarity index 50% rename from packages/pvm-notifications/lib/logger.ts rename to packages/pvm/mechanics/notifications/logger.ts index 391d5946f..b6b88ddfb 100644 --- a/packages/pvm-notifications/lib/logger.ts +++ b/packages/pvm/mechanics/notifications/logger.ts @@ -1,3 +1,3 @@ -import { loggerFor } from '@pvm/core/lib/logger' +import { loggerFor } from '../../lib/logger' export const logger = loggerFor('pvm:messaging') diff --git a/packages/pvm-notifications/lib/messenger-clients.ts b/packages/pvm/mechanics/notifications/messenger-clients.ts similarity index 100% rename from packages/pvm-notifications/lib/messenger-clients.ts rename to packages/pvm/mechanics/notifications/messenger-clients.ts diff --git a/packages/pvm-notifications/lib/notificator.ts b/packages/pvm/mechanics/notifications/notificator.ts similarity index 60% rename from packages/pvm-notifications/lib/notificator.ts rename to packages/pvm/mechanics/notifications/notificator.ts index c76f5bf07..f71a446b5 100644 --- a/packages/pvm-notifications/lib/notificator.ts +++ b/packages/pvm/mechanics/notifications/notificator.ts @@ -1,48 +1,38 @@ import { MessengerClients } from './messenger-clients' import type { AbstractMessengerClient } from './abstract-messenger-client' -import type { Message, MessengerClientConfig } from '@pvm/types' -import type { Config } from '@pvm/core/lib/config' -import { getConfig } from '@pvm/core/lib/config' +import type { Message, MessengerClientConfig, Config } from '../../types' + import { logger } from './logger' import resolveFrom from 'resolve-from' -import { requireDefault } from '@pvm/core' -import defaultsDeep from 'lodash.defaultsdeep' -import { getHostApi } from '@pvm/core/lib/plugins' +import { requireDefault } from '../../lib/interop' +import defaultsDeep from 'lodash/defaultsDeep' export class Notificator { private messengers: MessengerClients private config: Config - constructor(config: Config) { + constructor({ config, messengerClients }: { config: Config, messengerClients: Array | null}) { this.config = config this.messengers = new MessengerClients() - this.config.notifications.clients.forEach(({ name, pkg }) => { - const Client = require(pkg).MessengerClient as { new(name: string, config: Config, clientConfig?: MessengerClientConfig): AbstractMessengerClient } - if (!Client) { - throw new Error(`Messenger client ${pkg} should have named export "MessengerClient"`) - } - this.messengers.register(name, new Client(name, config, Notificator.getClientConfig(name, config))) + messengerClients?.forEach(client => { + this.messengers.register(client.name, client) }) } - static getClientConfig(clientName: string, config: Config): MessengerClientConfig { + static createClient(Client: { new(name: string, config: Config, clientConfig?: MessengerClientConfig): AbstractMessengerClient }, config: Config, opts: MessengerClientConfig & { name?: string }): AbstractMessengerClient { const projectPkg = resolveFrom.silent(config.cwd, './package') const username = projectPkg ? `${requireDefault(projectPkg).name} minion` : void 0 - return defaultsDeep({}, config.notifications.client_configs[clientName], config.notifications.clients_common_config, { + const clientName = opts.name ?? Client.name + + return new Client(clientName, config, defaultsDeep({}, config.notifications.client_configs[clientName], opts, config.notifications.clients_common_config, { author: { name: username, }, - }) - } - - static async create(cwd: string = process.cwd()): Promise { - // initializing plugins - await getHostApi(cwd) - return new Notificator(await getConfig(cwd)) + })) } - async sendMessage(message: Message, opts: { target?: string } = {}): Promise { + async sendMessage(message: Message, opts: { target?: string | string[] } = {}): Promise { const target = opts.target ?? this.config.notifications.target const errors: Error[] = [] switch (target) { diff --git a/packages/pvm/mechanics/notifications/providers.ts b/packages/pvm/mechanics/notifications/providers.ts new file mode 100644 index 000000000..01e4c4bf2 --- /dev/null +++ b/packages/pvm/mechanics/notifications/providers.ts @@ -0,0 +1,17 @@ +import { provide } from '../../lib/di' +import { CONFIG_TOKEN, MESSENGER_CLIENT_TOKEN, NOTIFICATOR_TOKEN } from '../../tokens' +import { Notificator } from './notificator' + +export default [ + provide({ + provide: NOTIFICATOR_TOKEN, + useClass: Notificator, + deps: { + config: CONFIG_TOKEN, + messengerClients: { + token: MESSENGER_CLIENT_TOKEN, + optional: true, + }, + }, + }), +] diff --git a/packages/pvm/mechanics/packages/index.ts b/packages/pvm/mechanics/packages/index.ts new file mode 100644 index 000000000..e39ceff46 --- /dev/null +++ b/packages/pvm/mechanics/packages/index.ts @@ -0,0 +1,72 @@ +import pkgsetChanged from '../pkgset/strategies/changed' +import pkgsetAffected from '../pkgset/strategies/affected' +import pkgsetSinceRelease from '../pkgset/strategies/changed-since-release' +import pkgsetReleased from '../pkgset/strategies/released' +import drainItems from '../../lib/iter/drain-items' +import { getUpdateState } from '../update' +import { matchAny } from '../../lib/pkg-match' +import fromGlobPatterns from '../pkgset/from-glob-patterns' +import type { Pkg } from '../../lib/pkg' +import { concatPackages } from '../../lib/pkg' +import { Repository } from '../repository' +import type { Container } from '../../lib/di' + +// connected with type yargs.commands['pvm-publish].options.list.choices in ../cli/commands/pvm-packages.ts +export type PackagesType = 'about-to-update' | 'update' | 'changed' | 'changed-since-release' | 'affected' | 'released' | 'updated' | 'all' + +interface GetPackagesOptions { + filter?: string[], + ignoreDangerouslyOpts?: boolean, + cwd?: string, +} + +export async function getPackages(di: Container, type: PackagesType = 'all', opts: GetPackagesOptions = {}): Promise { + let packages + const { ignoreDangerouslyOpts = false, cwd = process.cwd() } = opts + const repo = await Repository.init(di) + + let always_changed_workspaces: string[] = [] + let extraPackages: Iterable = [] + if (!ignoreDangerouslyOpts) { + const config = repo.config + always_changed_workspaces = config.dangerously_opts?.always_changed_workspaces || [] + + if (always_changed_workspaces.length) { + extraPackages = fromGlobPatterns(config, always_changed_workspaces, void 0) + } + } + + switch (type) { + case 'about-to-update': + case 'update': + // getUpdateState сам подключает always_changed_workspaces + packages = Array.from((await getUpdateState(di, { readonly: true, cwd })).getReleasePackages().keys()) + break + case 'changed': + packages = await drainItems(pkgsetChanged(di, { includeUncommited: true, cwd })) + packages = concatPackages(packages, extraPackages) + break + case 'affected': + packages = await drainItems(pkgsetAffected(di, { includeUncommited: true, cwd })) + break + case 'changed-since-release': + packages = await drainItems(pkgsetSinceRelease(di, { cwd })) + packages = concatPackages(packages, extraPackages) + break + case 'released': + case 'updated': + packages = await drainItems(pkgsetReleased(di, { cwd })) + break + default: + // 'all' + packages = [...repo.packagesList] + break + } + + const { filter } = opts + if (filter && filter.length) { + packages = packages.filter(pkg => matchAny(pkg, filter)) + } + + return packages +} diff --git a/packages/pvm-pkgset/lib/changed-files.ts b/packages/pvm/mechanics/pkgset/changed-files.ts similarity index 87% rename from packages/pvm-pkgset/lib/changed-files.ts rename to packages/pvm/mechanics/pkgset/changed-files.ts index 9d9c74be1..56d26e6f3 100644 --- a/packages/pvm-pkgset/lib/changed-files.ts +++ b/packages/pvm/mechanics/pkgset/changed-files.ts @@ -1,7 +1,7 @@ -import { wdShell } from '@pvm/core/lib/shell' -import namedDiff from '@pvm/core/lib/git/named-diff' -import type { DiffStats } from '@pvm/types' -import { mergeBase } from '@pvm/core/lib/git/merge-base' +import { wdShell } from '../../lib/shell' +import namedDiff from '../../lib/git/named-diff' +import type { DiffStats } from '../../types' +import { mergeBase } from '../../lib/git/merge-base' export interface ChangedFilesOpts { from?: string, diff --git a/packages/pvm-pkgset/lib/filter-packages.ts b/packages/pvm/mechanics/pkgset/filter-packages.ts similarity index 95% rename from packages/pvm-pkgset/lib/filter-packages.ts rename to packages/pvm/mechanics/pkgset/filter-packages.ts index 3b6613ca0..8ba7afbf1 100644 --- a/packages/pvm-pkgset/lib/filter-packages.ts +++ b/packages/pvm/mechanics/pkgset/filter-packages.ts @@ -1,4 +1,4 @@ -import type { Config } from '@pvm/core/lib/config' +import type { Config } from '../../types' import binarySearch from './utils/binary-search' import { exclude } from './smart-paths' import isRootChanged from './is-root-changed' diff --git a/packages/pvm-pkgset/lib/from-changed-files.ts b/packages/pvm/mechanics/pkgset/from-changed-files.ts similarity index 77% rename from packages/pvm-pkgset/lib/from-changed-files.ts rename to packages/pvm/mechanics/pkgset/from-changed-files.ts index c07321660..bff07e65a 100644 --- a/packages/pvm-pkgset/lib/from-changed-files.ts +++ b/packages/pvm/mechanics/pkgset/from-changed-files.ts @@ -1,11 +1,11 @@ -import type { IncludeRootOption } from '../types' +import type { IncludeRootOption } from './types' import filterPackages from './filter-packages' import includeRootResolve from './include-root-resolve' -import type { Pkg } from '@pvm/core/lib/pkg' -import { loadPkg } from '@pvm/core/lib/pkg' -import { getWorkspacesFromRef, getWorkspacesSync } from '@pvm/core/lib/workspaces' +import type { Pkg } from '../../lib/pkg' +import { loadPkg } from '../../lib/pkg' +import { getWorkspacesFromRef, getWorkspacesSync } from '../../lib/workspaces' import type { ChangedFiles } from './changed-files' -import type { Config } from '@pvm/core/lib/config/types' +import type { Config } from '../../types' export interface FromChangedFilesOpts { includeRoot?: IncludeRootOption, diff --git a/packages/pvm-pkgset/lib/from-glob-patterns.ts b/packages/pvm/mechanics/pkgset/from-glob-patterns.ts similarity index 66% rename from packages/pvm-pkgset/lib/from-glob-patterns.ts rename to packages/pvm/mechanics/pkgset/from-glob-patterns.ts index 7a8b109ec..6c5c6e68a 100644 --- a/packages/pvm-pkgset/lib/from-glob-patterns.ts +++ b/packages/pvm/mechanics/pkgset/from-glob-patterns.ts @@ -1,8 +1,8 @@ import micromatch from 'micromatch' -import { getWorkspacesSync, getWorkspacesFromRef } from '@pvm/core/lib/workspaces' -import type { Pkg } from '@pvm/core/lib/pkg' -import { loadPkg } from '@pvm/core/lib/pkg' -import type { Config } from '@pvm/core/lib/config' +import { getWorkspacesSync, getWorkspacesFromRef } from '../../lib/workspaces' +import type { Pkg } from '../../lib/pkg' +import { loadPkg } from '../../lib/pkg' +import type { Config } from '../../types' function * fromGlobPatterns(config: Config, patterns: string[], ref: string | undefined): IterableIterator { const { cwd } = config diff --git a/packages/pvm-pkgset/lib/include-root-resolve.ts b/packages/pvm/mechanics/pkgset/include-root-resolve.ts similarity index 71% rename from packages/pvm-pkgset/lib/include-root-resolve.ts rename to packages/pvm/mechanics/pkgset/include-root-resolve.ts index 0a665db02..4b5b259f1 100644 --- a/packages/pvm-pkgset/lib/include-root-resolve.ts +++ b/packages/pvm/mechanics/pkgset/include-root-resolve.ts @@ -1,7 +1,7 @@ -import type { IncludeRootOption } from '../types' -import { loadPkg } from '@pvm/core/lib/pkg' -import type { Config } from '@pvm/core/lib/config' -import { logger } from '@pvm/core/lib/logger' +import type { IncludeRootOption } from './types' +import { loadPkg } from '../../lib/pkg' +import type { Config } from '../../types' +import { logger } from '../../lib/logger' import chalk from 'chalk' function includeRootResolve(includeRoot: IncludeRootOption, config: Config, ref?: string): boolean { diff --git a/packages/pvm-pkgset/lib/is-root-changed.ts b/packages/pvm/mechanics/pkgset/is-root-changed.ts similarity index 100% rename from packages/pvm-pkgset/lib/is-root-changed.ts rename to packages/pvm/mechanics/pkgset/is-root-changed.ts diff --git a/packages/pvm-pkgset/lib/pkgset-all.ts b/packages/pvm/mechanics/pkgset/pkgset-all.ts similarity index 74% rename from packages/pvm-pkgset/lib/pkgset-all.ts rename to packages/pvm/mechanics/pkgset/pkgset-all.ts index 27e8973d9..18ed00d9d 100644 --- a/packages/pvm-pkgset/lib/pkgset-all.ts +++ b/packages/pvm/mechanics/pkgset/pkgset-all.ts @@ -1,9 +1,9 @@ -import { getWorkspacesSync, getWorkspacesFromRef } from '@pvm/core/lib/workspaces' -import type { Pkg } from '@pvm/core/lib/pkg' -import { loadPkg } from '@pvm/core/lib/pkg' -import type { IncludeRootOption } from '../types' +import { getWorkspacesSync, getWorkspacesFromRef } from '../../lib/workspaces' +import type { Pkg } from '../../lib/pkg' +import { loadPkg } from '../../lib/pkg' +import type { IncludeRootOption } from './types' import includeRootResolve from './include-root-resolve' -import type { Config } from '@pvm/core/lib/config' +import type { Config } from '../../types' export interface PkgsetAllOpts { includeRoot?: IncludeRootOption, diff --git a/packages/pvm-pkgset/lib/pkgset-from-ref.ts b/packages/pvm/mechanics/pkgset/pkgset-from-ref.ts similarity index 65% rename from packages/pvm-pkgset/lib/pkgset-from-ref.ts rename to packages/pvm/mechanics/pkgset/pkgset-from-ref.ts index 4907073ca..8cbc02444 100644 --- a/packages/pvm-pkgset/lib/pkgset-from-ref.ts +++ b/packages/pvm/mechanics/pkgset/pkgset-from-ref.ts @@ -1,8 +1,8 @@ import { pkgsetAll } from './pkgset-all' -import type { IncludeRootOption } from '../types' -import type { Pkg } from '@pvm/core/lib/pkg' -import type { Config } from '@pvm/core/lib/config/types' +import type { IncludeRootOption } from './types' +import type { Pkg } from '../../lib/pkg' +import type { Config } from '../../types' export interface PkgsetFromRefOpts { includeRoot?: IncludeRootOption, diff --git a/packages/pvm/mechanics/pkgset/pkgset.ts b/packages/pvm/mechanics/pkgset/pkgset.ts new file mode 100644 index 000000000..42d3cda10 --- /dev/null +++ b/packages/pvm/mechanics/pkgset/pkgset.ts @@ -0,0 +1,25 @@ +import strategies from './strategies/index' +import type { Pkg } from '../../lib/pkg' +import { parseSubArgs } from '../../lib/text/sub-args' +import type { Container } from '../../lib/di' + +function pkgset(di: Container, strategy: string, opts: Record = {}): AsyncIterable { + const strategyFn = strategies[strategy] + if (typeof strategyFn !== 'function') { + throw new Error(`no such strategy ${strategy}`) + } + + return strategyFn(di, opts) +} + +async function * pkgsetFromFlags(di: Container, flags: { + strategy: string, + strategyOption?: string[], +}): AsyncIterableIterator { + yield * pkgset(di, flags.strategy, parseSubArgs(flags.strategyOption)) +} + +export { + pkgset, + pkgsetFromFlags, +} diff --git a/packages/pvm-pkgset/lib/pprint.ts b/packages/pvm/mechanics/pkgset/pprint.ts similarity index 80% rename from packages/pvm-pkgset/lib/pprint.ts rename to packages/pvm/mechanics/pkgset/pprint.ts index 125291676..c76ec6ccb 100644 --- a/packages/pvm-pkgset/lib/pprint.ts +++ b/packages/pvm/mechanics/pkgset/pprint.ts @@ -1,8 +1,8 @@ -import type { Pkg } from '@pvm/core/lib/pkg' +import type { Pkg } from '../../lib/pkg' async function * pprint(pkgIterator: AsyncIterable, format = '%p'): AsyncIterableIterator { for await (const pkg of pkgIterator) { - const data = { + const data: Record = { p: pkg.path, n: pkg.name, s: pkg.shortName, diff --git a/packages/pvm-pkgset/lib/smart-paths.ts b/packages/pvm/mechanics/pkgset/smart-paths.ts similarity index 100% rename from packages/pvm-pkgset/lib/smart-paths.ts rename to packages/pvm/mechanics/pkgset/smart-paths.ts diff --git a/packages/pvm-pkgset/lib/strategies/affected.ts b/packages/pvm/mechanics/pkgset/strategies/affected.ts similarity index 86% rename from packages/pvm-pkgset/lib/strategies/affected.ts rename to packages/pvm/mechanics/pkgset/strategies/affected.ts index b86db05bf..79466b017 100644 --- a/packages/pvm-pkgset/lib/strategies/affected.ts +++ b/packages/pvm/mechanics/pkgset/strategies/affected.ts @@ -2,9 +2,8 @@ import chalk from 'chalk' import micromatch from 'micromatch' import glob from 'fast-glob' -import { getConfig } from '@pvm/core/lib/config' -import { Repository } from '@pvm/repository/lib' -import { PkgSet } from '@pvm/core/lib/pkg-set' +import { Repository } from '../../repository' +import { PkgSet } from '../../../lib/pkg-set' import { pkgsetAll } from '../pkgset-all' import type { ChangedFilesOpts } from '../changed-files' @@ -15,7 +14,9 @@ import { pkgsetFromChangedFiles } from '../from-changed-files' import fromGlobPatterns from '../from-glob-patterns' import { describeStrategy } from '../utils/describe-strategy' -import type { Pkg } from '@pvm/core/lib/pkg' +import type { Pkg } from '../../../lib/pkg' +import type { Container } from '../../../lib/di' +import { CONFIG_TOKEN } from '../../../tokens' export type PkgsetChangedOpts = ChangedFilesOpts & FromChangedFilesOpts & { ignoreDangerouslyOpts?: boolean, @@ -26,12 +27,12 @@ const globOpts = { ignore: ['**/node_modules/**'], } -async function * pkgset(opts: PkgsetChangedOpts = {}): AsyncIterableIterator { +async function * pkgset(di: Container, opts: PkgsetChangedOpts = {}): AsyncIterableIterator { const resultChanged = changedFiles(opts) let forceAllPackages = false const { ignoreDangerouslyOpts = false, cwd = process.cwd() } = opts - const config = await getConfig(cwd) - const repo = await Repository.init(cwd, { ref: resultChanged.targetLoadRef }) + const config = di.get(CONFIG_TOKEN) + const repo = await Repository.init(di, { ref: resultChanged.targetLoadRef }) const affectedConfig: { if_changed: string[], then_affected: string[] | '*' }[] = config.pkgset?.affected_files ?? [] const resultPatterns: Set = new Set() diff --git a/packages/pvm-pkgset/lib/strategies/all.ts b/packages/pvm/mechanics/pkgset/strategies/all.ts similarity index 59% rename from packages/pvm-pkgset/lib/strategies/all.ts rename to packages/pvm/mechanics/pkgset/strategies/all.ts index ce7234d2c..9feae41ca 100644 --- a/packages/pvm-pkgset/lib/strategies/all.ts +++ b/packages/pvm/mechanics/pkgset/strategies/all.ts @@ -1,16 +1,17 @@ -import { getConfig } from '@pvm/core/lib/config' import { describeStrategy } from '../utils/describe-strategy' import { pkgsetAll } from '../pkgset-all' import type { PkgsetAllOpts } from '../pkgset-all' -import type { Pkg } from '@pvm/core/lib/pkg' +import type { Pkg } from '../../../lib/pkg' +import type { Container } from '../../../lib/di' +import { CONFIG_TOKEN } from '../../../tokens' export interface PkgsetAsyncAllOpts extends PkgsetAllOpts { cwd?: string, } -async function * pkgset(opts: PkgsetAsyncAllOpts = {}): AsyncIterableIterator { +async function * pkgset(di: Container, opts: PkgsetAsyncAllOpts = {}): AsyncIterableIterator { const { cwd, ...restOpts } = opts - const config = await getConfig(cwd) + const config = di.get(CONFIG_TOKEN) yield * pkgsetAll(config, restOpts) } diff --git a/packages/pvm-pkgset/lib/strategies/changed-at.ts b/packages/pvm/mechanics/pkgset/strategies/changed-at.ts similarity index 56% rename from packages/pvm-pkgset/lib/strategies/changed-at.ts rename to packages/pvm/mechanics/pkgset/strategies/changed-at.ts index ede1a4874..b3a8f5f3b 100644 --- a/packages/pvm-pkgset/lib/strategies/changed-at.ts +++ b/packages/pvm/mechanics/pkgset/strategies/changed-at.ts @@ -1,15 +1,16 @@ import type { PkgsetChangedOpts } from './changed' import changed from './changed' -import type { Pkg } from '@pvm/core/lib/pkg' +import type { Pkg } from '../../../lib/pkg' +import type { Container } from '../../../lib/di' type PkgsetChangedAtOpts = PkgsetChangedOpts & Partial<{ ref: string, }> -function pkgset(opts: PkgsetChangedAtOpts = {}): AsyncIterableIterator { +function pkgset(di: Container, opts: PkgsetChangedAtOpts = {}): AsyncIterableIterator { const { ref = 'HEAD' } = opts - return changed({ + return changed(di, { ...opts, from: `${ref}^`, to: ref, diff --git a/packages/pvm-pkgset/lib/strategies/changed-since-release.ts b/packages/pvm/mechanics/pkgset/strategies/changed-since-release.ts similarity index 57% rename from packages/pvm-pkgset/lib/strategies/changed-since-release.ts rename to packages/pvm/mechanics/pkgset/strategies/changed-since-release.ts index 9f51ee5ac..74f0d4ea4 100644 --- a/packages/pvm-pkgset/lib/strategies/changed-since-release.ts +++ b/packages/pvm/mechanics/pkgset/strategies/changed-since-release.ts @@ -1,18 +1,19 @@ import type { PkgsetChangedOpts } from './changed' import changed from './changed' -import { lastReleaseTag } from '@pvm/core/lib/git/last-release-tag' -import { wdShell } from '@pvm/core/lib/shell' -import { log } from '@pvm/core/lib/logger' -import { getConfig } from '@pvm/core/lib/config' -import type { Pkg } from '@pvm/core/lib/pkg' +import { lastReleaseTag } from '../../../lib/git/last-release-tag' +import { wdShell } from '../../../lib/shell' +import { log } from '../../../lib/logger' +import type { Pkg } from '../../../lib/pkg' +import type { Container } from '../../../lib/di' +import { CONFIG_TOKEN } from '../../../tokens' type PkgsetChangedAtReleaseOpts = PkgsetChangedOpts & Partial<{ ref: string, }> -async function * pkgset(opts: PkgsetChangedAtReleaseOpts = {}): AsyncIterableIterator { +async function * pkgset(di: Container, opts: PkgsetChangedAtReleaseOpts = {}): AsyncIterableIterator { const { ref = 'HEAD', cwd = process.cwd() } = opts - const config = await getConfig(cwd) + const config = di.get(CONFIG_TOKEN) const revSha = wdShell(cwd, `git rev-parse ${ref}`) @@ -24,7 +25,7 @@ async function * pkgset(opts: PkgsetChangedAtReleaseOpts = {}): AsyncIterableIte fromRev = `${revSha}^` } - yield * changed({ + yield * changed(di, { ...opts, from: fromRev, to: ref, diff --git a/packages/pvm-pkgset/lib/strategies/changed.ts b/packages/pvm/mechanics/pkgset/strategies/changed.ts similarity index 72% rename from packages/pvm-pkgset/lib/strategies/changed.ts rename to packages/pvm/mechanics/pkgset/strategies/changed.ts index 0ae949726..c98f1ae63 100644 --- a/packages/pvm-pkgset/lib/strategies/changed.ts +++ b/packages/pvm/mechanics/pkgset/strategies/changed.ts @@ -2,16 +2,16 @@ import type { ChangedFilesOpts } from '../changed-files' import { changedFiles } from '../changed-files' import type { FromChangedFilesOpts } from '../from-changed-files' import { pkgsetFromChangedFiles } from '../from-changed-files' -import type { Pkg } from '@pvm/core/lib/pkg' +import type { Pkg } from '../../../lib/pkg' import { describeStrategy } from '../utils/describe-strategy' -import { getConfig } from '@pvm/core/lib/config' import chalk from 'chalk' +import type { Container } from '../../../lib/di' +import { CONFIG_TOKEN } from '../../../tokens' export type PkgsetChangedOpts = ChangedFilesOpts & FromChangedFilesOpts -async function * pkgset(opts: PkgsetChangedOpts = {}): AsyncIterableIterator { - const config = await getConfig(opts.cwd) - yield * pkgsetFromChangedFiles(config, changedFiles(opts), opts) +async function * pkgset(di: Container, opts: PkgsetChangedOpts = {}): AsyncIterableIterator { + yield * pkgsetFromChangedFiles(di.get(CONFIG_TOKEN), changedFiles(opts), opts) } describeStrategy(pkgset, 'changed', chalk`Prints packages which have been changed between two revisions. diff --git a/packages/pvm-pkgset/lib/strategies/index.ts b/packages/pvm/mechanics/pkgset/strategies/index.ts similarity index 71% rename from packages/pvm-pkgset/lib/strategies/index.ts rename to packages/pvm/mechanics/pkgset/strategies/index.ts index 80bb90a5c..99a2f6ff3 100644 --- a/packages/pvm-pkgset/lib/strategies/index.ts +++ b/packages/pvm/mechanics/pkgset/strategies/index.ts @@ -1,3 +1,4 @@ +import type { PkgsetChangedOpts } from './changed' import changed from './changed' import stdin from './stdin' import stale from './stale' @@ -6,8 +7,10 @@ import changedAt from './changed-at' import changedSinceRelease from './changed-since-release' import released from './released' import affected from './affected' +import type { Container } from '../../../lib/di' +import type { Pkg } from '../../../lib/pkg' -const strategies = { +const strategies: Record AsyncIterableIterator> = { changed, stdin, stale, diff --git a/packages/pvm-pkgset/lib/strategies/released.ts b/packages/pvm/mechanics/pkgset/strategies/released.ts similarity index 76% rename from packages/pvm-pkgset/lib/strategies/released.ts rename to packages/pvm/mechanics/pkgset/strategies/released.ts index 117dde7ba..cdb132998 100644 --- a/packages/pvm-pkgset/lib/strategies/released.ts +++ b/packages/pvm/mechanics/pkgset/strategies/released.ts @@ -1,11 +1,12 @@ -import { lastReleaseTag as getLastReleaseTag } from '@pvm/core/lib/git/last-release-tag' -import { wdShell } from '@pvm/core/lib/shell' +import { lastReleaseTag as getLastReleaseTag } from '../../../lib/git/last-release-tag' +import { wdShell } from '../../../lib/shell' import { pkgsetFromRef } from '../pkgset-from-ref' -import { loggerFor } from '@pvm/core/lib/logger' -import type { Pkg } from '@pvm/core/lib/pkg' -import { getConfig } from '@pvm/core/lib/config' +import { loggerFor } from '../../../lib/logger' +import type { Pkg } from '../../../lib/pkg' import { describeStrategy } from '../utils/describe-strategy' -import { ImmutablePkgSet } from '@pvm/core/lib/pkg-set' +import { ImmutablePkgSet } from '../../../lib/pkg-set' +import type { Container } from '../../../lib/di' +import { CONFIG_TOKEN, CWD_TOKEN } from '../../../tokens' const logger = loggerFor('pvm:pkgset-released') export interface PkgsetReleasedOpts { @@ -13,9 +14,9 @@ export interface PkgsetReleasedOpts { cwd?: string, } -async function * pkgsetReleased(opts: PkgsetReleasedOpts = {}): AsyncIterableIterator { - const { ref = 'HEAD', cwd = process.cwd() } = opts - const config = await getConfig(cwd) +async function * pkgsetReleased(di: Container, opts: PkgsetReleasedOpts = {}): AsyncIterableIterator { + const { ref = 'HEAD', cwd = di.get(CWD_TOKEN) } = opts + const config = di.get(CONFIG_TOKEN) const lastReleaseTag = getLastReleaseTag(config, ref) if (!lastReleaseTag) { diff --git a/packages/pvm-pkgset/lib/strategies/stale.ts b/packages/pvm/mechanics/pkgset/strategies/stale.ts similarity index 78% rename from packages/pvm-pkgset/lib/strategies/stale.ts rename to packages/pvm/mechanics/pkgset/strategies/stale.ts index b83ec1d17..539df7b10 100644 --- a/packages/pvm-pkgset/lib/strategies/stale.ts +++ b/packages/pvm/mechanics/pkgset/strategies/stale.ts @@ -1,22 +1,23 @@ import chalk from 'chalk' import semver from 'semver' -import { logger } from '@pvm/core/lib/logger' -import { getWorkspacesSync } from '@pvm/core/lib/workspaces' -import type { Pkg } from '@pvm/core/lib/pkg' -import { loadPkg } from '@pvm/core/lib/pkg' -import { getConfig } from '@pvm/core/lib/config' -import { wdShell } from '@pvm/core/lib/shell' +import { logger } from '../../../lib/logger' +import { getWorkspacesSync } from '../../../lib/workspaces' +import type { Pkg } from '../../../lib/pkg' +import { loadPkg } from '../../../lib/pkg' +import { wdShell } from '../../../lib/shell' +import type { Container } from '../../../lib/di' import { describeStrategy } from '../utils/describe-strategy' +import { CONFIG_TOKEN } from '../../../tokens' export type PkgsetStaleOpts = Partial<{ cwd: string, registry: string, }> -async function * pkgset(opts: PkgsetStaleOpts = {}): AsyncIterableIterator { +async function * pkgset(di: Container, opts: PkgsetStaleOpts = {}): AsyncIterableIterator { const pkgPaths = getWorkspacesSync(opts.cwd) - const config = await getConfig(opts.cwd) + const config = di.get(CONFIG_TOKEN) for (const pkgPath of pkgPaths) { const pkg = loadPkg(config, pkgPath)! @@ -28,7 +29,7 @@ async function * pkgset(opts: PkgsetStaleOpts = {}): AsyncIterableIterator // @TODO сделать параллельные запросы в нпм (ускорить) logger.info(`retrieving published version for ${pkg.name} from ${registry || 'default'} registry..`) response = wdShell(config.cwd, `npm view ${pkg.name} version ${registry ? `--registry ${registry}` : ''}`, { stdio: 'pipe' }) - } catch (e) { + } catch (e: any) { // According https://github.com/npm/cli/issues/3075 there is a flag --json behaviour change that defeats its purpose // and making output unparsable as json if (e.toString().indexOf(' E404') === -1) { diff --git a/packages/pvm-pkgset/lib/strategies/stdin.ts b/packages/pvm/mechanics/pkgset/strategies/stdin.ts similarity index 59% rename from packages/pvm-pkgset/lib/strategies/stdin.ts rename to packages/pvm/mechanics/pkgset/strategies/stdin.ts index d181a6e1b..10b2d1d10 100644 --- a/packages/pvm-pkgset/lib/strategies/stdin.ts +++ b/packages/pvm/mechanics/pkgset/strategies/stdin.ts @@ -1,19 +1,20 @@ -import { getWorkspacesSync } from '@pvm/core/lib/workspaces' -import { loadPkg } from '@pvm/core/lib/pkg' -import { getConfig } from '@pvm/core/lib/config' +import { getWorkspacesSync } from '../../../lib/workspaces' +import { loadPkg } from '../../../lib/pkg' import binarySearch from '../utils/binary-search' -import readLines from '@pvm/core/lib/read-lines' -import drainIterator from '@pvm/core/lib/iter/drain-items' +import readLines from '../../../lib/read-lines' +import drainIterator from '../../../lib/iter/drain-items' import { describeStrategy } from '../utils/describe-strategy' +import type { Container } from '../../../lib/di' +import { CONFIG_TOKEN } from '../../../tokens' export type PkgsetStdinOpts = Partial<{ cwd: string, }> -async function * pkgset(opts: PkgsetStdinOpts = {}) { +async function * pkgset(di: Container, opts: PkgsetStdinOpts = {}) { const packagesNames = (await drainIterator(readLines())).sort() const pkgPaths = getWorkspacesSync(opts.cwd) - const config = await getConfig(opts.cwd) + const config = di.get(CONFIG_TOKEN) for (const pkgPath of pkgPaths) { const pkg = loadPkg(config, pkgPath)! diff --git a/packages/pvm-pkgset/types/index.ts b/packages/pvm/mechanics/pkgset/types/index.ts similarity index 100% rename from packages/pvm-pkgset/types/index.ts rename to packages/pvm/mechanics/pkgset/types/index.ts diff --git a/packages/pvm-pkgset/lib/utils/binary-search.ts b/packages/pvm/mechanics/pkgset/utils/binary-search.ts similarity index 100% rename from packages/pvm-pkgset/lib/utils/binary-search.ts rename to packages/pvm/mechanics/pkgset/utils/binary-search.ts diff --git a/packages/pvm-pkgset/lib/utils/describe-strategy.ts b/packages/pvm/mechanics/pkgset/utils/describe-strategy.ts similarity index 52% rename from packages/pvm-pkgset/lib/utils/describe-strategy.ts rename to packages/pvm/mechanics/pkgset/utils/describe-strategy.ts index 70d698c1d..5576439de 100644 --- a/packages/pvm-pkgset/lib/utils/describe-strategy.ts +++ b/packages/pvm/mechanics/pkgset/utils/describe-strategy.ts @@ -1,6 +1,6 @@ import chalk from 'chalk' -export function describeStrategy(strategyFn, display, description): void { +export function describeStrategy(strategyFn: any, display: string, description: string): void { strategyFn.description = chalk`{whiteBright ${display}} ${description}` } diff --git a/packages/pvm/mechanics/platform/decorated-platform.ts b/packages/pvm/mechanics/platform/decorated-platform.ts new file mode 100644 index 000000000..7241b31bc --- /dev/null +++ b/packages/pvm/mechanics/platform/decorated-platform.ts @@ -0,0 +1,220 @@ +import { PlatformInterface } from './platform-interface' +import type { + AddTagOptions, + CommitOptions, + CommitResult, CreateReleasePayload, + GetReleaseResult, MetaComment, + PlatformReleaseTag, + ReleasePayload, + VcsRelease, + AbstractVcs, HostApi, +} from '../../types' +import type { GlobalFlags } from '../../lib/cli/global-flags' +import { logDryRun } from '../../lib/utils' + +export class DecoratedPlatform extends PlatformInterface { + protected platform: PlatformInterface + protected vcs: AbstractVcs + protected cwd: string + protected hostApi: HostApi + + constructor({ platform, globalFlags, vcs, cwd, hostApi }: { platform: PlatformInterface, globalFlags: GlobalFlags, vcs: AbstractVcs, cwd: string, hostApi: HostApi }) { + super({ name: platform.name, globalFlags }) + this.platform = platform + this.vcs = vcs + this.cwd = cwd + this.hostApi = hostApi + this.name = this.platform.name + } + + @logDryRun + async addTag(tag_name: string, ref: string, opts: AddTagOptions | undefined): Promise { + if (!this.dryRun && !this.localMode) { + return this.platform.addTag(tag_name, ref, opts) + } + } + + @logDryRun + addTagAndRelease(ref: string, tag_name: string, data: CreateReleasePayload): Promise { + if (this.dryRun) { + return Promise.resolve() + } + + if (!this.localMode) { + return this.platform.addTagAndRelease(ref, tag_name, data) + } else { + return this.vcs.addTag(tag_name, ref, { + annotation: data.annotation, + }) + } + } + + async beginMrAttribution(): Promise { + if (!this.localMode) { + await this.platform.beginMrAttribution() + } + } + + @logDryRun + async createMrNote(body: string): Promise { + if (!this.dryRun && !this.localMode) { + return this.platform.createMrNote(body) + } + } + + @logDryRun + async createProjectLabel(label: string, color: string): Promise { + if (!this.dryRun && !this.localMode) { + return this.platform.createProjectLabel(label, color) + } + } + + @logDryRun + async createRelease(tagName: string, payload: CreateReleasePayload): Promise { + if (!this.dryRun && !this.localMode) { + return this.platform.createRelease(tagName, payload) + } + } + + @logDryRun + async editRelease(tag_name: string, data: ReleasePayload): Promise { + if (!this.dryRun && !this.localMode) { + return this.platform.editRelease(tag_name, data) + } + } + + @logDryRun + async ensureMrLabels(labels: string[]): Promise { + if (!this.dryRun && !this.localMode) { + return this.platform.ensureMrLabels(labels) + } + } + + fetchLatestSha(refName: string): Promise { + return this.platform.fetchLatestSha(refName) + } + + findMrNote(kind: string): Promise | void> { + return this.platform.findMrNote(kind) + } + + getCommitLink(commit: string): Promise { + return this.platform.getCommitLink(commit) + } + + getCommitSha(): string { + return this.platform.getCommitSha() + } + + getCurrentBranch(): string | undefined { + return this.platform.getCurrentBranch() + } + + getProjectLabels(): AsyncIterable<{ name: string }> { + return this.platform.getProjectLabels() + } + + getRelease(tagName: string): Promise { + return this.platform.getRelease(tagName) + } + + getUpdateHintsByCommit(commit: string): Promise | null> { + return this.platform.getUpdateHintsByCommit(commit) + } + + releaseTagsIterator(): AsyncGenerator { + return this.platform.releaseTagsIterator() + } + + releasesIterator(): AsyncGenerator { + return this.platform.releasesIterator() + } + + requireMr(): any { + return this.platform.requireMr() + } + + @logDryRun + async setMrLabels(labels: string[]): Promise { + if (!this.dryRun && !this.localMode) { + return this.platform.setMrLabels(labels) + } + } + + @logDryRun + async syncAttachment(kind: string, attachment: Buffer, opts: any): Promise { + if (!this.dryRun && !this.localMode) { + return this.platform.syncAttachment(kind, attachment, opts) + } + } + + @logDryRun + async syncText(kind: string, text: string): Promise { + if (!this.dryRun && !this.localMode) { + return this.platform.syncText(kind, text) + } + } + + @logDryRun + async updateMrNote(commentId: number | string, body: string): Promise { + if (!this.dryRun && !this.localMode) { + return this.platform.updateMrNote(commentId, body) + } + } + + @logDryRun + async upsertRelease(tag_name: string, data: ReleasePayload): Promise { + if (!this.dryRun && !this.localMode) { + return this.platform.upsertRelease(tag_name, data) + } + } + + @logDryRun + addFiles(commitContext: any, filePaths: string[]): void { + if (!this.dryRun && !this.localMode) { + return this.platform.addFiles(commitContext, filePaths) + } + } + + @logDryRun + appendFile(commitContext: any, filePath: string, content: string): void { + if (!this.dryRun && !this.localMode) { + return this.platform.appendFile(commitContext, filePath, content) + } + } + + beginCommit(): any { + if (!this.localMode) { + return this.platform.beginCommit() + } + } + + @logDryRun + commit(commitContext: any, message: string, opts?: CommitOptions): Promise { + if (this.dryRun || this.localMode) { + return Promise.resolve({ + id: this.vcs.getHeadRev(), + }) + } + + return this.platform.commit(commitContext, message, opts) + } + + @logDryRun + deleteFile(commitContext: any, file_path: string): void { + if (!this.dryRun && !this.localMode) { + return this.platform.deleteFile(commitContext, file_path) + } + } + + rollbackCommit(commitContext: any): Promise { + return this.platform.rollbackCommit(commitContext) + } + + @logDryRun + updateFile(commitContext: any, file_path: string, content: string): void { + if (!this.dryRun && !this.localMode) { + return this.platform.updateFile(commitContext, file_path, content) + } + } +} diff --git a/packages/pvm/mechanics/platform/index.ts b/packages/pvm/mechanics/platform/index.ts new file mode 100644 index 000000000..570546b5b --- /dev/null +++ b/packages/pvm/mechanics/platform/index.ts @@ -0,0 +1 @@ +export { PlatformInterface } from './platform-interface' diff --git a/packages/pvm/mechanics/platform/platform-interface.ts b/packages/pvm/mechanics/platform/platform-interface.ts new file mode 100644 index 000000000..0a3e43aa4 --- /dev/null +++ b/packages/pvm/mechanics/platform/platform-interface.ts @@ -0,0 +1,190 @@ +import stringToColor from 'string-to-color' +import { logger, log } from '../../lib/logger' +import type { + CommitOptions, CommitResult, + CreateReleasePayload, FileCommitApi, + GetReleaseResult, MetaComment, PlatformReleaseTag, + ReleasePayload, + VcsRelease, + AddTagOptions, HostApi, +} from '../../types' +import { getNoteBody } from '../vcs/utils' +import { logDryRun } from '../../lib/utils' +import { PlatformResult } from '../../lib/shared' +import getCommits from '../../lib/git/commits' +import type { GlobalFlags } from '../../lib/cli/global-flags' + +export abstract class PlatformInterface implements FileCommitApi { + name: string + protected globalFlags: GlobalFlags + + constructor({ name, globalFlags }: { name: string, globalFlags: GlobalFlags }) { + this.globalFlags = globalFlags + this.name = name + } + + get dryRun() { + return this.globalFlags.getFlag('dryRun') + } + + get localMode() { + return this.globalFlags.getFlag('localMode') + } + + protected abstract cwd: string + protected abstract hostApi: HostApi + abstract requireMr(): MergeRequest; + abstract getCommitLink(commit: string): Promise; + /** Создает и тег и релиз, если тег уже есть то выбрасывается исключение */ + abstract addTagAndRelease(ref: string, tag_name: string, data: CreateReleasePayload): Promise; + /** Создает релиз на существующем теге */ + abstract createRelease(tagName: string, payload: CreateReleasePayload): Promise; + /** Возвращает релиз, если есть, для существующего тега. Результат если тега нет или нет релиза отличается по коду ответа */ + abstract getRelease(tagName: string): Promise; + /** Редактирует существующий релиз, если нет релиза или тега будет ошибка */ + abstract editRelease(tag_name: string, data: ReleasePayload): Promise; + /** Редактирует или создает релиз, тег должен существовать */ + abstract upsertRelease(tag_name: string, data: ReleasePayload): Promise; + abstract releasesIterator(): AsyncGenerator; + abstract releaseTagsIterator(): AsyncGenerator; + abstract syncAttachment(kind: string, attachment: Buffer, opts: any): Promise; + abstract beginMrAttribution(): void; + // common with AbstractVcs + abstract fetchLatestSha(refName: string): Promise; + abstract getCurrentBranch(): string | undefined + abstract getCommitSha(): string + abstract addTag(tag_name: string, ref: string, opts?: AddTagOptions): Promise; + + abstract findMrNote(kind: string): Promise | void>; + + abstract createMrNote(body: string): Promise; + abstract updateMrNote(commentId: number | string, body: string): Promise; + + abstract getProjectLabels(): AsyncIterable<{ name: string }>; + abstract createProjectLabel(label: string, color: string): Promise; + abstract setMrLabels(labels: string[]): Promise; + + abstract getUpdateHintsByCommit(commit: string): Promise | null>; + + @logDryRun + async syncText(kind: string, text: string): Promise { + if (this.dryRun) { + return + } + + const existingNote = await this.findMrNote(kind) + + const noteBody = getNoteBody([['kind', kind], ['ref', this.getCommitSha()]], text) + + if (existingNote) { + return this.updateMrNote(existingNote.note.id, noteBody) + } else { + return this.createMrNote(noteBody) + } + } + + @logDryRun + async ensureMrLabels(labels: string[]): Promise { + if (this.dryRun) { + return + } + + const labelsByName = Object.create(null) + for await (const label of this.getProjectLabels()) { + labelsByName[label.name] = label + } + + const newLabels: string[] = [] + + for (const line of labels) { + if (line in labelsByName) { + continue + } + const color = stringToColor(line) + logger.debug(`creating label ${line}, color ${color}`) + + await this.createProjectLabel(line, color) + newLabels.push(line) + } + + if (newLabels.length !== 0) { + log(`Successfully created new labels: ${newLabels.join(', ')}`) + } + + return this.setMrLabels(labels) + } + + async prepareReleaseData(targetTag: string, prevRef: string): Promise { + log(`making release for ${targetTag} tag`) + const commits = await getCommits(this.cwd, prevRef, targetTag) + + log(`generating release notes from commits ${prevRef}..${targetTag}`) + const releaseNotes = await this.hostApi.commitsToNotes(commits) + + return { + name: targetTag, + description: releaseNotes, + } + } + + @logDryRun + async makeReleaseForTag(tagObject: { name: string }, prevRef: string): Promise { + if (this.dryRun) { + return + } + + const releaseData = await this.prepareReleaseData(tagObject.name, prevRef) + + // цель: обновить у существующего тега/релиза description в не зависимости от наличия релиза + await this.upsertRelease(tagObject.name, releaseData) + + log(`release notes for ${tagObject.name} have written successfully`) + } + + // тег должен существовать + @logDryRun + async makeReleaseForTagName(tagName: string, prevRef: string, opts: { + skipIfExists?: boolean, + } = {}): Promise { + if (this.dryRun) { + return + } + + const { skipIfExists = false } = opts + const releaseData = await this.prepareReleaseData(tagName, prevRef) + + const [responseCode, maybeRelease] = await this.getRelease(tagName) + + if (responseCode === PlatformResult.OK) { + if (!maybeRelease!.description || !skipIfExists) { + await this.editRelease(tagName, releaseData) + } else { + log(`release notes for ${tagName} already exists, skipping`) + return + } + } else if (responseCode === PlatformResult.NOT_FOUND) { // тег есть, но нет релиза + await this.createRelease(tagName, releaseData) + } else if (responseCode === PlatformResult.NO_SUCH_TAG) { + throw new Error(`Couldn't write release notes for tag "${tagName}". It doesn't exist.`) + } + + log(`release notes for ${tagName} have written successfully`) + } + + abstract addFiles(commitContext: CommitContext, filePaths: string[]): void; + + abstract appendFile(commitContext: CommitContext, filePath: string, content: string): void; + + abstract beginCommit(): CommitContext; + + abstract commit(commitContext: CommitContext, message: string, opts?: CommitOptions): Promise; + + abstract deleteFile(commitContext: CommitContext, file_path: string): void; + + abstract rollbackCommit(commitContext: CommitContext): Promise; + + abstract updateFile(commitContext: CommitContext, file_path: string, content: string): void; +} diff --git a/packages/pvm/mechanics/platform/providers.ts b/packages/pvm/mechanics/platform/providers.ts new file mode 100644 index 000000000..8019a76b9 --- /dev/null +++ b/packages/pvm/mechanics/platform/providers.ts @@ -0,0 +1,24 @@ +import { provide } from '../../lib/di' +import { + CWD_TOKEN, + GLOBAL_FLAGS_TOKEN, + HOST_API_TOKEN, + PLATFORM_TOKEN, + RAW_PLATFORM_TOKEN, + VCS_TOKEN, +} from '../../tokens' +import { DecoratedPlatform } from './decorated-platform' + +export default [ + provide({ + provide: PLATFORM_TOKEN, + useClass: DecoratedPlatform, + deps: { + platform: RAW_PLATFORM_TOKEN, + vcs: VCS_TOKEN, + globalFlags: GLOBAL_FLAGS_TOKEN, + cwd: CWD_TOKEN, + hostApi: HOST_API_TOKEN, + }, + }), +] diff --git a/src/plugins/core/publish/flags.ts b/packages/pvm/mechanics/publish/flags.ts similarity index 66% rename from src/plugins/core/publish/flags.ts rename to packages/pvm/mechanics/publish/flags.ts index 61e6b0f75..324d25bf1 100644 --- a/src/plugins/core/publish/flags.ts +++ b/packages/pvm/mechanics/publish/flags.ts @@ -1,7 +1,10 @@ +import type { InferredOptionTypes } from 'yargs' import yargs from 'yargs' -import { enpl } from '@pvm/core/lib/text/plural' -import { revParse } from '@pvm/core/lib/git/commands' +import { enpl } from '../../lib/text/plural' +import { revParse } from '../../lib/git/commands' +import { RELEASE_NOTIFICATIONS_MAP_TOKEN } from '../../tokens' +import type { Container } from '../../lib/di' const defaultConcurrency = 1 @@ -27,11 +30,11 @@ const canaryFlag = { const messageChannelFlag = { messageChannel: { desc: `Channel for notifications`, - default: undefined as unknown as string, + type: 'string' as const, }, } -export const flagsBuilder = { +export const flagsBuilder = (di: Container) => ({ filter: { alias: 'f', type: 'array' as const, @@ -44,6 +47,7 @@ export const flagsBuilder = { default: function() { return yargs.options(canaryFlag).help(false).argv.canary ? 'affected' : 'updated' } as unknown as string, + type: 'string' as const, }, strategyOption: { alias: 'S', @@ -61,7 +65,7 @@ export const flagsBuilder = { alias: 't', desc: `Same as --tag option for npm publish command: associates published package with given tag. By default equals to latest or canary (if canary mode enabled) unless registry package version is greater than published.`, - type: 'string', + type: 'string' as const, default: function() { return yargs.options(canaryFlag).help(false).argv.canary ? revParse('HEAD', process.cwd()) : null } as unknown as string, @@ -70,31 +74,32 @@ export const flagsBuilder = { alias: 'b', desc: 'Exit publishing immediately upon the first unsuccessful package publishing.', default: false, + type: 'boolean' as const, }, concurrency: { type: 'number' as const, alias: 'c', desc: `Number of simultaneously executed publishing processes. If argument not specified, makes ${enpl(['%1 threads', '%1 thread', '%1 threads'], defaultConcurrency)}, if argument specified without value, makes a thread to each CPU core`, - default: undefined as unknown as number, }, byDependentOrder: { default: false, + type: 'boolean' as const, desc: 'Publish packages in concurrency mode according to each other', }, forceVersioning: { - type: 'string', + type: 'string' as const, choices: ['tag', 'file', 'package'], default: undefined as unknown as (undefined | 'tag' | 'file' | 'package'), }, registry: { alias: 'r', desc: 'npm registry, default is taken from publishConfig.registry package.json\'s value.', - default: undefined as unknown as string, + type: 'string' as const, }, notify: { alias: 'Z', desc: 'Send notification if SLACK_WEBHOOK_URL or SLACK_TOKEN env variable present.', - type: 'boolean', + type: 'boolean' as const, default: function() { const { canary, messageChannel } = yargs.options({ ...messageChannelFlag, @@ -103,43 +108,23 @@ export const flagsBuilder = { return !canary || !!messageChannel } as unknown as boolean, }, - notifyScript: { + notificationName: { alias: 'i', desc: ` - The script that will be executed to create the notification text after successfull packages publishing. - By default, the internal script "@pvm/lib-core/messages/notify-scripts/release.js" is used. - - Could be absolute file path, or file path relative to config, or http/https URL to script in the network. - - The script is obliged to send the message through function process.send. - The message should have the following format: { type: 'message', message: . }. - - Also script will receive the object describing the publication in the form: - { - tag: 'release-tag', - commits: , - packagesStats: { - success: [{pkg: string, registryVersion: string, publishedVersion: string}, ...] - skipped: [{pkg: string, publishVersion: string, reason: string}, ...] - error: [{pkg: string, publishVersion: string, reason: string}, ...] - }, - } - - Information about the published status of the packages. For more information about this field, see the documentation site. + Direct name of notification builder that will be used to build result publish message. Names are + mapped to values from RELEASE_NOTIFICATIONS_MAP_TOKEN providers. Current builders are: + ${Object.keys(di.get(RELEASE_NOTIFICATIONS_MAP_TOKEN)!.reduce((acc, m) => Object.assign(acc, m), {})).map(k => ` - ${k}`).join(`\n`)} `, - default: undefined as unknown as string, + type: 'string' as const, }, outputStats: { alias: 'o', desc: `Output filename for JSON report of published packages.`, - default: undefined as unknown as string, + type: 'string' as const, }, ...messageChannelFlag, ...canaryFlag, -} as const +}) -type FlagsBuilder = typeof flagsBuilder -export type Flags = { - [P in keyof FlagsBuilder]: FlagsBuilder[P]['default'] -} +export type Flags = InferredOptionTypes> diff --git a/src/plugins/core/publish/index.ts b/packages/pvm/mechanics/publish/index.ts similarity index 87% rename from src/plugins/core/publish/index.ts rename to packages/pvm/mechanics/publish/index.ts index 59c530e58..cabdfacc5 100644 --- a/src/plugins/core/publish/index.ts +++ b/packages/pvm/mechanics/publish/index.ts @@ -8,24 +8,21 @@ import pMap from 'p-map' import defaults from 'lodash/defaults' import mapValues from 'lodash/mapValues' -import { getHostApi } from '@pvm/core/lib/plugins' -import { parseSubArgs } from '@pvm/core/lib/text/sub-args' -import runShell from '@pvm/core/lib/shell/run' -import execShell from '@pvm/core/lib/shell/exec' -import shell from '@pvm/core/lib/shell' -import type { Config } from '@pvm/core/lib/config' -import { getConfig } from '@pvm/core/lib/config' -import drainItems from '@pvm/core/lib/iter/drain-items' -import { lastReleaseTag } from '@pvm/core/lib/git/last-release-tag' -import { getReleaseCommits } from '@pvm/core/lib/git/release-commits' -import { enpl } from '@pvm/core/lib/text/plural' -import { matchAny } from '@pvm/core/lib/pkg-match' -import revParse from '@pvm/core/lib/git/rev-parse' - -import { pkgset } from '@pvm/pkgset' -import { Notificator } from '@pvm/notifications' -import { Repository } from '@pvm/repository/lib' -import { buildDependantPackagesListIntoTree, visitDependantPackagesTree } from '@pvm/repository/lib/dependent-packages' +import { parseSubArgs } from '../../lib/text/sub-args' +import runShell from '../../lib/shell/run' +import execShell from '../../lib/shell/exec' +import { shell } from '../../lib/shell' +import type { Config, PkgFailStats, PkgSuccessStats, PkgSkippedStats, PublishedStats } from '../../types' +import drainItems from '../../lib/iter/drain-items' +import { lastReleaseTag } from '../../lib/git/last-release-tag' +import { getReleaseCommits } from '../../lib/git/release-commits' +import { enpl } from '../../lib/text/plural' +import { matchAny } from '../../lib/pkg-match' +import revParse from '../../lib/git/rev-parse' + +import { pkgset } from '../pkgset/pkgset' +import type { Repository } from '../repository' +import { buildDependantPackagesListIntoTree, visitDependantPackagesTree } from '../repository/dependent-packages' import { setupPublishNpmRCAndEnvVariables } from './prepare' import type { Flags } from './flags' @@ -40,16 +37,17 @@ import { printUnpublishedSummary, pushPkgStats, sortPublishedStats, } from './publish-stats' -import commits from '@pvm/core/lib/git/commits' -import { PkgSet } from '@pvm/core/lib/pkg-set' +import commits from '../../lib/git/commits' +import { PkgSet } from '../../lib/pkg-set' import { BasicPublishApplier } from './publish-applier/basic' import { CanaryPublishApplier } from './publish-applier/canary' -import type { PkgFailStats, PkgSuccessStats, PkgSkippedStats, PublishedStats } from '@pvm/types' -import type { Pkg } from '@pvm/core/lib/pkg' +import type { Pkg } from '../../lib/pkg' import { getPassedRegistry, getPkgRegistry } from './registry' import type { AbstractPublishApplier } from './publish-applier/abstract' -import { env } from '@pvm/core/lib/env' +import { env } from '../../lib/env' +import type { Container } from '../../lib/di' +import { CONFIG_TOKEN, CWD_TOKEN, NOTIFICATOR_TOKEN, REPOSITORY_FACTORY_TOKEN } from '../../tokens' const defaultConcurrency = 1 @@ -59,15 +57,14 @@ const { PVM_FORCE_TEST_PUBLISH, } = env -export async function publish(flags: Flags): Promise { +export async function publish(di: Container, flags: Flags): Promise { const skipRealPublishing = isSkipRealPublishing(flags) - const cwd = process.cwd() - let config = await getConfig(cwd) + const cwd = di.get(CWD_TOKEN) + let config = di.get(CONFIG_TOKEN) const ref = revParse('HEAD', cwd) - flags = applyFlagsDefaultsForUnification(flags) + flags = applyFlagsDefaultsForUnification(di, flags) config = applyFlagsToConfig(config, flags) - await initPlugins(cwd) logger.info(`publishing packages..`) if (skipRealPublishing) { @@ -94,7 +91,7 @@ export async function publish(flags: Flags): Promise { // например в тестовых целях в мерж-реквесте запускают публикацию всех зарелиженных пакетов // но при этом в мерж-реквесте один из пакетов удаляют, соответственно, он будет присутствовать в pkgset, // но в актуальном worktree его уже не будет - const pkgsetPackages = (await drainItems(pkgset(flags.strategy, { + const pkgsetPackages = (await drainItems(pkgset(di, flags.strategy, { ...parseSubArgs(flags.strategyOption), registry: passedRegistry, }))) @@ -103,7 +100,7 @@ export async function publish(flags: Flags): Promise { * Костыль для сохранения консистентности по ref в возвращаемом pkgset и в Repository при вызове pkgsetAll * https://github.com/Tinkoff/pvm/issues/2 */ - const repo = new Repository(cwd, config, pkgsetPackages[0]?.ref) + const repo = di.get(REPOSITORY_FACTORY_TOKEN)({ ref: pkgsetPackages[0]?.ref }) const packagesForPublish = pkgsetPackages.filter(pkg => repo.pkgset.has(pkg) && (!flags.filter.length || matchAny(pkg, flags.filter))) @@ -149,7 +146,7 @@ export async function publish(flags: Flags): Promise { if (flags.notify) { try { const prevReleaseTag = lastReleaseTag(config) - const message = await releaseMessage({ + const message = await releaseMessage(di, { targetType: 'slack', // for now only slack is supported tag: flags.canary ? [prevReleaseTag, `canary:${flags.tag}`].filter(Boolean).join('-') : prevReleaseTag, commits: flags.canary ? await commits(cwd, prevReleaseTag, ref) : await getReleaseCommits(config), @@ -157,9 +154,8 @@ export async function publish(flags: Flags): Promise { pvmConfig: config, registry: passedRegistry, }, { - notifyScript: flags.notifyScript, + notificationName: flags.notificationName, strategy: flags.strategy, - hostApi: await getHostApi(), }) if (flags.messageChannel) { @@ -167,7 +163,7 @@ export async function publish(flags: Flags): Promise { } if (!skipRealPublishing) { - const notificator = await Notificator.create(config.cwd) + const notificator = di.get(NOTIFICATOR_TOKEN) await notificator.sendMessage(message) } else { logger.info('Notify message:') @@ -257,7 +253,7 @@ async function publishPackage(inputPkg: Pkg, publishApplier: AbstractPublishAppl const passedRegistry = getPassedRegistry(flags, config) const registry = getPkgRegistry(inputPkg, flags) - const { publishEnv } = await setupPublishNpmRCAndEnvVariables(repo.cwd, { + const { publishEnv } = await setupPublishNpmRCAndEnvVariables(repo.config, { baseRegistry: passedRegistry, logger, }) @@ -408,17 +404,12 @@ function applyFlagsToConfig(config: Config, flags: Flags): Config { return config } -function applyFlagsDefaultsForUnification(flags: Flags): Flags { +function applyFlagsDefaultsForUnification(di: Container, flags: Flags): Flags { // унифицируем дефолтные значения для вызовов через node api и cli - return defaults(flags, mapValues(flagsBuilder, builder => builder.default)) + return defaults(flags, mapValues(flagsBuilder(di), builder => (builder as any).default)) } -async function initPlugins(cwd): Promise { - // для загрузки плагинов - await getHostApi(cwd) -} - -let distTagsCommandSupported +let distTagsCommandSupported: boolean function areDistTagsSupported(pkgName: string, registry?: string): boolean { if (distTagsCommandSupported === void 0) { try { @@ -447,7 +438,7 @@ async function getSortedPublishedVersions(pkgName: string, registry?: string): P if (typeof distTags === 'string') { distTags = [distTags] } - } catch (e) { + } catch (e: any) { // if package completely unpublished if (e.toString().indexOf('E404') !== -1) { return [] diff --git a/src/plugins/core/publish/logger.ts b/packages/pvm/mechanics/publish/logger.ts similarity index 93% rename from src/plugins/core/publish/logger.ts rename to packages/pvm/mechanics/publish/logger.ts index e03c99f7c..23d4c0345 100644 --- a/src/plugins/core/publish/logger.ts +++ b/packages/pvm/mechanics/publish/logger.ts @@ -1,4 +1,4 @@ -import { loggerFor } from '@pvm/core/lib/logger' +import { loggerFor } from '../../lib/logger' import stream from 'stream' export const logger = loggerFor('pvm:publish') diff --git a/src/plugins/core/publish/prepare.ts b/packages/pvm/mechanics/publish/prepare.ts similarity index 88% rename from src/plugins/core/publish/prepare.ts rename to packages/pvm/mechanics/publish/prepare.ts index a97441e19..61a81da42 100644 --- a/src/plugins/core/publish/prepare.ts +++ b/packages/pvm/mechanics/publish/prepare.ts @@ -5,12 +5,12 @@ import { URL } from 'url' import semver from 'semver' -import { getConfig } from '@pvm/core/lib/config' -import { getNpmVersion } from '@pvm/core/lib/runtime-env/versions' -import shell from '@pvm/core/lib/shell' -import { logger as defaultLogger } from '@pvm/core/lib/logger' -import type { LoggerFunc } from '@pvm/core/lib/logger' -import { env } from '@pvm/core/lib/env' +import { getNpmVersion } from '../../lib/runtime-env/versions' +import { shell } from '../../lib/shell' +import { logger as defaultLogger } from '../../lib/logger' +import type { LoggerFunc } from '../../lib/logger' +import { env } from '../../lib/env' +import type { Config } from '../../types/config' interface LoggerLike { log: LoggerFunc, @@ -43,13 +43,13 @@ export interface PublishPrepareResult { npmrc: string[], } -export async function setupPublishNpmRCAndEnvVariables(cwd: string, opts: PrepareOpts = {}): Promise { +export async function setupPublishNpmRCAndEnvVariables(config: Config, opts: PrepareOpts = {}): Promise { + const cwd = config.cwd const { baseRegistry = 'https://registry.npmjs.org', logger = defaultLogger, dontWriteNpmRc = false, } = opts - const config = await getConfig(cwd) const npmVersion = getNpmVersion() || '0.0.0' logger.log(`npm version is ${npmVersion}`) diff --git a/packages/pvm/mechanics/publish/providers.ts b/packages/pvm/mechanics/publish/providers.ts new file mode 100644 index 000000000..2a16a0319 --- /dev/null +++ b/packages/pvm/mechanics/publish/providers.ts @@ -0,0 +1,26 @@ +import { provide } from '../../lib/di' +import { RELEASE_NOTIFICATIONS_MAP_TOKEN } from '../../tokens' +import type { ReleasedProps } from '../../types' +import { buildMessage, releaseMessage } from '../../lib/messages/message-builder' + +export default [ + provide({ + provide: RELEASE_NOTIFICATIONS_MAP_TOKEN, + useValue: { + release: (releaseProps: ReleasedProps) => Promise.resolve(releaseMessage(releaseProps, { + attachPackages: false, + })), + releaseWithPackages: (releaseProps: ReleasedProps) => Promise.resolve(releaseMessage(releaseProps, { + attachPackages: true, + })), + stale: (releaseProps: ReleasedProps) => Promise.resolve(buildMessage(releaseProps, { + bodyWrapper: (_body, { releaseLink, releaseName, registry }) => { + const header = `Publish stale packages for ${releaseLink || releaseName} for ${registry || 'default'} registry` + + return `${header}` + }, + attachPackages: true, + })), + }, + }), +] diff --git a/src/plugins/core/publish/publish-applier/abstract.ts b/packages/pvm/mechanics/publish/publish-applier/abstract.ts similarity index 92% rename from src/plugins/core/publish/publish-applier/abstract.ts rename to packages/pvm/mechanics/publish/publish-applier/abstract.ts index 529392f43..93a5b6fb1 100644 --- a/src/plugins/core/publish/publish-applier/abstract.ts +++ b/packages/pvm/mechanics/publish/publish-applier/abstract.ts @@ -1,7 +1,7 @@ -import type { AppliedPkg, Pkg } from '@pvm/core/lib/pkg' -import { loadPkg } from '@pvm/core/lib/pkg' -import { isStubVersion } from '@pvm/core/lib/tag-meta' -import type { Repository } from '@pvm/repository' +import type { AppliedPkg, Pkg } from '../../../lib/pkg' +import { loadPkg } from '../../../lib/pkg' +import { isStubVersion } from '../../../lib/tag-meta' +import type { Repository } from '../../repository' function lowerCaseSentence(sentence: string): string { return sentence.charAt(0).toLowerCase() + sentence.substr(1) diff --git a/src/plugins/core/publish/publish-applier/basic.ts b/packages/pvm/mechanics/publish/publish-applier/basic.ts similarity index 77% rename from src/plugins/core/publish/publish-applier/basic.ts rename to packages/pvm/mechanics/publish/publish-applier/basic.ts index ad17f5a79..cec4cbfcd 100644 --- a/src/plugins/core/publish/publish-applier/basic.ts +++ b/packages/pvm/mechanics/publish/publish-applier/basic.ts @@ -1,6 +1,6 @@ -import type { Pkg } from '@pvm/core/lib/pkg' +import type { Pkg } from '../../../lib/pkg' import { AbstractPublishApplier } from './abstract' -import type { Repository } from '@pvm/repository' +import type { Repository } from '../../repository' export class BasicPublishApplier extends AbstractPublishApplier { // eslint-disable-next-line no-useless-constructor diff --git a/src/plugins/core/publish/publish-applier/canary.ts b/packages/pvm/mechanics/publish/publish-applier/canary.ts similarity index 93% rename from src/plugins/core/publish/publish-applier/canary.ts rename to packages/pvm/mechanics/publish/publish-applier/canary.ts index f89267fb9..621801cd5 100644 --- a/src/plugins/core/publish/publish-applier/canary.ts +++ b/packages/pvm/mechanics/publish/publish-applier/canary.ts @@ -1,14 +1,15 @@ -import type { PkgSet } from '@pvm/core/lib/pkg-set' +import type { PkgSet } from '../../../lib/pkg-set' import semver from 'semver' -import { logger } from '@pvm/core/lib/logger' -import { PkgMap } from '@pvm/core/lib/pkg-map' -import httpreq from '@pvm/core/lib/httpreq' +import { logger } from '../../../lib/logger' +import { PkgMap } from '../../../lib/pkg-map' +import type { HttpReqError } from '../../../lib/httpreq' +import { httpreq } from '../../../lib/httpreq' import { AbstractPublishApplier } from './abstract' import { getPkgRegistry } from '../registry' -import type { Pkg } from '@pvm/core/lib/pkg' -import type { Repository } from '@pvm/repository' +import type { Pkg } from '../../../lib/pkg' +import type { Repository } from '../../repository' import type { Flags } from '../flags' export class CanaryPublishApplier extends AbstractPublishApplier { @@ -102,8 +103,8 @@ export class CanaryPublishApplier extends AbstractPublishApplier { * Поэтому ходим в registry напрямую через rest api */ packumentStr = (await httpreq(`${registry.replace(/\/$/, '')}/${pkg.name}`)).body - } catch (e) { - if (e.statusCode !== 404) { + } catch (e: unknown) { + if ((e as HttpReqError).statusCode !== 404) { throw e } } diff --git a/src/plugins/core/publish/publish-stats.ts b/packages/pvm/mechanics/publish/publish-stats.ts similarity index 96% rename from src/plugins/core/publish/publish-stats.ts rename to packages/pvm/mechanics/publish/publish-stats.ts index f022ed6cb..f4ffe47fd 100644 --- a/src/plugins/core/publish/publish-stats.ts +++ b/packages/pvm/mechanics/publish/publish-stats.ts @@ -1,5 +1,5 @@ -import type { PkgFailStats, PkgSkippedStats, PkgSuccessStats, PublishedStats } from '@pvm/types' -import { cmpStr } from '@pvm/core/lib/utils/string' +import type { PkgFailStats, PkgSkippedStats, PkgSuccessStats, PublishedStats } from '../../types' +import { cmpStr } from '../../lib/utils/string' import chalk from 'chalk' import CliTable from 'cli-table' diff --git a/src/plugins/core/publish/registry.ts b/packages/pvm/mechanics/publish/registry.ts similarity index 77% rename from src/plugins/core/publish/registry.ts rename to packages/pvm/mechanics/publish/registry.ts index a77188236..c40b29efb 100644 --- a/src/plugins/core/publish/registry.ts +++ b/packages/pvm/mechanics/publish/registry.ts @@ -1,6 +1,6 @@ import type { Flags } from './flags' -import type { Config } from '@pvm/core/lib/config' -import type { Pkg } from '@pvm/core/lib/pkg' +import type { Config } from '../../types' +import type { Pkg } from '../../lib/pkg' export function getPassedRegistry(flags: Flags, config: Config): string | undefined { return flags.registry || config.publish.registry diff --git a/packages/pvm/mechanics/publish/release-message.ts b/packages/pvm/mechanics/publish/release-message.ts new file mode 100644 index 000000000..69bc3b3ee --- /dev/null +++ b/packages/pvm/mechanics/publish/release-message.ts @@ -0,0 +1,24 @@ +import type { ReleasedProps, Message } from '../../types' + +import type { Container } from '../../lib/di' +import { RELEASE_NOTIFICATIONS_MAP_TOKEN } from '../../tokens' + +interface NotifyOpts { + notificationName?: string, + strategy?: string, +} + +export async function releaseMessage(di: Container, releasedProps: ReleasedProps, opts: NotifyOpts): Promise { + const { strategy } = opts + const notificationBuildersList = di.get(RELEASE_NOTIFICATIONS_MAP_TOKEN)!.reduce((acc, m) => Object.assign(acc, m), {}) + + const { + notificationName = strategy === 'stale' ? 'stale' : 'release', + } = opts + + if (!notificationBuildersList[notificationName]) { + throw new Error(`Notificator "${notificationBuildersList[notificationName]}" is not listed in notificators map. Inspect provided RELEASE_NOTIFICATIONS_MAP_TOKEN and check provider notificatorName for correctness.`) + } + + return notificationBuildersList[notificationName](releasedProps) +} diff --git a/packages/pvm-releases/lib/index.ts b/packages/pvm/mechanics/releases/index.ts similarity index 70% rename from packages/pvm-releases/lib/index.ts rename to packages/pvm/mechanics/releases/index.ts index df86d1028..41d539736 100644 --- a/packages/pvm-releases/lib/index.ts +++ b/packages/pvm/mechanics/releases/index.ts @@ -1,13 +1,14 @@ -import { prevReleaseTag, lastReleaseTag } from '@pvm/core/lib/git/last-release-tag' -import { pkgsetFromRef } from '@pvm/pkgset/lib/pkgset-from-ref' -import { getConfig } from '@pvm/core/lib/config' -import revParse from '@pvm/core/lib/git/rev-parse' -import gitCommits from '@pvm/core/lib/git/commits' -import { logger } from '@pvm/core/lib/logger' -import { wdShell } from '@pvm/core/lib/shell' - -import type { Config } from '@pvm/core/lib/config/types' -import type { PkgIdentity } from '../types' +import { prevReleaseTag, lastReleaseTag } from '../../lib/git/last-release-tag' +import { pkgsetFromRef } from '../pkgset/pkgset-from-ref' +import revParse from '../../lib/git/rev-parse' +import gitCommits from '../../lib/git/commits' +import { logger } from '../../lib/logger' +import { wdShell } from '../../lib/shell' + +import type { Config } from '../../types' +import type { PkgIdentity } from '../../mechanics/releases/types' +import type { Container } from '../../lib/di' +import { CONFIG_TOKEN, CWD_TOKEN } from '../../tokens' function changedPackagesFromRef(config: Config, ref: string): PkgIdentity[] { logger.silly(`calculate changed packages for ${ref}`) @@ -54,10 +55,10 @@ export interface GetCurrentReleaseOpts { // 1. commits in target release // 2. packages[name, version] in target release // 3. release name -export async function getCurrentRelease(opts: GetCurrentReleaseOpts = {}) { - const { ref = 'HEAD', cwd = process.cwd() } = opts +export async function getCurrentRelease(di: Container, opts: GetCurrentReleaseOpts = {}) { + const { ref = 'HEAD', cwd = di.get(CWD_TOKEN) } = opts - const config = await getConfig(cwd) + const config = di.get(CONFIG_TOKEN) const releaseTagName = lastReleaseTag(config, ref) @@ -77,9 +78,3 @@ export async function getCurrentRelease(opts: GetCurrentReleaseOpts = {}) { name: releaseTagName, } } - -if (require.main === module) { - getCurrentRelease().then(releaseInfo => { - console.log(require('util').inspect(releaseInfo, false, 4, true)) - }) -} diff --git a/packages/pvm-releases/lib/producers/releases-by-working-tree.ts b/packages/pvm/mechanics/releases/producers/releases-by-working-tree.ts similarity index 73% rename from packages/pvm-releases/lib/producers/releases-by-working-tree.ts rename to packages/pvm/mechanics/releases/producers/releases-by-working-tree.ts index b2e4a4bba..5e04244ae 100644 --- a/packages/pvm-releases/lib/producers/releases-by-working-tree.ts +++ b/packages/pvm/mechanics/releases/producers/releases-by-working-tree.ts @@ -1,21 +1,21 @@ -import { lastReleaseTagIgnoreEnv } from '@pvm/core/lib/git/last-release-tag' -import { getConfig } from '@pvm/core/lib/config' -import { loggerFor } from '@pvm/core/lib/logger' -import { gitAuthorDate, isShallowRepository, revParse } from '@pvm/core/lib/git/commands' -import gitCommits from '@pvm/core/lib/git/commits' -import { getHostApi } from '@pvm/core/lib/plugins' -import { changedFiles } from '@pvm/pkgset/lib/changed-files' -import { makeUpdateState } from '@pvm/update/lib/index' -import { pkgsetFromRef } from '@pvm/pkgset/lib/pkgset-from-ref' -import { ImmutablePkgSet } from '@pvm/core/lib/pkg-set' -import { isReleaseCommit } from '@pvm/core/lib/versioning' -import { UpdateReasonType } from '@pvm/update/lib/update-state' -import { ChangedContext } from '@pvm/update/lib/changed-context' +import { lastReleaseTagIgnoreEnv } from '../../../lib/git/last-release-tag' +import { loggerFor } from '../../../lib/logger' +import { gitAuthorDate, isShallowRepository, revParse } from '../../../lib/git/commands' +import gitCommits from '../../../lib/git/commits' +import { changedFiles } from '../../pkgset/changed-files' +import { makeUpdateState } from '../../update' +import { pkgsetFromRef } from '../../pkgset/pkgset-from-ref' +import { ImmutablePkgSet } from '../../../lib/pkg-set' +import { isReleaseCommit } from '../../../lib/versioning' +import { UpdateReasonType } from '../../update/update-state' +import { ChangedContext } from '../../update/changed-context' import { lookBackForReleaseTag, ReleasePosition } from '../rline' -import type { PkgReleaseEntry, ReleaseData, ReleaseDataExt } from '../../types' -import type { Pkg } from '@pvm/core/lib/pkg' -import { env } from '@pvm/core/lib/env' +import type { PkgReleaseEntry, ReleaseData, ReleaseDataExt } from '../../../mechanics/releases/types' +import type { Pkg } from '../../../lib/pkg' +import { env } from '../../../lib/env' +import type { Container } from '../../../lib/di' +import { CONFIG_TOKEN, CWD_TOKEN, HOST_API_TOKEN } from '../../../tokens' export interface MakeReleasesFromWTOpts { stopAtRef?: string, @@ -35,9 +35,10 @@ function * releasedPackages(currentPackages: Iterable, prevPackages: Immuta const logger = loggerFor('pvm:releases') -async function makeReleasesFromWorkingTree(cwd: string, opts: MakeReleasesFromWTOpts = {}): Promise { +async function makeReleasesFromWorkingTree(di: Container, opts: MakeReleasesFromWTOpts = {}): Promise { const { stopAtRef = void 0, startFrom = 'HEAD' } = opts - const config = await getConfig(cwd) + const cwd = di.get(CWD_TOKEN) + const config = di.get(CONFIG_TOKEN) let currentRef = startFrom const result: ReleaseDataExt[] = [] @@ -69,7 +70,7 @@ async function makeReleasesFromWorkingTree(cwd: string, opts: MakeReleasesFromWT currentPackages = prevPackages || new ImmutablePkgSet(pkgsetFromRef(config, currentRef)) const targetRef = isReleaseCommit(config.cwd, releaseTag) ? `${releaseTag}^` : releaseTag - const hostApi = await getHostApi(config.cwd) + const hostApi = di.get(HOST_API_TOKEN) if (lookBackReleaseInfo.releasePosition === ReleasePosition.following) { const prevReleaseTag = lookBackReleaseInfo.prevTagName @@ -91,7 +92,7 @@ async function makeReleasesFromWorkingTree(cwd: string, opts: MakeReleasesFromWT config, }) - const updateState = await makeUpdateState(changedContext) + const updateState = await makeUpdateState(di, changedContext) prevPackages = new ImmutablePkgSet(pkgsetFromRef(config, fromRef)) @@ -159,24 +160,3 @@ async function makeReleasesFromWorkingTree(cwd: string, opts: MakeReleasesFromWT export { makeReleasesFromWorkingTree, } - -async function testMain() { - const fs = require('fs') - const cwd = process.cwd() - - const reseaseList = await makeReleasesFromWorkingTree(cwd, { - stopAtRef: env.STOP_AT, - }) - - console.log(`produced ${reseaseList.length} releases`) - - fs.writeFileSync('releases.json', JSON.stringify(reseaseList)) - console.info('release list saved to releases.json') -} - -if (require.main === module) { - testMain().catch(e => { - console.error(e) - process.exit(1) - }) -} diff --git a/packages/pvm-releases/lib/readme.md b/packages/pvm/mechanics/releases/readme.md similarity index 100% rename from packages/pvm-releases/lib/readme.md rename to packages/pvm/mechanics/releases/readme.md diff --git a/packages/pvm-releases/lib/release-data.ts b/packages/pvm/mechanics/releases/release-data.ts similarity index 84% rename from packages/pvm-releases/lib/release-data.ts rename to packages/pvm/mechanics/releases/release-data.ts index d484f5414..e0d10dddf 100644 --- a/packages/pvm-releases/lib/release-data.ts +++ b/packages/pvm/mechanics/releases/release-data.ts @@ -1,9 +1,9 @@ -import now from '@pvm/core/lib/now' -import { UpdateReasonType } from '@pvm/update/lib/update-state' -import { getPersistentRef } from '@pvm/core/lib/git/commands' +import now from '../../lib/now' +import { UpdateReasonType } from '../update/update-state' +import { getPersistentRef } from '../../lib/git/commands' -import type { ReleaseData, ReleaseDataExt } from '../types' -import type { ReleaseContext } from '@pvm/update/types' +import type { ReleaseData, ReleaseDataExt } from '../../mechanics/releases/types' +import type { ReleaseContext } from '../update/types' export interface ReleaseDataMakerOpts { dateNow?: Date, diff --git a/packages/pvm-releases/lib/release-list.ts b/packages/pvm/mechanics/releases/release-list.ts similarity index 90% rename from packages/pvm-releases/lib/release-list.ts rename to packages/pvm/mechanics/releases/release-list.ts index 545998e70..c0d7e19b0 100644 --- a/packages/pvm-releases/lib/release-list.ts +++ b/packages/pvm/mechanics/releases/release-list.ts @@ -1,14 +1,15 @@ import path from 'path' import fs from 'fs' import ms from 'ms' +// @ts-ignore import bytes from 'bytes' -import { expDropRight } from '@pvm/core/lib/utils/array' +import { expDropRight } from '../../lib/utils/array' import { makeReleasesFromWorkingTree } from './producers/releases-by-working-tree' -import { loggerFor } from '@pvm/core/lib/logger' -import now from '@pvm/core/lib/now' +import { loggerFor } from '../../lib/logger' +import now from '../../lib/now' -import type { ReleaseData } from '../types' -import type { Config, ArtifactLimitDef } from '@pvm/core/lib/config/types' +import type { ReleaseData } from './types' +import type { Config, ArtifactLimitDef } from '../../types' const logger = loggerFor('pvm:releases') @@ -68,7 +69,7 @@ export function appendReleaseData(config: Config, releaseList: ReleaseData[], re return reduceReleaseList(config, releaseList) } -export function fsAppendReleaseData(config: Config, releaseData: ReleaseData): void { +export function fsAppendReleaseData(config: Config, releaseData: ReleaseData, dryRun: boolean): void { const releaseListConfig = config.release_list if (!releaseListConfig.enabled) { return @@ -79,7 +80,7 @@ export function fsAppendReleaseData(config: Config, releaseData: ReleaseData): v releaseList = JSON.parse(fs.readFileSync(fullPath, { encoding: 'utf-8' })) as unknown as ReleaseData[] } const reducedReleaseList = appendReleaseData(config, releaseList, releaseData) - if (!config.executionContext.dryRun) { + if (!dryRun) { fs.writeFileSync(fullPath, JSON.stringify(reducedReleaseList)) } logger.info(`ReleaseList(size=${reducedReleaseList.length}) has been written to "${releaseListConfig.path}"`) diff --git a/packages/pvm-releases/lib/rline.ts b/packages/pvm/mechanics/releases/rline.ts similarity index 85% rename from packages/pvm-releases/lib/rline.ts rename to packages/pvm/mechanics/releases/rline.ts index a5379a6eb..b72466cab 100644 --- a/packages/pvm-releases/lib/rline.ts +++ b/packages/pvm/mechanics/releases/rline.ts @@ -1,7 +1,7 @@ -import { isShallowRepository } from '@pvm/core/lib/git/commands' -import { lastReleaseTagIgnoreEnv } from '@pvm/core/lib/git/last-release-tag' +import { isShallowRepository } from '../../lib/git/commands' +import { lastReleaseTagIgnoreEnv } from '../../lib/git/last-release-tag' -import type { Config } from '@pvm/core/lib/config' +import type { Config } from '../../types' export enum ReleasePosition { following, // это не первый релиз, перед ним еще есть diff --git a/packages/pvm-releases/types/index.ts b/packages/pvm/mechanics/releases/types.ts similarity index 86% rename from packages/pvm-releases/types/index.ts rename to packages/pvm/mechanics/releases/types.ts index 292567e78..403925500 100644 --- a/packages/pvm-releases/types/index.ts +++ b/packages/pvm/mechanics/releases/types.ts @@ -1,4 +1,4 @@ -import type { UpdateReasonType } from '@pvm/update/lib/update-state' +import type { UpdateReasonType } from '../update/update-state' export interface PkgIdentity { name: string, diff --git a/packages/pvm-repository/lib/dependent-packages.ts b/packages/pvm/mechanics/repository/dependent-packages.ts similarity index 96% rename from packages/pvm-repository/lib/dependent-packages.ts rename to packages/pvm/mechanics/repository/dependent-packages.ts index 4c3c33b12..547686573 100644 --- a/packages/pvm-repository/lib/dependent-packages.ts +++ b/packages/pvm/mechanics/repository/dependent-packages.ts @@ -1,5 +1,5 @@ -import { PkgSet } from '@pvm/core/lib/pkg-set' -import type { Pkg } from '@pvm/core/lib/pkg' +import { PkgSet } from '../../lib/pkg-set' +import type { Pkg } from '../../lib/pkg' type PkgNode = { parents: Set, diff --git a/packages/pvm-repository/lib/index.ts b/packages/pvm/mechanics/repository/index.ts similarity index 100% rename from packages/pvm-repository/lib/index.ts rename to packages/pvm/mechanics/repository/index.ts diff --git a/packages/pvm-repository/lib/linter.ts b/packages/pvm/mechanics/repository/linter.ts similarity index 95% rename from packages/pvm-repository/lib/linter.ts rename to packages/pvm/mechanics/repository/linter.ts index af21d9adc..d84189b30 100644 --- a/packages/pvm-repository/lib/linter.ts +++ b/packages/pvm/mechanics/repository/linter.ts @@ -2,16 +2,16 @@ import fs from 'fs' import path from 'path' import semver from 'semver' -import { isStubVersion } from '@pvm/core/lib/tag-meta' -import { loggerFor } from '@pvm/core/lib/logger' -import { versioningFile } from '@pvm/core/lib/dedicated-versions-file' -import { indexFile } from '@pvm/core/lib/git/commands' -import { enpl } from '@pvm/core/lib/text/plural' +import { isStubVersion } from '../../lib/tag-meta' +import { loggerFor } from '../../lib/logger' +import { versioningFile } from '../../lib/dedicated-versions-file' +import { indexFile } from '../../lib/git/commands' +import { enpl } from '../../lib/text/plural' import type { Repository } from './repository' -import type { Pkg } from '@pvm/core/lib/pkg' -import type { Config } from '@pvm/core/lib/config' +import type { Pkg } from '../../lib/pkg' +import type { Config } from '../../types' export interface LintOptions { fix?: boolean, @@ -110,6 +110,9 @@ const versionsFileGeneralRule: LintRepoRule = { } const versionsRecord = versioningFile.load(repo.config) + if (!versionsRecord) { + return + } // проверяем что нет лишних записей for (const pkgName of Object.keys(versionsRecord)) { if (!repo.pkgset.has(pkgName)) { diff --git a/packages/pvm/mechanics/repository/providers.ts b/packages/pvm/mechanics/repository/providers.ts new file mode 100644 index 000000000..79c8e82fb --- /dev/null +++ b/packages/pvm/mechanics/repository/providers.ts @@ -0,0 +1,29 @@ +import { provide } from '../../lib/di' +import { Repository } from './repository' +import { CONFIG_TOKEN, CWD_TOKEN, HOST_API_TOKEN, PLATFORM_TOKEN, REPOSITORY_FACTORY_TOKEN } from '../../tokens' + +export default [ + provide({ + provide: REPOSITORY_FACTORY_TOKEN, + useFactory({ + config, + hostApi, + platform, + cwd, + }) { + return ({ ref }: { ref: string | void } = { ref: undefined }) => new Repository({ + config, + hostApi, + platform, + ref, + cwd, + }) + }, + deps: { + config: CONFIG_TOKEN, + hostApi: HOST_API_TOKEN, + platform: PLATFORM_TOKEN, + cwd: CWD_TOKEN, + }, + }), +] diff --git a/packages/pvm-repository/lib/repository.ts b/packages/pvm/mechanics/repository/repository.ts similarity index 82% rename from packages/pvm-repository/lib/repository.ts rename to packages/pvm/mechanics/repository/repository.ts index 3fa0cffe0..77030c90d 100644 --- a/packages/pvm-repository/lib/repository.ts +++ b/packages/pvm/mechanics/repository/repository.ts @@ -1,23 +1,24 @@ import semver from 'semver' -import { getConfig } from '@pvm/core/lib/config' -import { lazyCallee } from '@pvm/core/lib/class-helpers' -import { pkgsetAll } from '@pvm/pkgset/lib/pkgset-all' -import { loadPkg } from '@pvm/core/lib/pkg' -import includeRootResolve from '@pvm/pkgset/lib/include-root-resolve' -import { getHostApi } from '@pvm/core/lib/plugins' +import { lazyCallee } from '../../lib/class-helpers' +import { pkgsetAll } from '../pkgset/pkgset-all' +import { loadPkg } from '../../lib/pkg' +import includeRootResolve from '../pkgset/include-root-resolve' import { getUnifiedGroups } from './unified-groups' -import { ImmutablePkgSet, PkgSet } from '@pvm/core/lib/pkg-set' -import loadHintsFile, { validateUpdateHints } from '@pvm/core/lib/hints-file' -import { lastReleaseTag } from '@pvm/core/lib/git/last-release-tag' -import { logger } from '@pvm/core/lib/logger' -import { noPackagesInMugError } from '@pvm/core/lib/behaviors/no-packages-in-mug' - -import type { Config } from '@pvm/core/lib/config' -import type { Pkg, AppliedPkg } from '@pvm/core/lib/pkg' -import type { UpdateHints } from '@pvm/types' -import { wdShell } from '@pvm/core' -import revParse from '@pvm/core/lib/git/rev-parse' -import { initVcsPlatform } from '@pvm/vcs' +import { ImmutablePkgSet, PkgSet } from '../../lib/pkg-set' +import loadHintsFile, { validateUpdateHints } from '../../lib/hints-file' +import { lastReleaseTag } from '../../lib/git/last-release-tag' +import { logger } from '../../lib/logger' +import { noPackagesInMugError } from '../../lib/behaviors/no-packages-in-mug' + +import type { Config, HostApi, UpdateHints } from '../../types' +import type { Pkg, AppliedPkg } from '../../lib/pkg' + +import { wdShell } from '../../lib/shell' +import revParse from '../../lib/git/rev-parse' +import type { Container } from '../../lib/di' +import type { HOST_API_TOKEN } from '../../tokens' +import { REPOSITORY_FACTORY_TOKEN } from '../../tokens' +import type { PlatformInterface } from '../platform' interface RepositoryInitOpts { ref?: string | void, @@ -38,19 +39,28 @@ interface ApplyVersionOpts { export class Repository { cwd: string config: Config + platform?: PlatformInterface + hostApi: HostApi ref: string | undefined - constructor(cwd: string, config: Config, ref: string | void) { - this.cwd = cwd + constructor({ + config, + hostApi, + cwd, + platform, + ref, + }: { config: Config, hostApi: HostApi, platform: PlatformInterface, cwd: string, ref: string | void}) { this.config = config + this.hostApi = hostApi + this.platform = platform + this.cwd = cwd if (ref) { this.ref = ref } } - static async init(repositoryPath: string, opts: RepositoryInitOpts = {}): Promise { - const config = await getConfig(repositoryPath) - const repo = new Repository(repositoryPath, config, opts.ref) + static async init(di: Container, opts: RepositoryInitOpts = {}): Promise { + const repo = di.get(REPOSITORY_FACTORY_TOKEN)({ ref: opts.ref }) if (!opts.skipValidatingConfig) { repo.validateConfig() @@ -93,8 +103,8 @@ export class Repository { return result } - getHostApi(): ReturnType { - return getHostApi(this.cwd) + getHostApi(): typeof HOST_API_TOKEN { + return this.hostApi } @lazyCallee @@ -158,8 +168,7 @@ export class Repository { } } - const vcsPlatform = await initVcsPlatform({ cwd: this.cwd }) - const updateHints = await vcsPlatform.getUpdateHintsByCommit(revParse('HEAD', this.cwd)) ?? {} + const updateHints = (await this.platform?.getUpdateHintsByCommit(revParse('HEAD', this.cwd))) ?? {} validateUpdateHints(this.config, updateHints) diff --git a/packages/pvm-repository/lib/unified-groups.ts b/packages/pvm/mechanics/repository/unified-groups.ts similarity index 89% rename from packages/pvm-repository/lib/unified-groups.ts rename to packages/pvm/mechanics/repository/unified-groups.ts index 345b8a66f..8a3209b80 100644 --- a/packages/pvm-repository/lib/unified-groups.ts +++ b/packages/pvm/mechanics/repository/unified-groups.ts @@ -1,7 +1,7 @@ -import { matchAny } from '@pvm/core/lib/pkg-match' -import { PkgSet } from '@pvm/core/lib/pkg-set' -import type { Config } from '@pvm/core/lib/config/types' -import type { Pkg } from '@pvm/core/lib/pkg' +import { matchAny } from '../../lib/pkg-match' +import { PkgSet } from '../../lib/pkg-set' +import type { Config } from '../../types' +import type { Pkg } from '../../lib/pkg' export interface UnifiedGroups { mainUnifiedGroup: PkgSet, diff --git a/src/plugins/core/set-versions.ts b/packages/pvm/mechanics/set-versions/index.ts similarity index 69% rename from src/plugins/core/set-versions.ts rename to packages/pvm/mechanics/set-versions/index.ts index 0dedfc312..ad8576106 100644 --- a/src/plugins/core/set-versions.ts +++ b/packages/pvm/mechanics/set-versions/index.ts @@ -1,18 +1,19 @@ -import { isValidReleaseType } from '@pvm/core/lib/semver-extra' -import { log } from '@pvm/core/lib/logger' -import { Repository } from '@pvm/repository' -import type { AppliedPkg, Pkg } from '@pvm/core/lib/pkg' -import { pkgsetFromFlags } from '@pvm/pkgset' +import { isValidReleaseType } from '../../lib/semver-extra' +import { log, logger } from '../../lib/logger' +import { Repository } from '../repository' +import type { AppliedPkg, Pkg } from '../../lib/pkg' +import { pkgsetFromFlags } from '../pkgset/pkgset' import micromatch from 'micromatch' import type { ReleaseType } from 'semver' import semver from 'semver' -import type { PvmReleaseType } from '@pvm/types' +import type { PvmReleaseType } from '../../types' +import type { Container } from '../../lib/di' -export async function setVersions(opts: { +export async function setVersions(di: Container, opts: { versionOrReleaseType: PvmReleaseType | string, - filterPath: string[], + filterPath?: string[], strategy: string, - strategyOption: string[], + strategyOption?: string[], updateDependants: boolean, bumpDependants: boolean, }): Promise { @@ -29,13 +30,13 @@ export async function setVersions(opts: { log(`About to update packages using "${opts.strategy}" strategy`) if (filterPath.length) { - log(`filtering packages by path by ${opts.filterPath.join(', ')} glob patterns`) + log(`filtering packages by path by ${filterPath.join(', ')} glob patterns`) } - const repo = await Repository.init(process.cwd()) + const repo = await Repository.init(di) const newVersions = new Map() - for await (const pkg of pkgsetFromFlags(opts)) { - if (filterPath.length && !micromatch.any(pkg.path, opts.filterPath, {})) { + for await (const pkg of pkgsetFromFlags(di, opts)) { + if (filterPath.length && !micromatch.any(pkg.path, filterPath, {})) { continue } @@ -47,7 +48,7 @@ export async function setVersions(opts: { } else { resultVersion = semver.inc(pkg.version, versionOrReleaseType as ReleaseType) if (resultVersion === null) { - log.warn(`Could not increment version ${pkg.version} of ${pkg.name} with release type ${versionOrReleaseType}`) + logger.warn(`Could not increment version ${pkg.version} of ${pkg.name} with release type ${versionOrReleaseType}`) } } } diff --git a/packages/pvm-suffixes/lib/cities.ts b/packages/pvm/mechanics/suffixes/cities.ts similarity index 100% rename from packages/pvm-suffixes/lib/cities.ts rename to packages/pvm/mechanics/suffixes/cities.ts diff --git a/packages/pvm-suffixes/lib/elements.ts b/packages/pvm/mechanics/suffixes/elements.ts similarity index 100% rename from packages/pvm-suffixes/lib/elements.ts rename to packages/pvm/mechanics/suffixes/elements.ts diff --git a/packages/pvm-suffixes/lib/http.ts b/packages/pvm/mechanics/suffixes/http.ts similarity index 100% rename from packages/pvm-suffixes/lib/http.ts rename to packages/pvm/mechanics/suffixes/http.ts diff --git a/packages/pvm-suffixes/lib/index.ts b/packages/pvm/mechanics/suffixes/index.ts similarity index 100% rename from packages/pvm-suffixes/lib/index.ts rename to packages/pvm/mechanics/suffixes/index.ts diff --git a/packages/pvm-suffixes/lib/pokemon.ts b/packages/pvm/mechanics/suffixes/pokemon.ts similarity index 100% rename from packages/pvm-suffixes/lib/pokemon.ts rename to packages/pvm/mechanics/suffixes/pokemon.ts diff --git a/packages/pvm-suffixes/lib/superb.ts b/packages/pvm/mechanics/suffixes/superb.ts similarity index 100% rename from packages/pvm-suffixes/lib/superb.ts rename to packages/pvm/mechanics/suffixes/superb.ts diff --git a/packages/pvm-suffixes/lib/yes-no.ts b/packages/pvm/mechanics/suffixes/yes-no.ts similarity index 100% rename from packages/pvm-suffixes/lib/yes-no.ts rename to packages/pvm/mechanics/suffixes/yes-no.ts diff --git a/packages/pvm-template/lib/env.ts b/packages/pvm/mechanics/template/env.ts similarity index 81% rename from packages/pvm-template/lib/env.ts rename to packages/pvm/mechanics/template/env.ts index e43f0d6a1..ef2a8f652 100644 --- a/packages/pvm-template/lib/env.ts +++ b/packages/pvm/mechanics/template/env.ts @@ -1,18 +1,21 @@ import nunjucks from 'nunjucks' import requireSetupScript from './require-setup-script' -import { getConfig } from '@pvm/core/lib/config' -import { pullOutLinks, dottifyList } from '@pvm/core/lib/text/markdown' -import { issueToLink, issueToMdLink } from '@pvm/core/lib/text/jira' -import { stripServiceLabels } from '@pvm/core/lib/text/commits' -import { stripPkgNamespace } from '@pvm/core/lib/tag-meta' - -let env +import { pullOutLinks, dottifyList } from '../../lib/text/markdown' +import { issueToLink, issueToMdLink } from '../../lib/text/jira' +import { stripServiceLabels } from '../../lib/text/commits' +import { stripPkgNamespace } from '../../lib/tag-meta' +import type { Config } from '../../types' +import type { Pkg } from '../../lib/pkg' + +let env: nunjucks.Environment & { + setVar?: (name: string, value: any) => void, + getVar?: (name: string) => any, +} -async function getEnv(cwd: string = process.cwd()): Promise { +async function getEnv(config: Config): Promise { if (!env) { - const config = await getConfig(cwd) const ConfigLoader = class { - public getSource(name) { + public getSource(name: string) { return { src: config.templates[name], path: `/config/templates/${name}`, @@ -46,7 +49,7 @@ async function getEnv(cwd: string = process.cwd()): Promise { + env.addGlobal('showPkg', (pkg: Pkg) => { const name = templatingConfig.use_short_names ? pkg.shortName : pkg.name return `**${name}@${pkg.version}**` @@ -95,13 +98,13 @@ async function getEnv(cwd: string = process.cwd()): Promise { - return list.map(item => item[id]) + return list.map((item: any) => item[id]) }) env.addFilter('toArray', arr => { return Array.from(arr) }) env.addFilter('ul', (list, symbol = '•') => { - return list.map(item => `${symbol} ${item}`).join('\n') + return list.map((item: string) => `${symbol} ${item}`).join('\n') }) env.addFilter('wrap', (t, wrap) => { if (Array.isArray(t)) { diff --git a/packages/pvm/mechanics/template/index.ts b/packages/pvm/mechanics/template/index.ts new file mode 100644 index 000000000..9a470c66a --- /dev/null +++ b/packages/pvm/mechanics/template/index.ts @@ -0,0 +1,9 @@ +import { mema } from '../../lib/memoize' +import getTemplateEnv from './env' +import { compile } from 'nunjucks' +import type { Config } from '../../types' + +export const lazyCompileTemplate = mema(async (config: Config, text: string) => { + const templateEnv = await getTemplateEnv(config) + return compile(text, templateEnv) +}) diff --git a/packages/pvm-template/lib/require-setup-script.ts b/packages/pvm/mechanics/template/require-setup-script.ts similarity index 76% rename from packages/pvm-template/lib/require-setup-script.ts rename to packages/pvm/mechanics/template/require-setup-script.ts index f2db89235..5e0124265 100644 --- a/packages/pvm-template/lib/require-setup-script.ts +++ b/packages/pvm/mechanics/template/require-setup-script.ts @@ -1,7 +1,7 @@ import resolveFrom from 'resolve-from' -import { requireDefault } from '@pvm/core/lib' +import { requireDefault } from '../../lib/interop' -function resolveScript(setupScript) { +function resolveScript(setupScript: string) { const resolvedSetupScript = resolveFrom(process.cwd(), setupScript) const setupFn = requireDefault(resolvedSetupScript) if (typeof setupFn !== 'function') { diff --git a/packages/pvm-update/lib/changed-context.ts b/packages/pvm/mechanics/update/changed-context.ts similarity index 82% rename from packages/pvm-update/lib/changed-context.ts rename to packages/pvm/mechanics/update/changed-context.ts index b5e110c27..9832969c5 100644 --- a/packages/pvm-update/lib/changed-context.ts +++ b/packages/pvm/mechanics/update/changed-context.ts @@ -1,13 +1,13 @@ -import gitCommits from '@pvm/core/lib/git/commits' -import { ImmutablePkgSet } from '@pvm/core/lib/pkg-set' -import { pkgsetFromChangedFiles } from '@pvm/pkgset/lib/from-changed-files' -import { pkgsetFromRef } from '@pvm/pkgset/lib/pkgset-from-ref' -import { pkgCommits } from '@pvm/core/lib/git/pkg-commits' - -import type { Config } from '@pvm/core/lib/config' -import type { IncludeRootOption } from '@pvm/pkgset/types' -import type { Commit } from '@pvm/types' -import type { ChangedFiles } from '@pvm/pkgset/lib/changed-files' +import gitCommits from '../../lib/git/commits' +import { ImmutablePkgSet } from '../../lib/pkg-set' +import { pkgsetFromChangedFiles } from '../pkgset/from-changed-files' +import { pkgsetFromRef } from '../pkgset/pkgset-from-ref' +import { pkgCommits } from '../../lib/git/pkg-commits' + +import type { Config, Commit } from '../../types' +import type { IncludeRootOption } from '../pkgset/types' + +import type { ChangedFiles } from '../pkgset/changed-files' /** * Отвечает на вопросы что поменялось (файлы, пакеты) и за какой период истории git'а это произошло. diff --git a/packages/pvm-update/lib/dependants-updater.ts b/packages/pvm/mechanics/update/dependants-updater.ts similarity index 91% rename from packages/pvm-update/lib/dependants-updater.ts rename to packages/pvm/mechanics/update/dependants-updater.ts index 35b52cad3..ee7067cfe 100644 --- a/packages/pvm-update/lib/dependants-updater.ts +++ b/packages/pvm/mechanics/update/dependants-updater.ts @@ -1,13 +1,13 @@ import semver from 'semver' -import { matchAny, matchGroup } from '@pvm/core/lib/pkg-match' -import sortByRelease from '@pvm/core/lib/packages/sort-by-release' -import { loggerFor } from '@pvm/core/lib/logger' -import { releaseTypes as releaseTypesMath } from '@pvm/core/lib/semver-extra' +import { matchAny, matchGroup } from '../../lib/pkg-match' +import sortByRelease from '../../lib/packages/sort-by-release' +import { loggerFor } from '../../lib/logger' +import { releaseTypes as releaseTypesMath } from '../../lib/semver-extra' import { UpdateReasonType } from './update-state' -import type { Pkg } from '@pvm/core/lib/pkg' -import type { PvmReleaseType, SemverReleaseType } from '@pvm/types' -import type { Repository } from '@pvm/repository/lib/repository' +import type { Pkg } from '../../lib/pkg' +import type { PvmReleaseType, SemverReleaseType } from '../../types' +import type { Repository } from '../repository' import type { UpdateState } from './update-state' import { decreaseReleaseTypeForPackagesWithZeroMajorVersion } from './pkg-release-type' diff --git a/packages/pvm-update/lib/enrich-from-hints.ts b/packages/pvm/mechanics/update/enrich-from-hints.ts similarity index 60% rename from packages/pvm-update/lib/enrich-from-hints.ts rename to packages/pvm/mechanics/update/enrich-from-hints.ts index b49ca40a4..db19a07e3 100644 --- a/packages/pvm-update/lib/enrich-from-hints.ts +++ b/packages/pvm/mechanics/update/enrich-from-hints.ts @@ -1,16 +1,19 @@ -import { log, debug } from '@pvm/core/lib/logger' -import { matchAny } from '@pvm/core/lib/pkg-match' -import gitLog from '@pvm/core/lib/git/log' -import { getHostApi } from '@pvm/core/lib/plugins' +import { log, logger } from '../../lib/logger' +import { matchAny } from '../../lib/pkg-match' +import gitLog from '../../lib/git/log' import { processAffectedByDependants } from './dependants-updater' -import { PkgSet } from '@pvm/core/lib/pkg-set' +import { PkgSet } from '../../lib/pkg-set' -import type { Pkg } from '@pvm/core/lib/pkg' +import type { Container } from '../../lib/di' +import type { Pkg } from '../../lib/pkg' import type { UpdateState } from './update-state' -import type { Repository } from '@pvm/repository/lib' -import type { ForceReleaseState } from '../types' +import type { Repository } from '../repository' +import type { ForceReleaseState } from './types' +import { CWD_TOKEN, HOST_API_TOKEN } from '../../tokens' -async function releaseNotesByFile(cwd: string, filePath: string, defaultMessage: string): Promise { +async function releaseNotesByFile(di: Container, filePath: string, defaultMessage: string): Promise { + const cwd = di.get(CWD_TOKEN) + const hostApi = di.get(HOST_API_TOKEN) const latestCommits = await gitLog({ _: [filePath], 'no-merges': true, @@ -19,31 +22,29 @@ async function releaseNotesByFile(cwd: string, filePath: string, defaultMessage: if (latestCommits.length === 0) { return defaultMessage } - const hostApi = await getHostApi(cwd) return hostApi.commitsToNotes(latestCommits) } // could add new packages from hints['force-release'] directive -async function processForceRelease(updateState: UpdateState): Promise { +async function processForceRelease(di: Container, updateState: UpdateState): Promise { const packages = new PkgSet() - const { cwd } = updateState.repo const { hints } = updateState.updateContext const { changedContext } = updateState const forceRelease = hints['force-release'] if (forceRelease) { const { packages: packagesMasks = [] } = forceRelease - debug(`found force-release record, packages mask:`, packagesMasks) + logger.debug(`found force-release record, packages mask:`, packagesMasks) const defaultReleaseNotes = 'force release by update-hints.toml' - const releaseNotes = forceRelease['release-notes'] || await releaseNotesByFile(cwd, 'update-hints.toml', defaultReleaseNotes) + const releaseNotes = forceRelease['release-notes'] || (await releaseNotesByFile(di, 'update-hints.toml', defaultReleaseNotes)) - debug('already changed packages:', Array.from(changedContext.packages.keys())) + logger.debug('already changed packages:', Array.from(changedContext.packages.keys())) const allPackages = updateState.repo.packagesMaybeWithRoot for (const pkg of allPackages) { if (!changedContext.packages.has(pkg.name) && matchAny(pkg, packagesMasks)) { - debug(`force release ${pkg.name}`) + logger.debug(`force release ${pkg.name}`) updateState.releaseNotes.set(pkg, releaseNotes) packages.add(pkg) } @@ -65,7 +66,7 @@ async function enrichByDependants(repo: Repository, updateState: UpdateState, pa const { hints } = updateState.updateContext if (hints['update-dependants-for']) { log(`update dependants`) - debug(`final update dependants config:\n${JSON.stringify(hints['update-dependants-for'], null, 2)}`) + logger.debug(`final update dependants config:\n${JSON.stringify(hints['update-dependants-for'], null, 2)}`) return processAffectedByDependants(repo, updateState, packages) } diff --git a/packages/pvm-update/lib/index.ts b/packages/pvm/mechanics/update/index.ts similarity index 78% rename from packages/pvm-update/lib/index.ts rename to packages/pvm/mechanics/update/index.ts index bba435f7f..2401967e9 100644 --- a/packages/pvm-update/lib/index.ts +++ b/packages/pvm/mechanics/update/index.ts @@ -2,26 +2,30 @@ import semver from 'semver' import chalk from 'chalk' import { processForceRelease, enrichByDependants } from './enrich-from-hints' import getUpdateContext from './update-context' -import { debug, log, logger } from '@pvm/core/lib/logger' +import { log, logger } from '../../lib/logger' import * as makeRelease from './update-methods/release' import type { SinceLastReleaseOpts } from './strategies/since-last-release' import sinceLastRelease from './strategies/since-last-release' import { markReleaseType } from './pkg-release-type' import { createReleaseContext } from './release/release-context' -import { Repository } from '@pvm/repository/lib/repository' +import { Repository } from '../repository' import { UpdateReasonType, UpdateState } from './update-state' -import { vcsInitForUpdate } from './vcs-init' -import getConfig from '@pvm/core/lib/config/get-config' -import getTemplateEnv from '@pvm/template' -import { Notificator } from '@pvm/notifications' - -import type { Pkg } from '@pvm/core/lib/pkg' -import type { ReleaseContext, ForceReleaseState, UpdateMethod, CliUpdateOpts } from '../types' -import type { PvmReleaseType } from '@pvm/types' +import getTemplateEnv from '../template/env' + +import type { Pkg } from '../../lib/pkg' +import type { ReleaseContext, ForceReleaseState, UpdateMethod, CliUpdateOpts } from './types' +import type { PushError, PvmReleaseType } from '../../types' import type { ChangedContext } from './changed-context' +import type { Container } from '../../lib/di' -import { env } from '@pvm/core/lib/env' +import { env } from '../../lib/env' +import { + CONFIG_TOKEN, + CWD_TOKEN, NOTIFICATOR_TOKEN, + VCS_PLATFORM_FACTORY_TOKEN, + VCS_PLATFORM_TOKEN, +} from '../../tokens' async function markReleaseTypes(updateState: UpdateState, forceReleaseState: ForceReleaseState): Promise { let packagesForMark = updateState.changedContext.packages @@ -46,10 +50,10 @@ async function generateNotes(updateState: UpdateState): Promise { for (const pkg of packages) { const commits = await updateState.changedContext.pkgCommitsFor(pkg.name) if (commits && commits.length) { - debug(`(${pkg.name}) generate release notes`) + logger.debug(`(${pkg.name}) generate release notes`) const md = await hostApi.commitsToNotes(commits, pkg) - debug(`release notes for ${pkg.name}:\n${md.substr(0, 100)}..`) + logger.debug(`release notes for ${pkg.name}:\n${md.substr(0, 100)}..`) updateState.releaseNotes.set(pkg, md) } } @@ -59,8 +63,8 @@ export interface MakeUpdateStateOptions { readonly?: boolean, } -async function makeUpdateState(changedContext: ChangedContext, opts: MakeUpdateStateOptions = {}): Promise { - const repo = await Repository.init(changedContext.changedFiles.cwd, { +async function makeUpdateState(di: Container, changedContext: ChangedContext, opts: MakeUpdateStateOptions = {}): Promise { + const repo = await Repository.init(di, { ref: changedContext.targetLoadRef, }) @@ -76,7 +80,7 @@ async function makeUpdateState(changedContext: ChangedContext, opts: MakeUpdateS await generateNotes(updateState) } - const forceReleaseState = await processForceRelease(updateState) + const forceReleaseState = await processForceRelease(di, updateState) // Выставляем релизные типы на основе факта изменений пакетов и других условий await markReleaseTypes(updateState, forceReleaseState) @@ -114,16 +118,16 @@ export interface GetUpdateStateOpts extends SinceLastReleaseOpts { targetRef?: string, } -async function getUpdateState(opts: GetUpdateStateOpts = {}): Promise { - const cwd = opts.cwd || process.cwd() // @TODO: задепрекейтить process.cwd() здесь +async function getUpdateState(di: Container, opts: GetUpdateStateOpts = {}): Promise { + const cwd = opts.cwd || di.get(CWD_TOKEN)// @TODO: задепрекейтить process.cwd() здесь const { targetRef = 'HEAD' } = opts - const changedContext = await sinceLastRelease(targetRef, { + const changedContext = await sinceLastRelease(di, targetRef, { ...opts, cwd, }) - return await makeUpdateState(changedContext, { readonly: opts.readonly }) + return await makeUpdateState(di, changedContext, { readonly: opts.readonly }) } function printPackagesLimited(pkgList: Iterable, maxLength = 45): string { @@ -202,28 +206,28 @@ interface MakeReleaseContextOpts { cwd?: string, } -async function makeReleaseContext(targetRef: string | undefined = void 0, opts: MakeReleaseContextOpts = {}): Promise { - return createReleaseContext(await getUpdateState({ +async function makeReleaseContext(di: Container, targetRef: string | undefined = void 0, opts: MakeReleaseContextOpts = {}): Promise { + return createReleaseContext(await getUpdateState(di, { ...opts, targetRef, })) } -async function updateWithVcsRetry(updateMethod: UpdateMethod, opts: CliUpdateOpts | undefined = void 0): Promise { - const config = await getConfig(opts?.cwd) +async function updateWithVcsRetry(di: Container, updateMethod: UpdateMethod, opts: CliUpdateOpts | undefined = void 0): Promise { + const config = di.get(CONFIG_TOKEN) const { commit_via_platform, retry_via_platform_if_failed_via_vcs = true } = config.update const dryRun = opts?.dryRun || false try { - return await update(updateMethod, opts) - } catch (e) { - if (e.context === 'push' && !commit_via_platform && retry_via_platform_if_failed_via_vcs) { + return await update(di, updateMethod, opts) + } catch (e: any) { + if ((e as PushError).context === 'push' && !commit_via_platform && retry_via_platform_if_failed_via_vcs) { logger.warn(`PVM has failed to push a release commit via git:\n${e.message}\n Retrying release attempt using platform api now!`) - const templateEnv = await getTemplateEnv() + const templateEnv = await getTemplateEnv(config) const notifyMessage = templateEnv.render('failed_vcs_push', { CI_PIPELINE_URL: env.CI_PIPELINE_URL, }) if (!dryRun) { - const messenger = await Notificator.create(config.cwd) + const messenger = di.get(NOTIFICATOR_TOKEN) await messenger.sendMessage({ content: notifyMessage, attachments: [ @@ -238,7 +242,7 @@ async function updateWithVcsRetry(updateMethod: UpdateMethod, opts: CliUpd } // попытка номер два, запушить через платформу // @ts-ignore @TODO: упростить метод update с точки зрения типов, убрать генерик на опции - return await update(updateMethod, { + return await update(di, updateMethod, { ...opts, vcsMode: 'platform', }) @@ -248,29 +252,31 @@ async function updateWithVcsRetry(updateMethod: UpdateMethod, opts: CliUpd } } -async function update(updateMethod: UpdateMethod, opts: CliUpdateOpts = {}): Promise { +async function update(di: Container, updateMethod: UpdateMethod, opts: CliUpdateOpts = {}): Promise { // @ts-ignore if (opts && opts.dryRun) { log(chalk`{yellowBright DRY RUN}`) } - const config = await getConfig(opts?.cwd) + const config = di.get(CONFIG_TOKEN) - const vcs = await vcsInitForUpdate({ - ...opts, - cwd: config.cwd, - }) + let vcsPlatform + if (opts.vcsMode) { + vcsPlatform = di.get(VCS_PLATFORM_FACTORY_TOKEN)({ vcsMode: opts.vcsMode }) + } else { + vcsPlatform = di.get(VCS_PLATFORM_TOKEN) + } if (updateMethod.prepare) { - await updateMethod.prepare(config, vcs) + await updateMethod.prepare(di, vcsPlatform) } - const updateState = await getUpdateState({ cwd: config.cwd }) - return updateMethod.run(updateState, vcs, opts) + const updateState = await getUpdateState(di, { cwd: config.cwd }) + return updateMethod.run(di, updateState, vcsPlatform, opts) } -function release(): ReturnType { - return updateWithVcsRetry(makeRelease, void 0) +function release(di: Container): ReturnType { + return updateWithVcsRetry(di, makeRelease, void 0) } export { diff --git a/packages/pvm-update/lib/pkg-release-type.ts b/packages/pvm/mechanics/update/pkg-release-type.ts similarity index 89% rename from packages/pvm-update/lib/pkg-release-type.ts rename to packages/pvm/mechanics/update/pkg-release-type.ts index 5936caaff..ac8923a8f 100644 --- a/packages/pvm-update/lib/pkg-release-type.ts +++ b/packages/pvm/mechanics/update/pkg-release-type.ts @@ -1,21 +1,21 @@ import fs from 'fs' import path from 'path' import micromatch from 'micromatch' -import { logger } from '@pvm/core/lib/logger' -import { matchGroup } from '@pvm/core/lib/pkg-match' -import { releaseTypesInAscendingOrder, releaseTypes } from '@pvm/core/lib/semver-extra' +import { logger } from '../../lib/logger' +import { matchGroup } from '../../lib/pkg-match' +import { releaseTypesInAscendingOrder, releaseTypes } from '../../lib/semver-extra' import { UpdateReasonType } from './update-state' -import type { PvmReleaseType } from '@pvm/types' -import type { Pkg } from '@pvm/core/lib/pkg' -import type { ForceReleaseState } from '../types' +import type { PvmReleaseType } from '../../types' +import type { Pkg } from '../../lib/pkg' +import type { ForceReleaseState } from './types' import type { UpdateState } from './update-state' -const fileReleaseAliases = { +const fileReleaseAliases: Record = { skip: 'none', } -const releaseTypesInDescOrderWithAliases: string[] = [...releaseTypesInAscendingOrder] +const releaseTypesInDescOrderWithAliases = [...releaseTypesInAscendingOrder] .reverse() // @ts-ignore .concat(Object.keys(fileReleaseAliases)) @@ -92,12 +92,12 @@ export async function markReleaseType(pkg: Pkg, updateState: UpdateState, opts: } if (!releaseType && updateConfig.workspace_release_files) { - const updated = releaseTypesInDescOrderWithAliases.some(fileName => { - const releaseFile = path.join(pkg.absPath, fileName) + const updated = releaseTypesInDescOrderWithAliases.some(releaseFileName => { + const releaseFile = path.join(pkg.absPath, releaseFileName) if (fs.existsSync(releaseFile)) { - releaseType = fileReleaseAliases[fileName] || fileName + releaseType = fileReleaseAliases[releaseFileName] || releaseFileName - updateState.releaseFilesMap.set(pkg, fileName) + updateState.releaseFilesMap.set(pkg, releaseFileName) return true } return false diff --git a/packages/pvm-update/lib/release-name.ts b/packages/pvm/mechanics/update/release-name.ts similarity index 93% rename from packages/pvm-update/lib/release-name.ts rename to packages/pvm/mechanics/update/release-name.ts index ea6aa175d..69dd78f0a 100644 --- a/packages/pvm-update/lib/release-name.ts +++ b/packages/pvm/mechanics/update/release-name.ts @@ -1,11 +1,13 @@ +// @ts-ignore import shuffleSeed from 'shuffle-seed' import formatDate from 'date-fns/format' +// @ts-ignore import uniq from 'uniq' -import dateNow from '@pvm/core/lib/now' -import { lastReleaseTag } from '@pvm/core/lib/git/last-release-tag' -import type { Config } from '@pvm/core/lib/config' -import { log } from '@pvm/core/lib/logger' -import { wdShell } from '@pvm/core/lib/shell' +import dateNow from '../../lib/now' +import { lastReleaseTag } from '../../lib/git/last-release-tag' +import type { Config } from '../../types' +import { log } from '../../lib/logger' +import { wdShell } from '../../lib/shell' import resolveWords from './resolve-words' function rotate(arr: ReadonlyArray, n: number): T[] { @@ -28,7 +30,7 @@ function takeNextSuffix(cwd: string, words: string[], prevWord: string | null, g const rotatedWords = rotate(words, suffixIndex) let rotatedIndex = 0 - let suffix + let suffix: string = rotatedWords[rotatedIndex] let found = false while (rotatedIndex < rotatedWords.length) { suffix = rotatedWords[rotatedIndex++] diff --git a/packages/pvm-update/lib/release/prepare.ts b/packages/pvm/mechanics/update/release/prepare.ts similarity index 55% rename from packages/pvm-update/lib/release/prepare.ts rename to packages/pvm/mechanics/update/release/prepare.ts index 9b9713577..5611f7c28 100644 --- a/packages/pvm-update/lib/release/prepare.ts +++ b/packages/pvm/mechanics/update/release/prepare.ts @@ -1,15 +1,14 @@ -import { logger } from '@pvm/core/lib/logger' -import { Repository } from '@pvm/repository' -import { lint } from '@pvm/repository/lib/linter' +import { logger } from '../../../lib/logger' +import { lint } from '../../repository/linter' /* import { upconf } from '@pvm/repository/lib/upconf/upconf' */ -import { getConfig } from '@pvm/core/lib/config' -import type { Config } from '@pvm/core/lib/config/types' +import type { Container } from '../../../lib/di' +import { CONFIG_TOKEN, REPOSITORY_FACTORY_TOKEN } from '../../../tokens' /* import type { Vcs } from '@pvm/vcs' */ -async function autolint(config: Config) { +async function autolint(di: Container) { logger.info('update.autolint is enabled, linting and fix if necessary packages before update..') - const repo = new Repository(config.cwd, config) + const repo = di.get(REPOSITORY_FACTORY_TOKEN)() const lintResult = lint(repo, { fix: true, index: true, @@ -22,12 +21,12 @@ async function autolint(config: Config) { } } -async function prepare(config: Config/*, vcs: Vcs */) { +async function prepare(di: Container/*, vcs: Vcs */) { // await upconf(vcs) // after upconf we should refetch config - config = await getConfig(config.cwd) + const config = di.get(CONFIG_TOKEN) if (config.update.autolint) { - await autolint(config) + await autolint(di) } } diff --git a/packages/pvm-update/lib/release/release-context.ts b/packages/pvm/mechanics/update/release/release-context.ts similarity index 92% rename from packages/pvm-update/lib/release/release-context.ts rename to packages/pvm/mechanics/update/release/release-context.ts index 1ffd07e1c..8c1262719 100644 --- a/packages/pvm-update/lib/release/release-context.ts +++ b/packages/pvm/mechanics/update/release/release-context.ts @@ -1,14 +1,14 @@ import { calcGenericTagName, addSuffixToSemverTagName } from '../release-name' -import { semverTag, isGenericTagUsed } from '@pvm/core/lib/tag-meta' -import { takeFirstSync } from '@pvm/core/lib/iter' -import { noPackagesInMugError } from '@pvm/core/lib/behaviors/no-packages-in-mug' +import { semverTag, isGenericTagUsed } from '../../../lib/tag-meta' +import { takeFirstSync } from '../../../lib/iter' +import { noPackagesInMugError } from '../../../lib/behaviors/no-packages-in-mug' -import type { ReleaseContext } from '../../types' -import type { Pkg, AppliedPkg } from '@pvm/core/lib/pkg' +import type { ReleaseContext } from '../types' +import type { Pkg, AppliedPkg } from '../../../lib/pkg' import type { UpdateState } from '../update-state' -import type { Repository } from '@pvm/repository' +import type { Repository } from '../../repository' import chalk from 'chalk' -import { loggerFor } from '@pvm/core/lib/logger' +import { loggerFor } from '../../../lib/logger' const logger = loggerFor('pvm:release-context') diff --git a/packages/pvm-update/lib/release/updater.ts b/packages/pvm/mechanics/update/release/updater.ts similarity index 74% rename from packages/pvm-update/lib/release/updater.ts rename to packages/pvm/mechanics/update/release/updater.ts index 670fffff2..fb22df75c 100644 --- a/packages/pvm-update/lib/release/updater.ts +++ b/packages/pvm/mechanics/update/release/updater.ts @@ -3,33 +3,32 @@ import path from 'path' import ignore from 'ignore' import fs from 'fs' -import { pprintPackages } from '@pvm/core/lib/utils/pprint' -import { makeTagForPkg } from '@pvm/core/lib/tag-meta' -import { enpl } from '@pvm/core/lib/text/plural' -import { loggerFor } from '@pvm/core/lib/logger' -import { wdShell } from '@pvm/core/lib/shell' -import { getConfig } from '@pvm/core/lib/config' -import { releaseMark } from '@pvm/core/lib/consts' -import { getHostApi } from '@pvm/core/lib/plugins' -import { getStagedFiles, revParse } from '@pvm/core/lib/git/commands' -import { versioningFile } from '@pvm/core/lib/dedicated-versions-file' -import { releaseDataMaker } from '@pvm/releases/lib/release-data' -import { fsAppendReleaseData } from '@pvm/releases/lib/release-list' -import { StorageManager } from '@pvm/artifacts/lib/storage-manager' -import initVcs from '@pvm/vcs' - -import getTemplateEnv from '@pvm/template/lib/env' -import { makeChangelog } from '@pvm/changelog/lib' +import { pprintPackages } from '../../../lib/utils/pprint' +import { makeTagForPkg } from '../../../lib/tag-meta' +import { enpl } from '../../../lib/text/plural' +import { loggerFor } from '../../../lib/logger' +import { wdShell } from '../../../lib/shell' +import { releaseMark } from '../../../lib/consts' +import { getStagedFiles, revParse } from '../../../lib/git/commands' +import { versioningFile } from '../../../lib/dedicated-versions-file' +import { releaseDataMaker } from '../../releases/release-data' +import { fsAppendReleaseData } from '../../releases/release-list' +import { StorageManager } from '../../artifacts/storage-manager' + +import getTemplateEnv from '../../template/env' +import { makeChangelog } from '../../changelog' import { createReleaseContext } from './release-context' -import type { ReleaseContext } from '../../types' +import type { ReleaseContext, CliUpdateOpts } from '../types' import type { UpdateState } from '../update-state' -import type { VcsPlatform } from '@pvm/vcs/lib/vcs' -import type { Vcs } from '@pvm/vcs' -import type { CliUpdateOpts } from '../../types/cli' -import type{ ReleaseData } from '@pvm/releases/types' -import type{ Config } from '@pvm/core/lib/config' +import type { VcsPlatform } from '../../vcs' + +import type{ ReleaseData } from '../../releases/types' +import type{ Config } from '../../../types' +import type { Container } from '../../../lib/di' +import { CONFIG_TOKEN, GLOBAL_FLAGS_TOKEN, HOST_API_TOKEN, PLATFORM_TOKEN, VCS_PLATFORM_TOKEN } from '../../../tokens' +import type { PlatformInterface } from '../../platform' const logger = loggerFor('pvm:update') @@ -40,7 +39,7 @@ export interface ReleaseOpts extends CliUpdateOpts { vcsMode?: 'vcs' | 'platform', } -export async function release(updateState: UpdateState, vcsPlatform: Vcs, initialOpts: ReleaseOpts = {}): Promise { +export async function release(di: Container, updateState: UpdateState, vcsPlatform: VcsPlatform, initialOpts: ReleaseOpts = {}): Promise { const { targetRef } = updateState.changedContext const { config } = updateState.repo const releaseConf = config.release @@ -68,9 +67,9 @@ export async function release(updateState: UpdateState, vcsPlatform: Vcs, initia const releaseContext = await createReleaseContext(updateState) if (releaseContext) { - await runPluginPreReleaseHooks(config.cwd, vcsPlatform, releaseContext) - const { storageManager, releaseData } = await prepareStoreManagerAndReleaseData(config, releaseContext, vcsPlatform, opts) - await updateReleaseAndChangelogArtifacts(config, storageManager, releaseData) + await di.get(HOST_API_TOKEN).preReleaseHook(vcsPlatform, releaseContext) + const { storageManager, releaseData } = await prepareStoreManagerAndReleaseData(di, releaseContext) + await updateReleaseAndChangelogArtifacts(di, storageManager, releaseData) saveReleaseDataLocally(config.cwd, opts, releaseData) if (!tagOnly) { await updatePackages(vcsPlatform, updateState) @@ -79,10 +78,10 @@ export async function release(updateState: UpdateState, vcsPlatform: Vcs, initia // Ссылка на релиз либо от коммита который получен в результате пуша наработанных коммитов либо это целевая ссылка // если коммитить нечего - const releaseRef = (await conditionallyPushChanges(updateState, vcsPlatform, opts)) ?? calculateReleaseRef(config.cwd, targetRef) + const releaseRef = (await conditionallyPushChanges(di, updateState, vcsPlatform, opts)) ?? calculateReleaseRef(config.cwd, targetRef) if (releaseContext) { - await createRelease(vcsPlatform, releaseRef, updateState, releaseContext) + await createRelease(vcsPlatform, di.get(PLATFORM_TOKEN), releaseRef, updateState, releaseContext) } } catch (e) { await vcsPlatform.rollbackCommit(commitContext) @@ -130,18 +129,12 @@ async function removeWorkspaceReleaseFiles(updateState: UpdateState, vcsPlatform } } -async function runPluginPreReleaseHooks(cwd: string, vcsPlatform: VcsPlatform, releaseContext: ReleaseContext): Promise { - const hostApi = await getHostApi(cwd) - await hostApi.preReleaseHook(vcsPlatform, releaseContext) -} - -async function prepareStoreManagerAndReleaseData(config: Config, releaseContext: ReleaseContext, vcsPlatform: VcsPlatform, { dryRun, local, tagOnly }: ReleaseOpts): Promise<{ +async function prepareStoreManagerAndReleaseData(di: Container, releaseContext: ReleaseContext): Promise<{ releaseData?: ReleaseData, storageManager: StorageManager, }> { const storageManager = new StorageManager({ - config, - vcs: tagOnly || dryRun ? await initVcs({ vcsType: 'fs', cwd: config.cwd, localMode: local, dryRun: dryRun }) : vcsPlatform, + di, }) const releaseData = await releaseDataMaker.fromReleaseContext(releaseContext) @@ -152,7 +145,7 @@ async function prepareStoreManagerAndReleaseData(config: Config, releaseContext: } } -async function updateReleaseAndChangelogArtifacts(config: Config, storageManager: StorageManager, releaseData?: ReleaseData): Promise { +async function updateReleaseAndChangelogArtifacts(di: Container, storageManager: StorageManager, releaseData?: ReleaseData): Promise { // 1. Download ReleaseList artifact // 2. Update ReleaseList and apply limits // 3. Upload ReleaseList artifact @@ -162,12 +155,14 @@ async function updateReleaseAndChangelogArtifacts(config: Config, storageManager // 5. CHANGELOG. incremental: NOOP, single-pass: Render ReleaseList // 6. UPDATE only: upload ReleaseList, Changelogs artifacts + const config = di.get(CONFIG_TOKEN) + const dryRun = di.get(GLOBAL_FLAGS_TOKEN).getFlag('dryRun') const releaseListStorage = await storageManager.initFor(StorageManager.ArtifactsStorages.ReleaseList) if (config.release_list.enabled && releaseData) { await releaseListStorage.download() - fsAppendReleaseData(config, releaseData) + fsAppendReleaseData(config, releaseData, dryRun) await releaseListStorage.upload() } @@ -178,7 +173,7 @@ async function updateReleaseAndChangelogArtifacts(config: Config, storageManager if ((changelogConfig.enabled || changelogConfig.for_packages.enabled) && releaseData) { await changelogsStorage.download() - await makeChangelog(config, releaseData) + await makeChangelog(di, releaseData) await changelogsStorage.upload() } @@ -203,11 +198,11 @@ function calculateReleaseRef(cwd: string, targetRef: string): string { return revParse(targetRef, cwd) } -async function conditionallyPushChanges(updateState: UpdateState, vcsPlatform: VcsPlatform, { local, tagOnly, vcsMode }: ReleaseOpts): Promise { +async function conditionallyPushChanges(di: Container, updateState: UpdateState, vcsPlatform: VcsPlatform, { local, tagOnly, vcsMode }: ReleaseOpts): Promise { const { targetRef } = updateState.changedContext if (!local) { - await checkBranchActual(vcsPlatform, targetRef) + await checkBranchActual(di, targetRef) } if (vcsPlatform.isSomethingForCommit()) { @@ -223,7 +218,7 @@ async function conditionallyPushChanges(updateState: UpdateState, vcsPlatform: V throw e } - return await pushChanges(vcsPlatform, updateState) + return await pushChanges(di, vcsPlatform, updateState) } } else { vcsPlatform.resetCommitContext() @@ -231,24 +226,28 @@ async function conditionallyPushChanges(updateState: UpdateState, vcsPlatform: V } } -async function checkBranchActual(vcs: VcsPlatform, targetRef: string): Promise { - const config = await getConfig(vcs.cwd) +async function checkBranchActual(di: Container, targetRef: string): Promise { + const config = di.get(CONFIG_TOKEN) + const vcs = di.get(VCS_PLATFORM_TOKEN) + const platform = di.get(PLATFORM_TOKEN) const releaseOpts = config.release - const maybeCurrentBranch = vcs.getCurrentBranch() + const maybeCurrentBranch = platform.getCurrentBranch() if (releaseOpts.ensure_branch_up_to_date && maybeCurrentBranch) { // before pushing changes, check for upstream branch is still actual debug(`checking ${maybeCurrentBranch} is still actual`) - if (!await vcs.isRefMatchesRemoteBranch(targetRef, maybeCurrentBranch)) { + if (!(await vcs.isRefMatchesRemoteBranch(targetRef, maybeCurrentBranch))) { throw new Error(`${maybeCurrentBranch} has updated in the middle of updating packages, exiting`) } } } // метод делает коммит с обновлением версий -async function pushChanges(vcs: VcsPlatform, updateState: UpdateState): Promise { - const templateEnv = await getTemplateEnv() +async function pushChanges(di: Container, vcs: VcsPlatform, updateState: UpdateState): Promise { + const templateEnv = await getTemplateEnv(di.get(CONFIG_TOKEN)) + const platform = di.get(PLATFORM_TOKEN) + const dryRun = di.get(GLOBAL_FLAGS_TOKEN).getFlag('dryRun') let commitMessage = templateEnv.render('release-commit', { packages: updateState.getReleasePackages(), @@ -258,14 +257,14 @@ async function pushChanges(vcs: VcsPlatform, updateState: UpdateState): Promise< commitMessage += `\n\n${releaseMark}` const updCommit = await vcs.commit(commitMessage, { - branch: vcs.getCurrentBranch(), + branch: platform.getCurrentBranch(), }) if (updCommit) { await vcs.push({ remote: updateState.repo.config.update.push_remote, }) - const prefix = vcs.isDryRun ? 'DRY RUN: ' : '' + const prefix = dryRun ? 'DRY RUN: ' : '' logger.info(`${prefix}changes have been committed, sha: ${updCommit.id}`) return updCommit.id @@ -318,7 +317,7 @@ async function updatePackages(vcs: VcsPlatform, updateState: UpdateState): Promi } } -async function createRelease(vcs: VcsPlatform, sha: string, updateState: UpdateState, releaseContext: ReleaseContext): Promise { +async function createRelease(vcs: VcsPlatform, platform: PlatformInterface, sha: string, updateState: UpdateState, releaseContext: ReleaseContext): Promise { const { config } = updateState.repo const { for_packages } = config.tagging @@ -328,7 +327,7 @@ async function createRelease(vcs: VcsPlatform, sha: string, updateState: UpdateS logger.info(chalk`creating release tag {underline ${releaseContext.releaseTag}} on ref:${sha}`) logger.info('tagAnnotation:', releaseContext.tagAnnotation) debug('release-notes:', releaseContext.releaseNotes) - await vcs.addTagAndRelease(sha, releaseContext.releaseTag, { + await platform.addTagAndRelease(sha, releaseContext.releaseTag, { name: releaseContext.name, description: releaseContext.releaseNotes, annotation: releaseContext.tagAnnotation || undefined, @@ -356,7 +355,7 @@ async function createRelease(vcs: VcsPlatform, sha: string, updateState: UpdateS */ let maybePromise if (for_packages.as_release) { - maybePromise = vcs.addTagAndRelease(sha, newTagName, { + maybePromise = platform.addTagAndRelease(sha, newTagName, { name: `${newPkg.name} ${newPkg.version}`, description: updateState.releaseNotes.get(oldPkg) || '', }) diff --git a/packages/pvm-update/lib/resolve-words.ts b/packages/pvm/mechanics/update/resolve-words.ts similarity index 89% rename from packages/pvm-update/lib/resolve-words.ts rename to packages/pvm/mechanics/update/resolve-words.ts index 7fd283146..7d1f31877 100644 --- a/packages/pvm-update/lib/resolve-words.ts +++ b/packages/pvm/mechanics/update/resolve-words.ts @@ -1,5 +1,5 @@ import resolveFrom from 'resolve-from' -import { requireDefault } from '@pvm/core/lib' +import { requireDefault } from '../../lib/interop' function resolveWords(maybeWords: string[] | string): string[] { if (Array.isArray(maybeWords)) { diff --git a/packages/pvm-update/lib/strategies/since-last-release.ts b/packages/pvm/mechanics/update/strategies/since-last-release.ts similarity index 78% rename from packages/pvm-update/lib/strategies/since-last-release.ts rename to packages/pvm/mechanics/update/strategies/since-last-release.ts index d8330bf0a..df4e06179 100644 --- a/packages/pvm-update/lib/strategies/since-last-release.ts +++ b/packages/pvm/mechanics/update/strategies/since-last-release.ts @@ -1,18 +1,18 @@ import fs from 'fs' import path from 'path' -import { loggerFor } from '@pvm/core/lib/logger' -import { getConfig } from '@pvm/core/lib/config' -import __dangerous_shell, { wdShell } from '@pvm/core/lib/shell' -import { lastReleaseTag } from '@pvm/core/lib/git/last-release-tag' -import { changedFiles } from '@pvm/pkgset/lib/changed-files' -import { getCurrentBranchIgnoreEnv, getOldestDescendantCommitRef, gitFetch } from '@pvm/core/lib/git/commands' +import { loggerFor } from '../../../lib/logger' +import { wdShell, shell as __dangerous_shell } from '../../../lib/shell' +import { lastReleaseTag } from '../../../lib/git/last-release-tag' +import { changedFiles } from '../../pkgset/changed-files' +import { getCurrentBranchIgnoreEnv, getOldestDescendantCommitRef, gitFetch } from '../../../lib/git/commands' import { ChangedContext } from '../changed-context' -import type { IncludeRootOption } from '@pvm/pkgset/types' -import type { Config } from '@pvm/core/lib/config' -import initVcsPlatform from '@pvm/vcs' +import type { IncludeRootOption } from '../../pkgset/types' +import type { Config } from '../../../types' +import type { Container } from '../../../lib/di' +import { CONFIG_TOKEN, PLATFORM_TOKEN } from '../../../tokens' const logger = loggerFor('pvm:changed-files') const GIT_DEEPEN_VALUE = 50 @@ -55,23 +55,21 @@ function ensureCommitsDepth(cwd: string, from: string, to: string): void { } // вычисляет последний релиз, и на основе него получаем коммиты и список пакетов на новый релиз -async function sinceLastRelease(targetRef: string, opts: SinceLastReleaseOpts): Promise { - const config = await getConfig(opts.cwd) - const vcsPlatform = await initVcsPlatform({ - cwd: opts.cwd, - }) +async function sinceLastRelease(di: Container, targetRef: string, opts: SinceLastReleaseOpts): Promise { + const config = di.get(CONFIG_TOKEN) + const platform = di.get({ token: PLATFORM_TOKEN, optional: true }) const updConfig = config.update + const cwd = config.cwd const { includeRoot = updConfig.include_root, noReleaseRef: noReleaseRefOpt = updConfig.no_release_ref, includeUncommited = updConfig.include_uncommited, - cwd = process.cwd(), // @TODO: задепрекейтить } = opts const gitShell = (cmd: string) => __dangerous_shell(cmd, { cwd }) - const noReleaseRef = noReleaseRefOpt || getOldestDescendantCommitRef(config.cwd, vcsPlatform.getCurrentBranch() || getCurrentBranchIgnoreEnv(cwd), targetRef) + const noReleaseRef = noReleaseRefOpt || getOldestDescendantCommitRef(config.cwd, platform?.getCurrentBranch() || getCurrentBranchIgnoreEnv(cwd), targetRef) const lastRelease = lastReleaseTag(config, targetRef) diff --git a/packages/pvm-update/types/cli.ts b/packages/pvm/mechanics/update/types/cli.ts similarity index 100% rename from packages/pvm-update/types/cli.ts rename to packages/pvm/mechanics/update/types/cli.ts diff --git a/packages/pvm/mechanics/update/types/index.ts b/packages/pvm/mechanics/update/types/index.ts new file mode 100644 index 000000000..e82cc2cc7 --- /dev/null +++ b/packages/pvm/mechanics/update/types/index.ts @@ -0,0 +1,27 @@ +import type { UpdateState } from '../update-state' +import type { PvmReleaseType } from '../../../types' +import type { ImmutablePkgSet } from '../../../lib/pkg-set' + +import type { VcsPlatform } from '../../../mechanics/vcs' +import type { CliUpdateOpts } from './cli' +import type { Container } from '../../../lib/di' + +export type { CliUpdateOpts, VcsPlatform } + +export interface UpdateMethod { + run(di: Container, updateState: UpdateState, vcs: VcsPlatform, args: CliUpdateOpts): Promise, + prepare?(di: Container, vcs: VcsPlatform): Promise, +} + +export interface ForceReleaseState { + packages: ImmutablePkgSet, + defaultReleaseType?: PvmReleaseType, +} + +export interface ReleaseContext { + name: string, + tagAnnotation: string, + releaseTag: string, + releaseNotes: string, + updateState: UpdateState, +} diff --git a/packages/pvm-update/lib/update-context.ts b/packages/pvm/mechanics/update/update-context.ts similarity index 70% rename from packages/pvm-update/lib/update-context.ts rename to packages/pvm/mechanics/update/update-context.ts index 4f0ffaf59..a5f996fa4 100644 --- a/packages/pvm-update/lib/update-context.ts +++ b/packages/pvm/mechanics/update/update-context.ts @@ -1,5 +1,5 @@ -import type { Repository } from '@pvm/repository/lib' -import type { HintsContext } from '@pvm/repository/lib/repository' +import type { Repository } from '../repository' +import type { HintsContext } from '../repository/repository' // сейчас то же что и HintsContext но возможно расширится в будущем export type UpdateContext = HintsContext diff --git a/packages/pvm-update/lib/update-methods/analyze.ts b/packages/pvm/mechanics/update/update-methods/analyze.ts similarity index 96% rename from packages/pvm-update/lib/update-methods/analyze.ts rename to packages/pvm/mechanics/update/update-methods/analyze.ts index af6290714..cab77f8e5 100644 --- a/packages/pvm-update/lib/update-methods/analyze.ts +++ b/packages/pvm/mechanics/update/update-methods/analyze.ts @@ -1,5 +1,5 @@ import semver from 'semver' -import { PkgSet } from '@pvm/core/lib/pkg-set' +import { PkgSet } from '../../../lib/pkg-set' import type { UpdateState } from '../update-state' interface AnalyzeResult { diff --git a/packages/pvm-update/lib/update-methods/dot.ts b/packages/pvm/mechanics/update/update-methods/dot.ts similarity index 95% rename from packages/pvm-update/lib/update-methods/dot.ts rename to packages/pvm/mechanics/update/update-methods/dot.ts index 4d8284a3d..9c587d8ad 100644 --- a/packages/pvm-update/lib/update-methods/dot.ts +++ b/packages/pvm/mechanics/update/update-methods/dot.ts @@ -1,6 +1,7 @@ import semver from 'semver' -import type { AppliedPkg, Pkg } from '@pvm/core/lib/pkg' +import type { AppliedPkg, Pkg } from '../../../lib/pkg' import type { UpdateState } from '../update-state' +import type { Container } from '../../../lib/di/index' enum DepType { TYPE_NORMAL = 1, @@ -25,7 +26,7 @@ function getLegend(): Legend { getStyleItem(type, flags) { const isDependant = flags & DepType.TYPE_DEPENDANT - const baseStyle = type => { + const baseStyle = (type: string) => { switch (type) { case 'root': return `shape=egg color=green` @@ -162,7 +163,7 @@ digraph p { ) } -async function run(updateState: UpdateState): Promise { +async function run(_di: Container, updateState: UpdateState): Promise { if (updateState.isSomethingForRelease) { return updateStateToDot(updateState) } diff --git a/packages/pvm-update/lib/update-methods/index.ts b/packages/pvm/mechanics/update/update-methods/index.ts similarity index 60% rename from packages/pvm-update/lib/update-methods/index.ts rename to packages/pvm/mechanics/update/update-methods/index.ts index 65febe2d2..468705844 100644 --- a/packages/pvm-update/lib/update-methods/index.ts +++ b/packages/pvm/mechanics/update/update-methods/index.ts @@ -2,8 +2,9 @@ import * as release from './release' import * as dot from './dot' import * as print from './print' import * as mdTable from './md-table' +import type { UpdateMethod } from '../types/index' -export { +export const updateMethods: Record> = { release, dot, print, diff --git a/packages/pvm-update/lib/update-methods/md-table.ts b/packages/pvm/mechanics/update/update-methods/md-table.ts similarity index 61% rename from packages/pvm-update/lib/update-methods/md-table.ts rename to packages/pvm/mechanics/update/update-methods/md-table.ts index aa7e64e0b..921910f07 100644 --- a/packages/pvm-update/lib/update-methods/md-table.ts +++ b/packages/pvm/mechanics/update/update-methods/md-table.ts @@ -1,16 +1,16 @@ -import sortByRelease from '@pvm/core/lib/packages/sort-by-release' +import sortByRelease from '../../../lib/packages/sort-by-release' import { MdUpdatedTable } from '../utils/md-table' import type { UpdateState } from '../update-state' +import { UPDATE_MD_TABLE_EXTEND_TOKEN } from '../../../tokens' +import type { Container } from '../../../lib/di' -export async function run(updateState: UpdateState): Promise { +export async function run(di: Container, updateState: UpdateState): Promise { if (updateState.isSomethingForRelease) { const updatedPackages = updateState.getReleasePackages() const changedPackagesSorted = sortByRelease(updatedPackages.keys(), updateState.getLikelyReleaseTypeFor.bind(updateState)) const table = new MdUpdatedTable() - const hostApi = await updateState.repo.getHostApi() - - await hostApi.plEachSeries('md.table', table) + await di.get({ token: UPDATE_MD_TABLE_EXTEND_TOKEN, optional: true })?.forEach(ext => ext(table)) for (const oldPkg of changedPackagesSorted) { const newPkg = updatedPackages.get(oldPkg)! diff --git a/packages/pvm-update/lib/update-methods/print.ts b/packages/pvm/mechanics/update/update-methods/print.ts similarity index 55% rename from packages/pvm-update/lib/update-methods/print.ts rename to packages/pvm/mechanics/update/update-methods/print.ts index bef0e5359..ec075af8e 100644 --- a/packages/pvm-update/lib/update-methods/print.ts +++ b/packages/pvm/mechanics/update/update-methods/print.ts @@ -1,12 +1,13 @@ -import pprint from '@pvm/pkgset/lib/pprint' +import pprint from '../../pkgset/pprint' import type { UpdateState } from '../update-state' -import type { UpdateMethod, CliUpdateOpts, Vcs } from '../../types' +import type { UpdateMethod, CliUpdateOpts } from '../types' +import type { Container } from '../../../lib/di' async function * iterableToAsyncIterable(it: Iterable): AsyncIterableIterator { return yield * it } -async function print(updateState: UpdateState, _vcs: Vcs, cliOpts: CliUpdateOpts): Promise> { +async function print(_di: Container, updateState: UpdateState, _vcs: any, cliOpts: CliUpdateOpts = {}): Promise> { const { format = '%n' } = cliOpts return pprint(iterableToAsyncIterable(updateState.getReleasePackages().values()), format) diff --git a/packages/pvm-update/lib/update-methods/release.ts b/packages/pvm/mechanics/update/update-methods/release.ts similarity index 100% rename from packages/pvm-update/lib/update-methods/release.ts rename to packages/pvm/mechanics/update/update-methods/release.ts diff --git a/packages/pvm-update/lib/update-state.ts b/packages/pvm/mechanics/update/update-state.ts similarity index 89% rename from packages/pvm-update/lib/update-state.ts rename to packages/pvm/mechanics/update/update-state.ts index fb498d5a0..0912b04e7 100644 --- a/packages/pvm-update/lib/update-state.ts +++ b/packages/pvm/mechanics/update/update-state.ts @@ -1,18 +1,18 @@ import semver from 'semver' -import { releaseTypes } from '@pvm/core/lib/semver-extra' -import { lazyCallee } from '@pvm/core/lib/class-helpers' -import { ImmutablePkgSet, PkgSet } from '@pvm/core/lib/pkg-set' -import getTemplateEnv from '@pvm/template/lib/env' +import { releaseTypes } from '../../lib/semver-extra' +import { lazyCallee } from '../../lib/class-helpers' +import { ImmutablePkgSet, PkgSet } from '../../lib/pkg-set' +import getTemplateEnv from '../template/env' import { decreaseReleaseTypeForPackagesWithZeroMajorVersion } from './pkg-release-type' -import fromGlobPatterns from '@pvm/pkgset/lib/from-glob-patterns' +import fromGlobPatterns from '../pkgset/from-glob-patterns' import type { ChangedContext } from './changed-context' import type { UpdateContext } from './update-context' -import type { Repository } from '@pvm/repository/lib' -import type { Pkg, AppliedPkg } from '@pvm/core/lib/pkg' -import type { PvmReleaseType, SemverReleaseType } from '@pvm/types' +import type { Repository } from '../repository' +import type { Pkg, AppliedPkg } from '../../lib/pkg' +import type { Config, PvmReleaseType, SemverReleaseType } from '../../types' -import { loggerFor } from '@pvm/core/lib/logger' +import { loggerFor } from '../../lib/logger' const logger = loggerFor('pvm:update') @@ -29,14 +29,14 @@ function getMaxVersion(packages: Iterable): string { } function makeProcessingDecorator(onlyInProcessing: boolean) { - return (_target: any, propKey: string, desc: PropertyDescriptor): void => { + return (_target: { _processing: boolean }, propKey: string, desc: PropertyDescriptor): void => { const descKey: 'get' | 'value' = desc.get ? 'get' : 'value' const fn = desc[descKey] if (typeof fn !== 'function') { throw new TypeError(`processing decorator applied on non-function property ${propKey}`) } - desc[descKey] = function(...args: any[]) { + desc[descKey] = function(this: { _processing: boolean }, ...args: any[]) { if (this._processing && !onlyInProcessing) { throw new Error(`Calling method ${propKey} are not allowed while update state under the construction`) } @@ -94,8 +94,8 @@ export class UpdateState { wantedReleaseTypes: Map = new Map() // для каких пакетов надо обновить зависимости исходя из newVersions updateDepsFor: Iterable = new Set() - protected _processing = true - protected _appliedPackages: ImmutablePkgSet + _processing = true + protected _appliedPackages: ImmutablePkgSet | undefined constructor(repo: Repository, changedContext: ChangedContext, updateContext: UpdateContext) { this.repo = repo @@ -204,7 +204,7 @@ export class UpdateState { predefinedDependants: this.updateDepsFor, }) - await addDependantsReleaseNotes(this, this._appliedPackages) + await addDependantsReleaseNotes(this.repo.config, this, this._appliedPackages) this._processing = false return this @@ -233,6 +233,11 @@ export class UpdateState { @lazyCallee getReleasePackages(): Map { const result = new Map() + + if (!this._appliedPackages) { + throw new Error('finalize should be called before') + } + for (const pkg of this.newVersions.keys()) { if (!this.hasSameVersion(pkg)) { result.set(pkg, this._appliedPackages.get(pkg.name)!) @@ -271,10 +276,10 @@ export class UpdateState { } } -async function addDependantsReleaseNotes(updateState: UpdateState, appliedPackages: ImmutablePkgSet): Promise { +async function addDependantsReleaseNotes(config: Config, updateState: UpdateState, appliedPackages: ImmutablePkgSet): Promise { const { repo, changedContext } = updateState const hostApi = await repo.getHostApi() - const templateEnv = await getTemplateEnv(repo.cwd) + const templateEnv = await getTemplateEnv(config) const originReleaseNotes = await hostApi.commitsToNotes(changedContext.commits) diff --git a/packages/pvm-update/lib/utils/md-table.ts b/packages/pvm/mechanics/update/utils/md-table.ts similarity index 97% rename from packages/pvm-update/lib/utils/md-table.ts rename to packages/pvm/mechanics/update/utils/md-table.ts index 5ca51cc44..5b26a4d64 100644 --- a/packages/pvm-update/lib/utils/md-table.ts +++ b/packages/pvm/mechanics/update/utils/md-table.ts @@ -1,7 +1,7 @@ import semver from 'semver' import { UpdateReasonType } from '../update-state' -import type { Pkg } from '@pvm/core/lib/pkg' +import type { Pkg } from '../../../lib/pkg' import type { UpdateState } from '../update-state' export interface ColumnBuilder { title: string, diff --git a/packages/pvm-vcs/lib/__tests__/vcs.spec.ts b/packages/pvm/mechanics/vcs/__tests__/vcs.spec.ts similarity index 56% rename from packages/pvm-vcs/lib/__tests__/vcs.spec.ts rename to packages/pvm/mechanics/vcs/__tests__/vcs.spec.ts index b6abe9c4a..d387edb57 100644 --- a/packages/pvm-vcs/lib/__tests__/vcs.spec.ts +++ b/packages/pvm/mechanics/vcs/__tests__/vcs.spec.ts @@ -1,14 +1,17 @@ -import { initVcsPlatform } from '../vcs' +import initRepo from '../../../../../test/initRepo' +import { VCS_PLATFORM_FACTORY_TOKEN } from '../../../tokens' +import { GlobalFlags } from '../../../lib/cli/global-flags' describe('vcs', () => { it('should rollback commits', async () => { - // @ts-ignore const repo = await initRepo('monorepo-new') + const vcsFactory = repo.di.get(VCS_PLATFORM_FACTORY_TOKEN) - const vcs = await initVcsPlatform({ - localMode: true, + const globalFlags = new GlobalFlags() + globalFlags.setFlag('localMode', true) + const vcs = vcsFactory({ + globalFlags, vcsMode: 'vcs', - cwd: repo.dir, }) const commitContext = await vcs.beginCommit() diff --git a/packages/pvm/mechanics/vcs/decorated-vcs.ts b/packages/pvm/mechanics/vcs/decorated-vcs.ts new file mode 100644 index 000000000..33f393297 --- /dev/null +++ b/packages/pvm/mechanics/vcs/decorated-vcs.ts @@ -0,0 +1,117 @@ +import type { AbstractVcs, AddTagOptions, CommitOptions, CommitResult, PushOptions, PushError } from '../../types' +import type { GlobalFlags } from '../../lib/cli/global-flags' + +import { logDryRun } from '../../lib/utils' + +export class DecoratedVcs implements AbstractVcs { + dryRun: boolean + protected vcs: AbstractVcs + protected localMode: boolean + + constructor({ vcs, globalFlags }: { vcs: AbstractVcs, globalFlags: GlobalFlags}) { + this.vcs = vcs + this.dryRun = globalFlags.getFlag('dryRun') + this.localMode = globalFlags.getFlag('localMode') + } + + @logDryRun + addFiles(commitContext: any, filePaths: string[]): void { + if (this.dryRun) { + return + } + + return this.vcs.addFiles(commitContext, filePaths) + } + + @logDryRun + async addTag(tag_name: string, ref: string, opts: AddTagOptions): Promise { + if (this.dryRun) { + return + } + + return this.vcs.addTag(tag_name, ref, opts) + } + + @logDryRun + appendFile(commitContext: any, filePath: string, content: string): void { + if (this.dryRun) { + return + } + + return this.vcs.appendFile(commitContext, filePath, content) + } + + beginCommit(): any { + return this.vcs.beginCommit() + } + + commit(commitContext: any, message: string, opts?: CommitOptions): Promise { + if (this.dryRun) { + return Promise.resolve({ + id: this.getHeadRev(), + }) + } + + return this.vcs.commit(commitContext, message, opts) + } + + @logDryRun + deleteFile(commitContext: any, file_path: string): void { + if (this.dryRun) { + return + } + + return this.vcs.deleteFile(commitContext, file_path) + } + + fetchLatestSha(refName: string): Promise { + return this.vcs.fetchLatestSha(refName) + } + + getCurrentBranch(): string | void { + return this.vcs.getCurrentBranch() + } + + getHeadRev(): string { + return this.vcs.getHeadRev() + } + + isLastAvailableRef(rev: string): boolean { + return this.vcs.isLastAvailableRef(rev) + } + + @logDryRun + async push(opts?: PushOptions): Promise { + if (this.localMode || this.dryRun) { + return + } + + try { + return this.vcs.push({ + ...opts, + dryRun: this.dryRun, + }) + } catch (e) { + (e as PushError).context = 'push' + throw e + } + } + + @logDryRun + async rollbackCommit(commitContext: any): Promise { + if (this.dryRun) { + return + } + + return this.vcs.rollbackCommit(commitContext) + } + + @logDryRun + updateFile(commitContext: any, file_path: string, content: string): void { + if (this.dryRun) { + return + } + + return this.vcs.updateFile(commitContext, file_path, content) + } +} diff --git a/packages/pvm-vcs-git/ci/git-load-push-creds.sh b/packages/pvm/mechanics/vcs/git-load-push-creds.sh old mode 100755 new mode 100644 similarity index 100% rename from packages/pvm-vcs-git/ci/git-load-push-creds.sh rename to packages/pvm/mechanics/vcs/git-load-push-creds.sh diff --git a/packages/pvm/mechanics/vcs/git-vcs.ts b/packages/pvm/mechanics/vcs/git-vcs.ts new file mode 100644 index 000000000..16600a655 --- /dev/null +++ b/packages/pvm/mechanics/vcs/git-vcs.ts @@ -0,0 +1,333 @@ +import fs from 'fs' +import { mkdirp, escapeFilePath } from '../../lib/fs' +import path from 'path' +import assert from 'assert' +import semver from 'semver' + +import { bindToCwd, shell as __shell } from '../../lib/shell' +import __runShell from '../../lib/shell/run' +import __execShell from '../../lib/shell/exec' + +import { logger } from '../../lib/logger' +import { mema } from '../../lib/memoize' +import revParse from '../../lib/git/rev-parse' +import { addTag, getCurrentBranchIgnoreEnv, gitFetch } from '../../lib/git/commands' +import { getGitVersion } from '../../lib/runtime-env/versions' + +import type { AbstractVcs, AddTagOptions, CommitResult, PushOptions, CommitOptions, Config } from '../../types' +import { env } from '../../lib/env' + +import type { RESOLVE_PUSH_REMOTE_TOKEN } from '../../tokens' + +const gitlabPushWithoutKeyDesc: { + ru: string, + _: string, +} = { + 'ru': `Вы пытаетесь отправить изменения через git на gitlab раннере. Однако, по умолчанию из гитлаб раннеров нельзя отправлять изменения через git протокол (см. https://gitlab.com/gitlab-org/gitlab-foss/-/issues/63858). + +Если операция не пройдет, сделайте следующее: +1. Создайте публичные и приватные ключи следуя инструкции описанной здесь: https://gitlab.com/help/ssh/README +2. Добавьте сгенерированный ключ на странице Settings -> CI / CD проекта. + Замечание: ключ хоть и добавляется на странице конкретного проекта, он будет доступен и для других проектов в пространстве. +3. Активируйте добавленный ключ для нужных вам проектов. Не забудьте проставить опцию "Write access allowed". +4. Добавьте переменную окружения GIT_SSH_PRIV_KEY на странице Settings -> CI / CD проекта со значением равным приватному ключу добавленному на втором шаге. + Переменную можно пометить как "protected", т.к. нужна она будет только для команды \`pvm update\`/\`pvm release\` которые обычно выполняются в master/main ветке проекта. + +После этого PVM будет использовать этот ключ для отправки изменений через git протокол.`, + '_': `You are trying to push changes through git on gitlab runner. However, by default you cannot send changes via the git protocol (see https://gitlab.com/gitlab-org/gitlab-foss/-/issues/63858). + +If the operation fails, do the following: +1. Create public and private keys following the instructions described here: https://gitlab.com/help/ssh/README. +2. Add the generated key on the Settings -> CI / Project CD page. + Note: although a key is added to a specific project page, it will be available for other projects in the space. +3. Activate the added key for the projects you need. Do not forget to check "Write access allowed" option. +4. Add environment variable GIT_SSH_PRIV_KEY on page Settings -> CI / CD of the project with value equal to private key added on the second step. + Variable can be marked as "protected" because it will be needed only for \`pvm update\`/\`pvm release\` command which are usually executed in master/main branch of the project. + +After that PVM will use this key to send changes via git protocol. +`, +} + +export interface GitCommitContext { + initialRev: string, + stashRef: string, +} + +enum PushOptionsVersion { + NOT_SUPPORTED, + LONG_KEY, + SHORT_KEY, +} + +function getPushOptionsVersion(): PushOptionsVersion { + const gitVersion = getGitVersion() + if (!gitVersion) { + return PushOptionsVersion.NOT_SUPPORTED + } + if (semver.lt(gitVersion, '2.10.0')) { + return PushOptionsVersion.NOT_SUPPORTED + } + if (semver.lt(gitVersion, '2.18.0')) { + return PushOptionsVersion.LONG_KEY + } + return PushOptionsVersion.SHORT_KEY +} + +function stringifyPushOptions(pushOptions: Map): string[] { + const pushOptionsVersion = getPushOptionsVersion() + if (pushOptionsVersion === PushOptionsVersion.NOT_SUPPORTED) { + if (pushOptions.size > 0) { + logger.error([ + `You have push options, but your git version ${getGitVersion()} doesn't support push-options.`, + `Please upgrade git to latest version. Minimum required version is 2.10.0 or better 2.18.0`, + ].join('\n')) + } + return [] + } + + const prefix = pushOptionsVersion === PushOptionsVersion.SHORT_KEY ? '-o ' : '--push-option=' + + return Array.from(pushOptions.entries()).map(([key, value]) => { + return `${prefix}"${key}${value === true ? '' : `=${value}`}"` + }) +} + +function prepareGit(cwd: string): void { + const shell = bindToCwd(cwd, __shell) + + let needDefineUserName + try { + needDefineUserName = !shell('git config user.name') + } catch (e) { + needDefineUserName = true + } + + let needDefineUserEmail + try { + needDefineUserEmail = !shell('git config user.email') + } catch (e) { + needDefineUserEmail = true + } + + if (needDefineUserName) { + shell('git config user.name "PVM Service"') + } + if (needDefineUserEmail) { + shell('git config user.email "pvm@pvm.service"') + } +} + +export class GitVcs implements AbstractVcs { + private gitPrepared = false + protected shell: typeof __shell + protected runShell: typeof __runShell + protected execShell: typeof __execShell + protected cachedShell: typeof __shell + protected config: Config + protected cwd: string + protected resolvePushRemote: typeof RESOLVE_PUSH_REMOTE_TOKEN | null + + // eslint-disable-next-line + constructor({ config, cwd, resolvePushRemote }: { config: Config, cwd: string, resolvePushRemote: typeof RESOLVE_PUSH_REMOTE_TOKEN | null }) { + this.config = config + this.cwd = cwd + this.resolvePushRemote = resolvePushRemote + this.shell = bindToCwd(this.cwd, __shell) + this.runShell = bindToCwd(this.cwd, __runShell) + this.execShell = bindToCwd(this.cwd, __execShell) + this.cachedShell = mema(this.shell) + } + + prepareGitMemo(): void { + if (!this.gitPrepared) { + prepareGit(this.cwd) + } + + this.gitPrepared = true + } + + async runGit(command: string) { + this.prepareGitMemo() + return await this.runShell(command) + } + + beginCommit(): GitCommitContext { + this.prepareGitMemo() + return { + initialRev: this.getHeadRev(), + stashRef: this.shell('git stash create'), + } + } + + async rollbackCommit(commitContext: GitCommitContext): Promise { + await this.runGit(`git reset --hard ${commitContext.initialRev}`) + if (commitContext.stashRef) { + await this.runGit(`git stash apply ${commitContext.stashRef}`) + } + } + + addFiles(_commitContext: GitCommitContext, filePaths: string[]) { + if (filePaths.length) { + return this.runGit(`git add ${filePaths.map(escapeFilePath).join(' ')}`) + } + return Promise.resolve() + } + + updateFile(_: GitCommitContext, filePath: string, content: string): Promise { + mkdirp(path.dirname(filePath)) + fs.writeFileSync(filePath, content) + + return this.runGit(`git add ${filePath}`) + } + + appendFile(_: GitCommitContext, filePath: string, content: string) { + mkdirp(path.dirname(filePath)) + fs.appendFileSync(filePath, content) + + return this.runGit(`git add ${filePath}`) + } + + async deleteFile(_: GitCommitContext, filePath: string): Promise { + if (fs.existsSync(filePath)) { + return this.runGit(`git rm ${filePath}`) + } + } + + getCurrentBranch(): string | void { + this.prepareGitMemo() + return getCurrentBranchIgnoreEnv(this.cwd) + } + + async commit(_: GitCommitContext, message: string, opts: CommitOptions = {}): Promise { + this.prepareGitMemo() + + const { branch } = opts + + const currentBranch = this.getCurrentBranch() + if (branch && currentBranch) { + assert.strictEqual(branch, currentBranch) + } + + // по крайней мере в git v2.25.0 есть бага: опция allow-empty не работает вместе с dry-run + const commitArgs = [`--file=-`] + if (opts.allowEmpty) { + commitArgs.push('--allow-empty') + } + + await this.runShell(`git commit ${commitArgs.join(' ')}`, { input: message }) + + return { + id: this.getHeadRev(), + } + } + + getHeadRev() { + this.prepareGitMemo() + return this.shell('git rev-parse HEAD') + } + + isLastAvailableRef(ref: string): boolean { + this.prepareGitMemo() + const rev = revParse(ref, this.cwd) + return this.cachedShell('git rev-list --max-parents=0 HEAD').indexOf(rev) !== -1 + } + + async push(opts: PushOptions = {}) { + this.prepareGitMemo() + const remoteBranch = this.getCurrentBranch() || this.config.git.push.default_branch + const remoteRepository = + opts.remote || + (this.resolvePushRemote ? await this.resolvePushRemote() : 'origin') + + const pushArgs: string[] = [] + + const { pushOptions = new Map() } = opts + + if (opts.skipCi && !pushOptions.has('ci.skip')) { + pushOptions.set('ci.skip', true) + } + + pushArgs.push(...stringifyPushOptions(pushOptions)) + + if (env.PVM_TESTING_ENV) { + logger.info('skip pushing in testing env') + // @TODO: код ниже ломает тесты в условиях гитлаб раннеров ломая евент-луп + return + } + + const pushEnv: Record = { + // eslint-disable-next-line pvm/no-process-env + ...process.env, + GIT_SSL_NO_VERIFY: '1', + } + + // если задана переменная PVM_DIRECT_GIT_PUSH то скрипт не будет выполнятся в любом случае + if (!env.PVM_DIRECT_GIT_PUSH && env.CI && this.config.git.push.try_load_ssh_keys) { + if (!env.GIT_SSH_PRIV_KEY) { + // @TODO: i18n support + const locale = Intl.DateTimeFormat().resolvedOptions().locale.split('-')[0].toLowerCase() + const messageLocale = locale in gitlabPushWithoutKeyDesc ? locale as keyof typeof gitlabPushWithoutKeyDesc : '_' + logger.warn(gitlabPushWithoutKeyDesc[messageLocale]) + } + const gitLoadPushCreds = path.resolve(__dirname, './git-load-push-creds.sh') + const payloadMark = '@----------ssh-agent-data----------@' + const { stdout } = await this.execShell(gitLoadPushCreds, { + printStdout: true, + env: { + // eslint-disable-next-line pvm/no-process-env + ...process.env, + PAYLOAD_MARK: payloadMark, + }, + }) + + const indexOfPayloadMark = stdout.indexOf(payloadMark) + if (indexOfPayloadMark !== -1) { + const payload = stdout.substr(indexOfPayloadMark).split(payloadMark)[1] + if (payload) { + const [SSH_AUTH_SOCK, SSH_AGENT_PID] = payload.trim().split(';') + if (SSH_AUTH_SOCK && SSH_AGENT_PID) { + logger.info('Successfully get ssh-agent identifiers from git-load-push-creds.sh script') + logger.debug(`SSH_AUTH_SOCK="${SSH_AUTH_SOCK}"`) + logger.debug(`SSH_AGENT_PID="${SSH_AGENT_PID}"`) + pushEnv.SSH_AUTH_SOCK = SSH_AUTH_SOCK + pushEnv.SSH_AGENT_PID = SSH_AGENT_PID + } + } + } else { + logger.error('No payload mark found produced by execution of git-load-push-creds.sh script') + } + } + + if (opts.refspec) { + await this.runShell(`git push ${pushArgs.join(' ')} ${remoteRepository} ${opts.refspec}`, { + env: pushEnv, + }) + } else { + await this.runShell(`git push ${pushArgs.join(' ')} ${remoteRepository} HEAD:${remoteBranch}`, { + env: pushEnv, + }) + if (!opts.noTags) { + await this.runShell(`git push ${pushArgs.join(' ')} --tags ${remoteRepository}`, { + env: pushEnv, + }) + } + } + } + + async fetchLatestSha(refName: string): Promise { + gitFetch(this.cwd, { repo: 'origin' }) + + return this.shell(`git rev-parse origin/${refName}`) + } + + async addTag(tagName: string, ref: string, opts: AddTagOptions = {}): Promise { + this.prepareGitMemo() + addTag(this.cwd, { + tagName, + ref, + annotation: opts.annotation, + }) + } +} + +export { prepareGit } diff --git a/packages/pvm-vcs/lib/index.ts b/packages/pvm/mechanics/vcs/index.ts similarity index 58% rename from packages/pvm-vcs/lib/index.ts rename to packages/pvm/mechanics/vcs/index.ts index 6cbbad4fa..71ef29a34 100644 --- a/packages/pvm-vcs/lib/index.ts +++ b/packages/pvm/mechanics/vcs/index.ts @@ -1,3 +1,2 @@ export * from './vcs' export * from './utils' -export { default } from './vcs' diff --git a/packages/pvm/mechanics/vcs/providers.ts b/packages/pvm/mechanics/vcs/providers.ts new file mode 100644 index 000000000..be3025b92 --- /dev/null +++ b/packages/pvm/mechanics/vcs/providers.ts @@ -0,0 +1,138 @@ +import { provide } from '../../lib/di' +import { + HOST_API_TOKEN, + ATTRIBUTE_RELEASE_DATA_HOOK_TOKEN, + COMMITS_TO_NOTES_TOKEN, + NOTIFY_SCRIPTS_PATH_TOKEN, + PRE_RELEASE_HOOK_TOKEN, + RELEASE_TYPE_BY_COMMITS_TOKEN, + RELEASE_TYPE_TOKEN, + CONFIG_TOKEN, + VCS_TOKEN, + CWD_TOKEN, + RESOLVE_PUSH_REMOTE_TOKEN, + GLOBAL_FLAGS_TOKEN, + VCS_PLATFORM_TOKEN, PLATFORM_TOKEN, VCS_PLATFORM_FACTORY_TOKEN, RAW_VCS_TOKEN, +} from '../../tokens' +import markdownifyCommits from '../../lib/markdownify-commits' +import type { Pkg } from '../../lib/pkg' +import { releaseMark } from '../../lib/consts' +import type { Commit, PvmReleaseType } from '../../types' +import type { ChangedContext } from '../update/changed-context' +import { VcsPlatform } from './vcs' +import type { ReleaseContext } from '../update/types' +import type { UpdateState } from '../update/update-state' +import type { ReleaseData, ReleaseDataExt } from '../releases/types' +import path from 'path' +import { GitVcs } from './git-vcs' +import { DecoratedVcs } from './decorated-vcs' + +export default [ + provide({ + provide: COMMITS_TO_NOTES_TOKEN, + useFactory({ config }) { + return (commits) => Promise.resolve(markdownifyCommits(commits, { jiraUrl: config.jira.url })) + }, + deps: { + config: CONFIG_TOKEN, + }, + }), + provide({ + provide: HOST_API_TOKEN, + useFactory({ + commitsToNotes, + releaseTypeByCommits, + releaseType, + preReleaseHooks, + attributeReleaseData, + config, + }) { + return { + async commitsToNotes(commits, maybePkg: Pkg | undefined) { + const filteredCommits = commits.filter(commit => { + return commit.subject.indexOf('[pvm noshow]') === -1 && commit.body.indexOf(releaseMark) === -1 + }) + return commitsToNotes(filteredCommits, maybePkg, config) + }, + releaseTypeByCommits(commits: Commit[], defaultValue = null) { + return releaseTypeByCommits ? releaseTypeByCommits(commits) : Promise.resolve(defaultValue) + }, + async releaseType(pkg: Pkg, changedContext: ChangedContext): Promise { + return releaseType ? releaseType(pkg, changedContext) : undefined + }, + async preReleaseHook(vcs: VcsPlatform, releaseContext: ReleaseContext) { + return preReleaseHooks ? Promise.all(preReleaseHooks.map(h => h(vcs, releaseContext))) : [] + }, + async attributeReleaseData(releaseData: ReleaseData, updateState: UpdateState | null): Promise { + if (attributeReleaseData) { + for (const proc of attributeReleaseData) { + releaseData = await proc(releaseData, updateState) + } + } + return releaseData + }, + } + }, + deps: { + commitsToNotes: COMMITS_TO_NOTES_TOKEN, + releaseTypeByCommits: { token: RELEASE_TYPE_BY_COMMITS_TOKEN, optional: true }, + releaseType: { token: RELEASE_TYPE_TOKEN, optional: true }, + preReleaseHooks: { token: PRE_RELEASE_HOOK_TOKEN, optional: true }, + attributeReleaseData: { token: ATTRIBUTE_RELEASE_DATA_HOOK_TOKEN, optional: true }, + config: CONFIG_TOKEN, + }, + }), + provide({ + provide: COMMITS_TO_NOTES_TOKEN, + useValue: (commits, _maybePkg, config) => Promise.resolve(markdownifyCommits(commits, { jiraUrl: config.jira.url })), + }), + provide({ + provide: NOTIFY_SCRIPTS_PATH_TOKEN, + useValue: () => Promise.resolve(path.resolve(__dirname, '../../lib/messages/notify-scripts')), + }), + provide({ + provide: VCS_TOKEN, + useClass: DecoratedVcs, + deps: { + vcs: RAW_VCS_TOKEN, + globalFlags: GLOBAL_FLAGS_TOKEN, + }, + }), + provide({ + provide: RAW_VCS_TOKEN, + useClass: GitVcs, + deps: { + resolvePushRemote: { token: RESOLVE_PUSH_REMOTE_TOKEN, optional: true }, + config: CONFIG_TOKEN, + cwd: CWD_TOKEN, + globalFlags: GLOBAL_FLAGS_TOKEN, + }, + }), + provide({ + provide: VCS_PLATFORM_TOKEN, + useFactory: ({ + vcsPlatformFactory, + }) => { + return vcsPlatformFactory({}) + }, + deps: { + vcsPlatformFactory: VCS_PLATFORM_FACTORY_TOKEN, + }, + }), + provide({ + provide: VCS_PLATFORM_FACTORY_TOKEN, + useFactory: (deps) => (customDeps) => { + return new VcsPlatform({ + ...deps, + ...customDeps, + }) + }, + deps: { + vcs: VCS_TOKEN, + platform: PLATFORM_TOKEN, + hostApi: HOST_API_TOKEN, + cwd: CWD_TOKEN, + globalFlags: GLOBAL_FLAGS_TOKEN, + }, + }), +] diff --git a/packages/pvm-vcs/lib/utils.ts b/packages/pvm/mechanics/vcs/utils.ts similarity index 100% rename from packages/pvm-vcs/lib/utils.ts rename to packages/pvm/mechanics/vcs/utils.ts diff --git a/packages/pvm-vcs/lib/vcs-only-stenographer.ts b/packages/pvm/mechanics/vcs/vcs-only-stenographer.ts similarity index 94% rename from packages/pvm-vcs/lib/vcs-only-stenographer.ts rename to packages/pvm/mechanics/vcs/vcs-only-stenographer.ts index aa7903fad..eb3835b28 100644 --- a/packages/pvm-vcs/lib/vcs-only-stenographer.ts +++ b/packages/pvm/mechanics/vcs/vcs-only-stenographer.ts @@ -1,7 +1,7 @@ -import { cutText } from '@pvm/core/lib/text' -import padLines from '@pvm/core/lib/text/pad-lines' +import { cutText } from '../../lib/text' +import padLines from '../../lib/text/pad-lines' -import type { AddTagOptions, CommitResult, VcsOnly, UnknownCommitContext, PushOptions } from '../types' +import type { AddTagOptions, CommitResult, VcsOnly, UnknownCommitContext, PushOptions } from '../../types' function details(text: string, maxLen = 2000): string { return '
\n\n```\n' + cutText(text, maxLen) + '\n````\n\n
' diff --git a/packages/pvm/mechanics/vcs/vcs.ts b/packages/pvm/mechanics/vcs/vcs.ts new file mode 100644 index 000000000..e47ebd46a --- /dev/null +++ b/packages/pvm/mechanics/vcs/vcs.ts @@ -0,0 +1,127 @@ +import { logger } from '../../lib/logger' +import { wdShell } from '../../lib/shell' + +import type { + VcsOnly, UnknownCommitContext, + AbstractVcs, AddTagOptions, CommitResult, PushOptions, +} from '../../types' +import type { PlatformInterface } from '../platform/platform-interface' +import type { GlobalFlags } from '../../lib/cli/global-flags' + +export class VcsPlatform implements VcsOnly { + readonly vcs: AbstractVcs + readonly cwd: string + dryRun = false + commitContext: any = null + _isSomethingForCommit = false + localMode = false + vcsMode: 'vcs' | 'platform' + vcsOrPlatform: PlatformInterface | AbstractVcs + + constructor(opts: { + cwd: string, + vcsMode?: 'vcs' | 'platform', + vcs: AbstractVcs, + platform: PlatformInterface, + globalFlags: GlobalFlags, + }) { + const { cwd, vcsMode = 'vcs', vcs, platform, globalFlags } = opts + + this.cwd = cwd + this.vcsMode = globalFlags.getFlag('localMode') ? 'vcs' : vcsMode + this.vcs = vcs + this.dryRun = globalFlags.getFlag('dryRun') + this.localMode = globalFlags.getFlag('localMode') + this.vcsOrPlatform = this.vcsMode === 'vcs' ? vcs : platform + } + + gitShell(cmd: string, opts = {}): string { + return wdShell(this.cwd, cmd, opts) + } + + isSomethingForCommit(): boolean { + return this._isSomethingForCommit + } + + resetCommitContext(): void { + this.commitContext = null + this._isSomethingForCommit = false + } + + async rollbackCommit(commitContext: UnknownCommitContext): Promise { + await this.vcsOrPlatform.rollbackCommit(commitContext) + + this.resetCommitContext() + } + + beginCommit(): UnknownCommitContext { + // FYI: upconf оперирует vcs без beginCommit + // поэтому неявный контекст созданный в _prepareCommitContext возвращаем как есть + if (!this.commitContext) { + this.commitContext = this.vcsOrPlatform.beginCommit() + } + return this.commitContext + } + + _prepareCommitContext(): UnknownCommitContext { + this._isSomethingForCommit = true + return this.beginCommit() + } + + async addFiles(filePaths: string[]): Promise { + if (filePaths.length) { + return this.vcsOrPlatform.addFiles(this._prepareCommitContext(), filePaths) + } + } + + async addPath(path: string): Promise { + const filePaths = this.gitShell(`git ls-files --cached --others "${path}"`).split('\n').filter(x => x.length !== 0) + return await this.addFiles(filePaths) + } + + async updateFile(filePath: string, content: string): Promise { + return this.vcsOrPlatform.updateFile(this._prepareCommitContext(), filePath, content) + } + + async appendFile(filePath: string, content: string): Promise { + return this.vcsOrPlatform.appendFile(this._prepareCommitContext(), filePath, content) + } + + async deleteFile(filePath: string): Promise { + return this.vcsOrPlatform.deleteFile(this._prepareCommitContext(), filePath) + } + + async commit(message: string, opts = {}): Promise { + if (!this.isSomethingForCommit()) { + logger.log('nothing to commit') + return + } + + const result = await this.vcsOrPlatform.commit(this.commitContext, message, opts) + this.resetCommitContext() + + // нулевой айди не обязателен здесь, но всякий случай пусть будет + return result || { id: '0000000000000000000000000000000000000000' } + } + + async push(opts: PushOptions = {}): Promise { + if (this.vcsMode === 'vcs') { + await this.vcs.push(opts) + } + } + + async addTag(tagName: string, ref: string, opts: AddTagOptions = {}): Promise { + await this.vcsOrPlatform.addTag(tagName, ref, opts) + } + + async fetchLatestSha(refName: string): Promise { + return this.vcsOrPlatform.fetchLatestSha(refName) + } + + async isRefMatchesRemoteBranch(targetRef = 'HEAD', branchName: string): Promise { + if (!branchName) { + throw new Error(`Branch name is required. Are you in detached head state ?`) + } + return this.gitShell(`git rev-parse ${targetRef}`) === (await this.fetchLatestSha(branchName)) + } +} diff --git a/packages/pvm/package.json b/packages/pvm/package.json index 05c8f50e5..f8b428c6d 100644 --- a/packages/pvm/package.json +++ b/packages/pvm/package.json @@ -3,7 +3,6 @@ "version": "0.0.0-stub", "initialVersion": "0.54.0", "description": "Featured, powerful and compliant package version/release manager", - "main": "lib/index.js", "bin": { "pvm": "bin/pvm.js" }, @@ -11,7 +10,46 @@ "author": "Andrey Rublev ", "license": "Apache-2.0", "dependencies": { - "@pvm/core": "0.0.0-stub", - "@pvm/plugin-core": "0.0.0-stub" + "@iarna/toml": "^2.2.3", + "@hutson/parse-repository-url": "^5.0.0", + "@tinkoff/dippy": "^0.8.6", + "ajv": "^6.12.2", + "chalk": "^4.0.0", + "cli-table": "^0.3.6", + "cosmiconfig": "^6.0.0", + "fast-deep-equal": "^3.1.3", + "fast-glob": "^3.1.1", + "git-log-parser": "^1.2.0", + "micromatch": "^3.1.10", + "mri": "^1.1.4", + "resolve-from": "^5.0.0", + "rfc6902": "^4.0.2", + "semver": "^7.3.0", + "signales": "^2.0.5", + "through2": "^4.0.2", + "git-url-parse": "^11.4.4", + "json5": "^2.2.1", + "bin-version-check": "^4.0.0", + "ini": "^1.3.8", + "yargs": "^16.1.1", + "get-stdin": "^7.0.0", + "bytes": "^3.1.0", + "ms": "^2.1.3", + "nunjucks": "^3.2.0", + "chokidar": "^3.3.0", + "viz.js": "^2.1.2", + "string-to-color": "^2.2.2", + "ignore": "^5.1.8", + "front-matter": "^3.2.1", + "fs-extra": "^9.1.0", + "date-fns": "^2.22.1", + "lodash": "^4.17.21", + "p-map": "^4.0.0", + "remarkable": "^2.0.1", + "shuffle-seed": "^1.1.6", + "superheroes": "^3.0.0", + "tempy": "^1.0.1", + "uniq": "^1.0.1", + "type-fest": "^3.3.0" } } diff --git a/packages/pvm-core/pvm-defaults.ts b/packages/pvm/pvm-defaults.ts similarity index 93% rename from packages/pvm-core/pvm-defaults.ts rename to packages/pvm/pvm-defaults.ts index aa2da91fc..efc8cb1d2 100644 --- a/packages/pvm-core/pvm-defaults.ts +++ b/packages/pvm/pvm-defaults.ts @@ -1,4 +1,4 @@ -import type { ConfigSchema } from '@pvm/types' +import type { ConfigSchema } from './types' export const defaultConfig: ConfigSchema = { versioning: { @@ -11,7 +11,7 @@ export const defaultConfig: ConfigSchema = { tagging: { release_tag_package: '', annotation_lookup_depth: 30, - suffixes: require.resolve('@pvm/suffixes'), + suffixes: require.resolve('./mechanics/suffixes'), generic_tag: { prefix: 'release', date_format: 'yyyy.MM.dd', @@ -82,7 +82,7 @@ export const defaultConfig: ConfigSchema = { }, skip_empty: false, renderer: { - type: 'builtin.list', + type: 'builtin.list-with-packages', tag_head_level: 2, show_date: true, }, @@ -127,12 +127,8 @@ export const defaultConfig: ConfigSchema = { process_npm_token: true, include_monorepo_root: false, }, - plugins: { - local_plugins: [], - options: {}, - }, plugins_v2: [ - { plugin: require.resolve('@pvm/plugin-common-plugins') }, + { plugin: require.resolve('./commands') }, ], templating: { use_short_names: false, @@ -160,7 +156,6 @@ export const defaultConfig: ConfigSchema = { dangerously_opts: {}, notifications: { target: 'first_available', - clients: [], clients_common_config: {}, client_configs: {}, }, diff --git a/packages/pvm/tokens/cli.ts b/packages/pvm/tokens/cli.ts new file mode 100644 index 000000000..4be6190bd --- /dev/null +++ b/packages/pvm/tokens/cli.ts @@ -0,0 +1,5 @@ +import { createToken } from '../lib/di' +import type { CommandFactory } from '../types' + +export const CLI_EXTENSION_TOKEN = createToken('CLI_EXTENSION_TOKEN', { multi: true }) +export const CLI_TOKEN = createToken<(opts: { argv: string[] }) => void>('CLI_TOKEN') diff --git a/packages/pvm/tokens/core.ts b/packages/pvm/tokens/core.ts new file mode 100644 index 000000000..ae04198a8 --- /dev/null +++ b/packages/pvm/tokens/core.ts @@ -0,0 +1,29 @@ +import { createToken } from '../lib/di' +import type { Config, HostApi, ReleaseMessageGenerator, AbstractVcs } from '../types' +import type { VcsPlatform } from '../mechanics/vcs' +import type { PlatformInterface } from '../mechanics/platform' +import type { GlobalFlags } from '../lib/cli/global-flags' +import type { IncrementalRenderer } from '../mechanics/changelog/types' +import type { AbstractMessengerClient, Notificator } from '../mechanics/notifications' +import type { Repository } from '../mechanics/repository' + +export { DI_TOKEN } from '../lib/di' + +export const CONFIG_TOKEN = createToken('CONFIG') +export const CWD_TOKEN = createToken('CWD_TOKEN') +export const PLATFORM_TOKEN = createToken>('PLATFORM_TOKEN') +export const RAW_PLATFORM_TOKEN = createToken>('RAW_PLATFORM_TOKEN') +export const HOST_API_TOKEN = createToken('HOST_API_TOKEN') +export const VCS_TOKEN = createToken>('VCS_TOKEN') +export const RAW_VCS_TOKEN = createToken>('RAW_VCS_TOKEN') +export const VCS_PLATFORM_TOKEN = createToken('VCS_PLATFORM_TOKEN') +export const VCS_PLATFORM_FACTORY_TOKEN = createToken<(opts: Partial[0]>) => VcsPlatform>('VCS_PLATFORM_FACTORY_TOKEN') +export const GLOBAL_FLAGS_TOKEN = createToken('GLOBAL_FLAGS_TOKEN') +export const CHANGELOG_RENDERERS_MAP = createToken>('CHANGELOG_RENDERERS_MAP') +export const CHANGELOG_CUSTOM_RENDERER = createToken('CHANGELOG_RENDERER') +export const MESSENGER_CLIENT_TOKEN = createToken('MESSENGER_CLIENT_TOKEN', { + multi: true, +}) +export const NOTIFICATOR_TOKEN = createToken('NOTIFICATOR_TOKEN') +export const RELEASE_NOTIFICATIONS_MAP_TOKEN = createToken>('RELEASE_NOTIFICATIONS_MAP_TOKEN', { multi: true }) +export const REPOSITORY_FACTORY_TOKEN = createToken<(opts?: { ref: string | void }) => Repository>('REPOSITORY_FACTORY_TOKEN') diff --git a/packages/pvm/tokens/hooks.ts b/packages/pvm/tokens/hooks.ts new file mode 100644 index 000000000..4af167d2b --- /dev/null +++ b/packages/pvm/tokens/hooks.ts @@ -0,0 +1,21 @@ +import { createToken } from '../lib/di' +import type { Commit, Config, PvmReleaseType, ConventionalCommit } from '../types' +import type { Pkg } from '../lib/pkg' +import type { ChangedContext } from '../mechanics/update/changed-context' +import type { VcsPlatform } from '../mechanics/vcs' +import type { ReleaseContext } from '../mechanics/update/types' +import type { ReleaseData, ReleaseDataExt } from '../mechanics/releases/types' +import type { UpdateState } from '../mechanics/update/update-state' +import type { MdUpdatedTable } from '../mechanics/update/utils/md-table' +import type { PlatformInterface } from '../mechanics/platform' + +export const NOTIFY_SCRIPTS_PATH_TOKEN = createToken<() => Promise>('NOTIFY_SCRIPTS_PATH_TOKEN') +export const RELEASE_TYPE_BY_COMMITS_TOKEN = createToken<(gitCommits: Array) => Promise >('RELEASE_TYPE_BY_COMMITS_TOKEN') +export const RELEASE_TYPE_TOKEN = createToken<(pkg: Pkg, changedContext: ChangedContext) => Promise >('RELEASE_TYPE_TOKEN') +export const COMMITS_TO_NOTES_TOKEN = createToken<(gitCommits: Array, maybePkg: Pkg | undefined, config: Config) => Promise >('COMMITS_TO_NOTES_TOKEN') +export const RELEASE_TYPE_BUILDER_TOKEN = createToken<(gitCommits: Array) => Promise>('RELEASE_TYPE_BUILDER_TOKEN') +export const PRE_RELEASE_HOOK_TOKEN = createToken<(vcs: VcsPlatform, releaseContext: ReleaseContext) => Promise>('PRE_RELEASE_HOOK_TOKEN', { multi: true }) +export const ATTRIBUTE_RELEASE_DATA_HOOK_TOKEN = createToken<(releaseData: ReleaseData, updateState: UpdateState | null) => Promise>('ATTRIBUTE_RELEASE_DATA_HOOK_TOKEN', { multi: true }) +export const MARK_PR_HOOK_TOKEN = createToken<(platform: PlatformInterface, updateState: UpdateState) => Promise>('MARK_PR_HOOK_TOKEN', { multi: true }) +export const RESOLVE_PUSH_REMOTE_TOKEN = createToken<() => Promise>('RESOLVE_PUSH_REMOTE_TOKEN') +export const UPDATE_MD_TABLE_EXTEND_TOKEN = createToken<(mdUpdatedTable: MdUpdatedTable) => void>('UPDATE_MD_TABLE_EXTEND_TOKEN', { multi: true }) diff --git a/packages/pvm/tokens/index.ts b/packages/pvm/tokens/index.ts new file mode 100644 index 000000000..69e03205e --- /dev/null +++ b/packages/pvm/tokens/index.ts @@ -0,0 +1,3 @@ +export * from './core' +export * from './cli' +export * from './hooks' diff --git a/packages/pvm/types/cli.ts b/packages/pvm/types/cli.ts new file mode 100644 index 000000000..1a63d0823 --- /dev/null +++ b/packages/pvm/types/cli.ts @@ -0,0 +1,3 @@ +import type { Argv } from 'yargs' + +export type CommandFactory = (yargs: Argv) => Argv diff --git a/packages/pvm-types/lib/config-schema.json b/packages/pvm/types/config-schema.json similarity index 78% rename from packages/pvm-types/lib/config-schema.json rename to packages/pvm/types/config-schema.json index cd52cf078..aa36d38d1 100644 --- a/packages/pvm-types/lib/config-schema.json +++ b/packages/pvm/types/config-schema.json @@ -53,10 +53,7 @@ "$ref": "#/definitions/ChangelogRendererBuiltin" }, { - "$ref": "#/definitions/ChangelogRendererCommonJs" - }, - { - "$ref": "#/definitions/ChangelogRendererByPlugin" + "$ref": "#/definitions/ChangelogRendererCustom" } ], "description": "Настройка рендерера" @@ -100,28 +97,11 @@ }, "type": "object" }, - "ChangelogRendererByPlugin": { - "properties": { - "providesPath": { - "type": "string" - }, - "type": { - "enum": [ - "by-plugin" - ], - "type": "string" - } - }, - "type": "object" - }, - "ChangelogRendererCommonJs": { + "ChangelogRendererCustom": { "properties": { - "path": { - "type": "string" - }, "type": { "enum": [ - "commonjs" + "custom" ], "type": "string" } @@ -139,19 +119,6 @@ }, "type": "object" }, - "MessengerClientLoadConfig": { - "properties": { - "name": { - "description": "Name of client. Used in matching with `MessengerName` in `messaging.target` and in `messaging.defaults`. Also\nused in logging errors.", - "type": "string" - }, - "pkg": { - "description": "Path to module or file which exports MessengerClient field. MessengerClient should inherit from AbstractMessengerClient\nin order to guarantee fit to use cases and to be compatible with current version of pvm.", - "type": "string" - } - }, - "type": "object" - }, "Omit": { "properties": { "enabled": { @@ -168,10 +135,7 @@ "$ref": "#/definitions/ChangelogRendererBuiltin" }, { - "$ref": "#/definitions/ChangelogRendererCommonJs" - }, - { - "$ref": "#/definitions/ChangelogRendererByPlugin" + "$ref": "#/definitions/ChangelogRendererCustom" } ], "description": "Настройка рендерера" @@ -207,150 +171,144 @@ }, "type": "object" }, - "PluginConfig": { + "PartialObjectDeep": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { - "options": { - "$ref": "#/definitions/PluginOptions" + "type": { + "enum": [ + "size", + "time" + ], + "type": "string" }, - "plugin": { + "value": { + "type": "string" + } + }, + "type": "object" + }, + "PartialObjectDeep": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", + "properties": { + "branch": { + "type": "string" + }, + "dest": { + "type": "string" + }, + "type": { + "enum": [ + "branch" + ], + "type": "string" + } + }, + "type": "object" + }, + "PartialObjectDeep&{output_dir:string;};},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", + "properties": { + "enabled": { + "description": "Включает рендер чейнджлога", + "type": "boolean" + }, + "for_packages": { + "$ref": "#/definitions/PartialObjectDeep&{output_dir:string;},Opts>", + "description": "Changelog settings for packages individually" + }, + "front_matter": { + "description": "Контент, который нужно поместить в начало файла чейнджлога", + "type": "string" + }, + "path": { + "description": "Путь до генерируемого файла чейнджлога", + "type": "string" + }, + "renderer": { "anyOf": [ { - "allOf": [ - { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - }, - { - "properties": { - "factory": { - "type": "object" - } - }, - "type": "object" - } - ] + "$ref": "#/definitions/PartialObjectDeep" }, { - "allOf": [ - { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - }, - { - "$ref": "#/definitions/{configExt:RecursivePartial;}" - } - ] + "$ref": "#/definitions/PartialObjectDeep" + } + ], + "description": "Настройка рендерера" + }, + "skip_empty": { + "description": "Не помещать записи без изменений в чейнджлог", + "type": "boolean" + }, + "storage": { + "anyOf": [ + { + "$ref": "#/definitions/PartialObjectDeep" }, { - "allOf": [ - { - "properties": { - "name": { - "type": "string" - } - }, - "type": "object" - }, - { - "properties": { - "configExt": { - "$ref": "#/definitions/RecursivePartial" - }, - "factory": { - "type": "object" - } - }, - "type": "object" - } - ] + "$ref": "#/definitions/PartialObjectDeep" }, { - "type": [ - "string", - "object" - ] + "$ref": "#/definitions/PartialObjectDeep" } - ] + ], + "description": "Storage settings" } }, "type": "object" }, - "PluginOptions": { - "type": "object" - }, - "Record>": { - "type": "object" - }, - "Record>": { + "PartialObjectDeep": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", + "properties": { + "show_date": { + "type": "boolean" + }, + "tag_head_level": { + "type": "number" + }, + "type": { + "enum": [ + "builtin.list", + "builtin.list-with-packages" + ], + "type": "string" + } + }, "type": "object" }, - "Record": { + "PartialObjectDeep": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", + "properties": { + "type": { + "enum": [ + "custom" + ], + "type": "string" + } + }, "type": "object" }, - "RecursivePartial": { + "PartialObjectDeep": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "changelog": { - "allOf": [ - { - "$ref": "#/definitions/Changelog" - }, - { - "properties": { - "for_packages": { - "allOf": [ - { - "$ref": "#/definitions/Omit" - }, - { - "properties": { - "output_dir": { - "description": "Output dir for individual package changelog files", - "type": "string" - } - }, - "type": "object" - } - ], - "description": "Changelog settings for packages individually" - } - }, - "type": "object" - } - ], + "$ref": "#/definitions/PartialObjectDeep&{output_dir:string;};},Opts>", "description": "Changelog generator settings" }, - "configLookupDir": { - "type": "string" - }, "core": { - "$ref": "#/definitions/RecursivePartial<{deps_keys:string[];}>" - }, - "cwd": { - "type": "string" + "$ref": "#/definitions/PartialObjectDeep<{deps_keys:(\"dependencies\"|\"devDependencies\"|\"peerDependencies\"|\"optionalDependencies\")[];},Opts>" }, "dangerously_opts": { - "$ref": "#/definitions/RecursivePartial<{always_changed_workspaces?:string[];}>", + "$ref": "#/definitions/PartialObjectDeep<{always_changed_workspaces?:string[];},Opts>", "description": "Options that need more attention in terms of the consequences of their activation." }, - "executionContext": { - "$ref": "#/definitions/RecursivePartial<{dryRun:boolean;local:boolean;}>" - }, "git": { - "$ref": "#/definitions/RecursivePartial<{push:{try_load_ssh_keys:boolean;default_branch:string;};}>" + "$ref": "#/definitions/PartialObjectDeep<{push:{try_load_ssh_keys:boolean;default_branch:string;};},Opts>" }, "github": { - "$ref": "#/definitions/RecursivePartial<{auth_strategy?:\"authApp\"|\"authToken\"|\"authAction\";api_url?:string;}>" + "$ref": "#/definitions/PartialObjectDeep<{auth_strategy?:\"authApp\"|\"authToken\"|\"authAction\";api_url?:string;},Opts>" }, "gitlab": { - "$ref": "#/definitions/RecursivePartial<{default_url:string;api_prefix:string;authorization_type:\"bearer\"|\"private-token\";api_url?:string;url?:string;}>" + "$ref": "#/definitions/PartialObjectDeep<{default_url:string;api_prefix:string;authorization_type:\"bearer\"|\"private-token\";api_url?:string;url?:string;},Opts>" }, "include": { "description": "External configuration paths", @@ -360,23 +318,20 @@ "type": "array" }, "jira": { - "$ref": "#/definitions/RecursivePartial<{url?:string;}>" + "$ref": "#/definitions/PartialObjectDeep<{url?:string;},Opts>" }, "mark_pr": { - "$ref": "#/definitions/RecursivePartial<{analyze_update:boolean;packages_table:boolean;attach_changelog:boolean;packages_as_labels:boolean;packages_graph:boolean;renderer:ChangelogRenderer;}>" + "$ref": "#/definitions/PartialObjectDeep<{analyze_update:boolean;packages_table:boolean;attach_changelog:boolean;packages_as_labels:boolean;packages_graph:boolean;renderer:ChangelogRenderer;},Opts>" }, "notifications": { - "$ref": "#/definitions/RecursivePartial<{target:string|string[];clients:MessengerClientLoadConfig[];clients_common_config:Partial;client_configs:Record>;}>", + "$ref": "#/definitions/PartialObjectDeep<{target:string|string[];clients_common_config:Partial;client_configs:Record>;},Opts>", "description": "How to deal with messages." }, "packages": { - "$ref": "#/definitions/RecursivePartial<{indent?:number;}>" + "$ref": "#/definitions/PartialObjectDeep<{indent?:number;},Opts>" }, "pkgset": { - "$ref": "#/definitions/RecursivePartial<{ignore_files:string[];affected_files:{if_changed:string[];then_affected:PkgFlexGlobs;}[];}>" - }, - "plugins": { - "$ref": "#/definitions/RecursivePartial<{local_plugins:string[];options:Record>;}>" + "$ref": "#/definitions/PartialObjectDeep<{ignore_files:string[];affected_files:{if_changed:string[];then_affected:PkgFlexGlobs;}[];},Opts>" }, "plugins_v2": { "items": { @@ -385,45 +340,91 @@ "type": "array" }, "publish": { - "$ref": "#/definitions/RecursivePartial<{registry?:string;disabled_for:string[];enabled_only_for:string[];path_subdir?:string;path_mapping?:Record;email?:string;cli_args?:string;process_npm_token?:boolean;include_monorepo_root:boolean;}>" + "$ref": "#/definitions/PartialObjectDeep<{registry?:string;disabled_for:string[];enabled_only_for:string[];path_subdir?:string;path_mapping?:Record;email?:string;cli_args?:string;process_npm_token?:boolean;include_monorepo_root:boolean;},Opts>" }, "release": { - "$ref": "#/definitions/RecursivePartial<{ensure_branch_up_to_date:boolean;tag_only:boolean;}>" + "$ref": "#/definitions/PartialObjectDeep<{ensure_branch_up_to_date:boolean;tag_only:boolean;},Opts>" }, "release_list": { - "$ref": "#/definitions/RecursivePartial<{enabled:boolean;path:string;limit:ArtifactLimitDef;storage:StorageDef;}>" + "$ref": "#/definitions/PartialObjectDeep<{enabled:boolean;path:string;limit:ArtifactLimitDef;storage:StorageDef;},Opts>" }, "slack_notification": { - "$ref": "#/definitions/RecursivePartial>", + "$ref": "#/definitions/PartialObjectDeep,Opts>", "description": "See https://api.slack.com/methods/chat.postMessage#arguments" }, "tagging": { - "$ref": "#/definitions/RecursivePartial<{release_tag_package:string;annotation_lookup_depth:number;suffixes:string|string[];generic_tag:{prefix:string;date_format:string;suffixes?:string|string[];};for_packages:{enabled:boolean;as_release:boolean;strip_namespace:boolean;};}>" + "$ref": "#/definitions/PartialObjectDeep<{release_tag_package:string;annotation_lookup_depth:number;suffixes:string|string[];generic_tag:{prefix:string;date_format:string;suffixes?:string|string[];};for_packages:{enabled:boolean;as_release:boolean;strip_namespace:boolean;};},Opts>" }, "templates": { - "$ref": "#/definitions/RecursivePartial<{'pkg-update-deps':string;'release-commit':string;failed_vcs_push:string;}>", + "$ref": "#/definitions/PartialObjectDeep<{[key:string]:string;'pkg-update-deps':string;'release-commit':string;failed_vcs_push:string;},Opts>", "description": "Templates\nSee https://mozilla.github.io/nunjucks/templating.html for template engine docs\nSee packages/pvm-template/lib/env.ts for extra filters and variables" }, "templating": { - "$ref": "#/definitions/RecursivePartial<{use_short_names:boolean;setup_script?:string;filters:{cutList:{maxLen:number;};};vars:{[key:string]:string|number;releaseLink?:string;};}>" + "$ref": "#/definitions/PartialObjectDeep<{use_short_names:boolean;setup_script?:string;filters:{cutList:{maxLen:number;};};vars:{[key:string]:string|number;releaseLink?:string;};},Opts>" }, "update": { - "$ref": "#/definitions/RecursivePartial<{default_release_type:\"patch\"|\"minor\"|\"major\";include_root:boolean|\"auto\";include_uncommited:boolean;update_dependants:boolean|{match:string;release_type:\"none\"|SemverReleaseType|\"as-dep\";}[];no_release_ref:string|false;dependants_release_type:SemverReleaseType|\"as-dep\";hints_file:string;workspace_release_files:boolean;autolint:boolean;respect_zero_major_version:boolean;commit_via_platform:boolean;push_remote:string;retry_via_platform_if_failed_via_vcs:boolean;release_type_overrides:{type:\"none\"|SemverReleaseType;files_match:string[];}[];graph:{title:string;strip_namespace:boolean;};}>" + "$ref": "#/definitions/PartialObjectDeep<{default_release_type:\"minor\"|\"major\"|\"patch\";include_root:boolean|\"auto\";include_uncommited:boolean;update_dependants:boolean|{match:string;release_type:\"none\"|SemverReleaseType|\"as-dep\";}[];no_release_ref:string|false;dependants_release_type:SemverReleaseType|\"as-dep\";hints_file:string;workspace_release_files:boolean;autolint:boolean;respect_zero_major_version:boolean;commit_via_platform:boolean;push_remote:string;retry_via_platform_if_failed_via_vcs:boolean;release_type_overrides:{type:\"none\"|SemverReleaseType;files_match:string[];}[];graph:{title:string;strip_namespace:boolean;};},Opts>" }, "vcs": { - "$ref": "#/definitions/RecursivePartial<{builtin_type:\"auto\"|\"git\"|\"fs\";}>", + "$ref": "#/definitions/PartialObjectDeep<{builtin_type:\"auto\"|\"git\"|\"fs\";},Opts>", "description": "Version control system settings" }, "versioning": { - "$ref": "#/definitions/RecursivePartial<{unified:boolean|string[];unified_versions_for:PkgFlexGlobs[];source:\"file\"|\"package\"|\"tag\";source_file:string;independent_packages:string[];}>" + "$ref": "#/definitions/PartialObjectDeep<{unified:boolean|string[];unified_versions_for:(string|string[])[];source:\"file\"|\"tag\"|\"package\";source_file:string;independent_packages:string[];},Opts>" + } + }, + "type": "object" + }, + "PartialObjectDeep": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", + "properties": { + "type": { + "enum": [ + "external" + ], + "type": "string" } }, "type": "object" }, - "RecursivePartial>": { + "PartialObjectDeep&{output_dir:string;},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", + "properties": { + "enabled": { + "description": "Включает рендер чейнджлога", + "type": "boolean" + }, + "front_matter": { + "description": "Контент, который нужно поместить в начало файла чейнджлога", + "type": "string" + }, + "output_dir": { + "description": "Output dir for individual package changelog files", + "type": "string" + }, + "renderer": { + "anyOf": [ + { + "$ref": "#/definitions/PartialObjectDeep" + }, + { + "$ref": "#/definitions/PartialObjectDeep" + } + ], + "description": "Настройка рендерера" + }, + "skip_empty": { + "description": "Не помещать записи без изменений в чейнджлог", + "type": "boolean" + } + }, + "type": "object" + }, + "PartialObjectDeep,Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "author": { - "$ref": "#/definitions/RecursivePartial<{name?:string;avatarEmoji?:string;avatarUrl?:string;}>", + "$ref": "#/definitions/PartialObjectDeep<{name?:string;avatarEmoji?:string;avatarUrl?:string;},Opts>", "description": "Displayed post author customization (not supported in all messengers)" }, "channel": { @@ -433,16 +434,31 @@ }, "type": "object" }, - "RecursivePartial>>": { + "PartialObjectDeep>,Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "type": "object" }, - "RecursivePartial>>": { + "PartialObjectDeep,Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "type": "object" }, - "RecursivePartial>": { + "PartialObjectDeep": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", + "properties": { + "dest": { + "type": "string" + }, + "type": { + "enum": [ + "repo" + ], + "type": "string" + } + }, "type": "object" }, - "RecursivePartial<{'pkg-update-deps':string;'release-commit':string;failed_vcs_push:string;}>": { + "PartialObjectDeep<{[key:string]:string;'pkg-update-deps':string;'release-commit':string;failed_vcs_push:string;},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "failed_vcs_push": { "description": "If vcs push failed then render error message for slack with this template", @@ -459,7 +475,8 @@ }, "type": "object" }, - "RecursivePartial<{[key:string]:string|number;releaseLink?:string;}>": { + "PartialObjectDeep<{[key:string]:string|number;releaseLink?:string;},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "releaseLink": { "type": "string" @@ -467,10 +484,11 @@ }, "type": "object" }, - "RecursivePartial<{always_changed_workspaces?:string[];}>": { + "PartialObjectDeep<{always_changed_workspaces?:string[];},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "always_changed_workspaces": { - "description": "A glob mask array that defines the packets that the system will interpret as always modified.\nThe mask will be applied to the path of the packages (workspaces).\nThis setting will affect the following places:\n- getPackages method in '@pvm/pvm' (except 'released' and 'updated' types)\n- getUpdateState method in '@pvm/update', which affects pvm-update or pvm-release commands", + "description": "A glob mask array that defines the packets that the system will interpret as always modified.\nThe mask will be applied to the path of the packages (workspaces).\nThis setting will affect the following places:\n- getPackages method in '@pvm/pvm' (except 'released' and 'updated' types)\n- pvm-update or pvm-release commands and update mechanic", "items": { "type": "string" }, @@ -479,7 +497,8 @@ }, "type": "object" }, - "RecursivePartial<{analyze_update:boolean;packages_table:boolean;attach_changelog:boolean;packages_as_labels:boolean;packages_graph:boolean;renderer:ChangelogRenderer;}>": { + "PartialObjectDeep<{analyze_update:boolean;packages_table:boolean;attach_changelog:boolean;packages_as_labels:boolean;packages_graph:boolean;renderer:ChangelogRenderer;},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "analyze_update": { "description": "Enable various checks of repo packages. In particular check sync of versions between packages. Mark-pr will print warnings\nin case of problems detected.", @@ -504,13 +523,10 @@ "renderer": { "anyOf": [ { - "$ref": "#/definitions/ChangelogRendererBuiltin" - }, - { - "$ref": "#/definitions/ChangelogRendererCommonJs" + "$ref": "#/definitions/PartialObjectDeep" }, { - "$ref": "#/definitions/ChangelogRendererByPlugin" + "$ref": "#/definitions/PartialObjectDeep" } ], "description": "Changelog render settings" @@ -518,7 +534,8 @@ }, "type": "object" }, - "RecursivePartial<{auth_strategy?:\"authApp\"|\"authToken\"|\"authAction\";api_url?:string;}>": { + "PartialObjectDeep<{auth_strategy?:\"authApp\"|\"authToken\"|\"authAction\";api_url?:string;},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "api_url": { "description": "Optional url of github server", @@ -537,7 +554,8 @@ }, "type": "object" }, - "RecursivePartial<{builtin_type:\"auto\"|\"git\"|\"fs\";}>": { + "PartialObjectDeep<{builtin_type:\"auto\"|\"git\"|\"fs\";},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "builtin_type": { "description": "Version system type", @@ -551,15 +569,17 @@ }, "type": "object" }, - "RecursivePartial<{cutList:{maxLen:number;};}>": { + "PartialObjectDeep<{cutList:{maxLen:number;};},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "cutList": { - "$ref": "#/definitions/RecursivePartial<{maxLen:number;}>" + "$ref": "#/definitions/PartialObjectDeep<{maxLen:number;},Opts>" } }, "type": "object" }, - "RecursivePartial<{default_release_type:\"patch\"|\"minor\"|\"major\";include_root:boolean|\"auto\";include_uncommited:boolean;update_dependants:boolean|{match:string;release_type:\"none\"|SemverReleaseType|\"as-dep\";}[];no_release_ref:string|false;dependants_release_type:SemverReleaseType|\"as-dep\";hints_file:string;workspace_release_files:boolean;autolint:boolean;respect_zero_major_version:boolean;commit_via_platform:boolean;push_remote:string;retry_via_platform_if_failed_via_vcs:boolean;release_type_overrides:{type:\"none\"|SemverReleaseType;files_match:string[];}[];graph:{title:string;strip_namespace:boolean;};}>": { + "PartialObjectDeep<{default_release_type:\"minor\"|\"major\"|\"patch\";include_root:boolean|\"auto\";include_uncommited:boolean;update_dependants:boolean|{match:string;release_type:\"none\"|SemverReleaseType|\"as-dep\";}[];no_release_ref:string|false;dependants_release_type:SemverReleaseType|\"as-dep\";hints_file:string;workspace_release_files:boolean;autolint:boolean;respect_zero_major_version:boolean;commit_via_platform:boolean;push_remote:string;retry_via_platform_if_failed_via_vcs:boolean;release_type_overrides:{type:\"none\"|SemverReleaseType;files_match:string[];}[];graph:{title:string;strip_namespace:boolean;};},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "autolint": { "description": "Lint and fix packages package.json files before update and commit them", @@ -589,7 +609,7 @@ "type": "string" }, "graph": { - "$ref": "#/definitions/RecursivePartial<{title:string;strip_namespace:boolean;}>", + "$ref": "#/definitions/PartialObjectDeep<{title:string;strip_namespace:boolean;},Opts>", "description": "Updated packages graph settings" }, "hints_file": { @@ -696,7 +716,8 @@ }, "type": "object" }, - "RecursivePartial<{default_url:string;api_prefix:string;authorization_type:\"bearer\"|\"private-token\";api_url?:string;url?:string;}>": { + "PartialObjectDeep<{default_url:string;api_prefix:string;authorization_type:\"bearer\"|\"private-token\";api_url?:string;url?:string;},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "api_prefix": { "description": "Gitlab api path", @@ -725,11 +746,18 @@ }, "type": "object" }, - "RecursivePartial<{deps_keys:string[];}>": { + "PartialObjectDeep<{deps_keys:(\"dependencies\"|\"devDependencies\"|\"peerDependencies\"|\"optionalDependencies\")[];},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "deps_keys": { "description": "Dependency lists that should be updated and used when package version updates", "items": { + "enum": [ + "dependencies", + "devDependencies", + "optionalDependencies", + "peerDependencies" + ], "type": "string" }, "type": "array" @@ -737,18 +765,8 @@ }, "type": "object" }, - "RecursivePartial<{dryRun:boolean;local:boolean;}>": { - "properties": { - "dryRun": { - "type": "boolean" - }, - "local": { - "type": "boolean" - } - }, - "type": "object" - }, - "RecursivePartial<{enabled:boolean;as_release:boolean;strip_namespace:boolean;}>": { + "PartialObjectDeep<{enabled:boolean;as_release:boolean;strip_namespace:boolean;},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "as_release": { "description": "Add as release in source code platform. Otherwise only as git tag.", @@ -765,14 +783,15 @@ }, "type": "object" }, - "RecursivePartial<{enabled:boolean;path:string;limit:ArtifactLimitDef;storage:StorageDef;}>": { + "PartialObjectDeep<{enabled:boolean;path:string;limit:ArtifactLimitDef;storage:StorageDef;},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "enabled": { "description": "Enable storing releases meta-info in specified storage (right now only git repository is supported)", "type": "boolean" }, "limit": { - "$ref": "#/definitions/ArtifactLimitDef", + "$ref": "#/definitions/PartialObjectDeep", "description": "How to limit entries count in release list" }, "path": { @@ -782,13 +801,13 @@ "storage": { "anyOf": [ { - "$ref": "#/definitions/RepoStorageDef" + "$ref": "#/definitions/PartialObjectDeep" }, { - "$ref": "#/definitions/BranchStorageDef" + "$ref": "#/definitions/PartialObjectDeep" }, { - "$ref": "#/definitions/ExternalStorageDef" + "$ref": "#/definitions/PartialObjectDeep" } ], "description": "Storage settings" @@ -796,7 +815,8 @@ }, "type": "object" }, - "RecursivePartial<{ensure_branch_up_to_date:boolean;tag_only:boolean;}>": { + "PartialObjectDeep<{ensure_branch_up_to_date:boolean;tag_only:boolean;},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "ensure_branch_up_to_date": { "description": "Before pushing changes, check for upstream branch is still actual", @@ -809,7 +829,8 @@ }, "type": "object" }, - "RecursivePartial<{ignore_files:string[];affected_files:{if_changed:string[];then_affected:PkgFlexGlobs;}[];}>": { + "PartialObjectDeep<{ignore_files:string[];affected_files:{if_changed:string[];then_affected:PkgFlexGlobs;}[];},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "affected_files": { "items": { @@ -853,7 +874,8 @@ }, "type": "object" }, - "RecursivePartial<{indent?:number;}>": { + "PartialObjectDeep<{indent?:number;},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "indent": { "description": "Ident for package.json write", @@ -862,21 +884,8 @@ }, "type": "object" }, - "RecursivePartial<{local_plugins:string[];options:Record>;}>": { - "properties": { - "local_plugins": { - "items": { - "type": "string" - }, - "type": "array" - }, - "options": { - "$ref": "#/definitions/RecursivePartial>>" - } - }, - "type": "object" - }, - "RecursivePartial<{maxLen:number;}>": { + "PartialObjectDeep<{maxLen:number;},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "maxLen": { "description": "Max list length, passed to cutList template filter", @@ -885,7 +894,8 @@ }, "type": "object" }, - "RecursivePartial<{name?:string;avatarEmoji?:string;avatarUrl?:string;}>": { + "PartialObjectDeep<{name?:string;avatarEmoji?:string;avatarUrl?:string;},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "avatarEmoji": { "type": "string" @@ -899,7 +909,8 @@ }, "type": "object" }, - "RecursivePartial<{prefix:string;date_format:string;suffixes?:string|string[];}>": { + "PartialObjectDeep<{prefix:string;date_format:string;suffixes?:string|string[];},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "date_format": { "description": "Date follows after prefix, delimited by '-' symbol", @@ -925,15 +936,17 @@ }, "type": "object" }, - "RecursivePartial<{push:{try_load_ssh_keys:boolean;default_branch:string;};}>": { + "PartialObjectDeep<{push:{try_load_ssh_keys:boolean;default_branch:string;};},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "push": { - "$ref": "#/definitions/RecursivePartial<{try_load_ssh_keys:boolean;default_branch:string;}>" + "$ref": "#/definitions/PartialObjectDeep<{try_load_ssh_keys:boolean;default_branch:string;},Opts>" } }, "type": "object" }, - "RecursivePartial<{registry?:string;disabled_for:string[];enabled_only_for:string[];path_subdir?:string;path_mapping?:Record;email?:string;cli_args?:string;process_npm_token?:boolean;include_monorepo_root:boolean;}>": { + "PartialObjectDeep<{registry?:string;disabled_for:string[];enabled_only_for:string[];path_subdir?:string;path_mapping?:Record;email?:string;cli_args?:string;process_npm_token?:boolean;include_monorepo_root:boolean;},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "cli_args": { "description": "Additional cli args string. Passed \"as is\" to `npm publish` command", @@ -963,7 +976,7 @@ "type": "boolean" }, "path_mapping": { - "$ref": "#/definitions/RecursivePartial>", + "$ref": "#/definitions/PartialObjectDeep,Opts>", "description": "By default publish path for each package and package path itself is same thing.\\nBut you can replace the beginning of each package path to another string via providing this argument.\\nExample: 'src/components' => 'lib/components'\"" }, "path_subdir": { @@ -981,17 +994,18 @@ }, "type": "object" }, - "RecursivePartial<{release_tag_package:string;annotation_lookup_depth:number;suffixes:string|string[];generic_tag:{prefix:string;date_format:string;suffixes?:string|string[];};for_packages:{enabled:boolean;as_release:boolean;strip_namespace:boolean;};}>": { + "PartialObjectDeep<{release_tag_package:string;annotation_lookup_depth:number;suffixes:string|string[];generic_tag:{prefix:string;date_format:string;suffixes?:string|string[];};for_packages:{enabled:boolean;as_release:boolean;strip_namespace:boolean;};},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "annotation_lookup_depth": { "description": "How deep to look for the version in the release tags annotations, if no version for the package can be found", "type": "integer" }, "for_packages": { - "$ref": "#/definitions/RecursivePartial<{enabled:boolean;as_release:boolean;strip_namespace:boolean;}>" + "$ref": "#/definitions/PartialObjectDeep<{enabled:boolean;as_release:boolean;strip_namespace:boolean;},Opts>" }, "generic_tag": { - "$ref": "#/definitions/RecursivePartial<{prefix:string;date_format:string;suffixes?:string|string[];}>", + "$ref": "#/definitions/PartialObjectDeep<{prefix:string;date_format:string;suffixes?:string|string[];},Opts>", "description": "To be used only if all conditions are met:\n1. Value `versioning.unified` = false.\n2. Value `tagging.release_tag_package` is not set.\n3. Repository can have packages of different versions according to pvm settings." }, "release_tag_package": { @@ -1015,21 +1029,15 @@ }, "type": "object" }, - "RecursivePartial<{target:string|string[];clients:MessengerClientLoadConfig[];clients_common_config:Partial;client_configs:Record>;}>": { + "PartialObjectDeep<{target:string|string[];clients_common_config:Partial;client_configs:Record>;},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "client_configs": { - "$ref": "#/definitions/RecursivePartial>>", + "$ref": "#/definitions/PartialObjectDeep>,Opts>", "description": "Default message values, each for specific messenger client. Its priority is higher than clients_common_config." }, - "clients": { - "description": "Messenger client load configs", - "items": { - "$ref": "#/definitions/MessengerClientLoadConfig" - }, - "type": "array" - }, "clients_common_config": { - "$ref": "#/definitions/RecursivePartial>", + "$ref": "#/definitions/PartialObjectDeep,Opts>", "description": "Common config which applied to all messenger clients. For example channel name is same in several messengers and you\ndont want to duplicate it" }, "target": { @@ -1049,7 +1057,8 @@ }, "type": "object" }, - "RecursivePartial<{title:string;strip_namespace:boolean;}>": { + "PartialObjectDeep<{title:string;strip_namespace:boolean;},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "strip_namespace": { "type": "boolean" @@ -1060,7 +1069,8 @@ }, "type": "object" }, - "RecursivePartial<{try_load_ssh_keys:boolean;default_branch:string;}>": { + "PartialObjectDeep<{try_load_ssh_keys:boolean;default_branch:string;},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "default_branch": { "description": "Default push branch if you try to\n\ntodo: ask reason for this setting", @@ -1073,7 +1083,8 @@ }, "type": "object" }, - "RecursivePartial<{unified:boolean|string[];unified_versions_for:PkgFlexGlobs[];source:\"file\"|\"package\"|\"tag\";source_file:string;independent_packages:string[];}>": { + "PartialObjectDeep<{unified:boolean|string[];unified_versions_for:(string|string[])[];source:\"file\"|\"tag\"|\"package\";source_file:string;independent_packages:string[];},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "independent_packages": { "description": "Packages who always use independent versioning regardless of `unified_versions_for` or `unified` settings.", @@ -1120,9 +1131,6 @@ "type": "array" }, { - "enum": [ - "*" - ], "type": "string" } ] @@ -1132,7 +1140,8 @@ }, "type": "object" }, - "RecursivePartial<{url?:string;}>": { + "PartialObjectDeep<{url?:string;},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "url": { "description": "jira url. If set, then jira-task ids will be transformed into links.", @@ -1141,10 +1150,11 @@ }, "type": "object" }, - "RecursivePartial<{use_short_names:boolean;setup_script?:string;filters:{cutList:{maxLen:number;};};vars:{[key:string]:string|number;releaseLink?:string;};}>": { + "PartialObjectDeep<{use_short_names:boolean;setup_script?:string;filters:{cutList:{maxLen:number;};};vars:{[key:string]:string|number;releaseLink?:string;};},Opts>": { + "description": "Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.", "properties": { "filters": { - "$ref": "#/definitions/RecursivePartial<{cutList:{maxLen:number;};}>" + "$ref": "#/definitions/PartialObjectDeep<{cutList:{maxLen:number;};},Opts>" }, "setup_script": { "description": "Path to script that can add templates extra variables, filters etc. (See https://mozilla.github.io/nunjucks/templating.html and nunjucks.Environment for more)", @@ -1155,11 +1165,96 @@ "type": "boolean" }, "vars": { - "$ref": "#/definitions/RecursivePartial<{[key:string]:string|number;releaseLink?:string;}>" + "$ref": "#/definitions/PartialObjectDeep<{[key:string]:string|number;releaseLink?:string;},Opts>" } }, "type": "object" }, + "PluginConfig": { + "properties": { + "options": { + "$ref": "#/definitions/PluginOptions" + }, + "plugin": { + "anyOf": [ + { + "allOf": [ + { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + { + "properties": { + "factory": { + "type": "object" + } + }, + "type": "object" + } + ] + }, + { + "allOf": [ + { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + { + "$ref": "#/definitions/{configExt:PartialObjectDeep;}" + } + ] + }, + { + "allOf": [ + { + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + { + "properties": { + "configExt": { + "$ref": "#/definitions/PartialObjectDeep" + }, + "factory": { + "type": "object" + } + }, + "type": "object" + } + ] + }, + { + "type": [ + "string", + "object" + ] + } + ] + } + }, + "type": "object" + }, + "PluginOptions": { + "type": "object" + }, + "Record>": { + "type": "object" + }, + "Record": { + "type": "object" + }, "RepoStorageDef": { "properties": { "dest": { @@ -1174,10 +1269,10 @@ }, "type": "object" }, - "{configExt:RecursivePartial;}": { + "{configExt:PartialObjectDeep;}": { "properties": { "configExt": { - "$ref": "#/definitions/RecursivePartial" + "$ref": "#/definitions/PartialObjectDeep" } }, "type": "object" @@ -1220,6 +1315,12 @@ "deps_keys": { "description": "Dependency lists that should be updated and used when package version updates", "items": { + "enum": [ + "dependencies", + "devDependencies", + "optionalDependencies", + "peerDependencies" + ], "type": "string" }, "type": "array" @@ -1231,7 +1332,7 @@ "description": "Options that need more attention in terms of the consequences of their activation.", "properties": { "always_changed_workspaces": { - "description": "A glob mask array that defines the packets that the system will interpret as always modified.\nThe mask will be applied to the path of the packages (workspaces).\nThis setting will affect the following places:\n- getPackages method in '@pvm/pvm' (except 'released' and 'updated' types)\n- getUpdateState method in '@pvm/update', which affects pvm-update or pvm-release commands", + "description": "A glob mask array that defines the packets that the system will interpret as always modified.\nThe mask will be applied to the path of the packages (workspaces).\nThis setting will affect the following places:\n- getPackages method in '@pvm/pvm' (except 'released' and 'updated' types)\n- pvm-update or pvm-release commands and update mechanic", "items": { "type": "string" }, @@ -1350,10 +1451,7 @@ "$ref": "#/definitions/ChangelogRendererBuiltin" }, { - "$ref": "#/definitions/ChangelogRendererCommonJs" - }, - { - "$ref": "#/definitions/ChangelogRendererByPlugin" + "$ref": "#/definitions/ChangelogRendererCustom" } ], "description": "Changelog render settings" @@ -1368,13 +1466,6 @@ "$ref": "#/definitions/Record>", "description": "Default message values, each for specific messenger client. Its priority is higher than clients_common_config." }, - "clients": { - "description": "Messenger client load configs", - "items": { - "$ref": "#/definitions/MessengerClientLoadConfig" - }, - "type": "array" - }, "clients_common_config": { "$ref": "#/definitions/Partial", "description": "Common config which applied to all messenger clients. For example channel name is same in several messengers and you\ndont want to duplicate it" @@ -1449,20 +1540,6 @@ }, "type": "object" }, - "plugins": { - "properties": { - "local_plugins": { - "items": { - "type": "string" - }, - "type": "array" - }, - "options": { - "$ref": "#/definitions/Record>" - } - }, - "type": "object" - }, "plugins_v2": { "items": { "$ref": "#/definitions/PluginConfig" @@ -1637,6 +1714,9 @@ "type": "object" }, "templates": { + "additionalProperties": { + "type": "string" + }, "description": "Templates\nSee https://mozilla.github.io/nunjucks/templating.html for template engine docs\nSee packages/pvm-template/lib/env.ts for extra filters and variables", "properties": { "failed_vcs_push": { @@ -1902,9 +1982,6 @@ "type": "array" }, { - "enum": [ - "*" - ], "type": "string" } ] diff --git a/packages/pvm-types/lib/config-schema.ts b/packages/pvm/types/config-schema.ts similarity index 95% rename from packages/pvm-types/lib/config-schema.ts rename to packages/pvm/types/config-schema.ts index 30aa8be64..7aff2fffd 100644 --- a/packages/pvm-types/lib/config-schema.ts +++ b/packages/pvm/types/config-schema.ts @@ -1,4 +1,4 @@ -import type { MessengerClientConfig } from './index' +import type { MessengerClientConfig } from './messages' import type { PluginConfig } from './di' type GlobPattern = string @@ -29,18 +29,11 @@ export interface ChangelogRendererBuiltin { show_date: boolean, } -export interface ChangelogRendererCommonJs { - type: 'commonjs', - path: string, -} - -export interface ChangelogRendererByPlugin { - type: 'by-plugin', - // should start with "changelog." - providesPath: string, +export interface ChangelogRendererCustom { + type: 'custom', } -export type ChangelogRenderer = ChangelogRendererBuiltin | ChangelogRendererCommonJs | ChangelogRendererByPlugin +export type ChangelogRenderer = ChangelogRendererBuiltin | ChangelogRendererCustom export interface ArtifactLimitDef { type: 'time' | 'size', @@ -109,7 +102,7 @@ export interface Config { * List of groups, each group is a list of globs or just one glob string for workspace paths, where each of group have own unified versioning. * If you want unified versioning for whole repository, choose ['*'] value or better set `unified` setting to true. */ - unified_versions_for: PkgFlexGlobs[], + unified_versions_for: Array, /** * Where do the versions come from. Also affects the way the versions are saved. See versioning section in documentation for more info. */ @@ -220,7 +213,7 @@ export interface Config { /** * Dependency lists that should be updated and used when package version updates */ - deps_keys: Array<'dependencies' | 'devDependencies' | 'peerDependencies' | 'optionalDependencies' | string>, + deps_keys: Array<'dependencies' | 'devDependencies' | 'peerDependencies' | 'optionalDependencies'>, }, pkgset: { /** @@ -415,13 +408,6 @@ export interface Config { */ renderer: ChangelogRenderer, }, - /** - * @deprecated please use [plugins_v2](/api/interfaces/pvm_types.Config.md#plugins_v2) - */ - plugins: { - local_plugins: string[], - options: Record>, - }, plugins_v2: PluginConfig[], templating: { /** @@ -451,6 +437,7 @@ export interface Config { * See packages/pvm-template/lib/env.ts for extra filters and variables */ templates: { + [key: string]: string, /** * todo: Привести к единому формату нейминга (дефисы в нижнее подчеркивание) */ @@ -527,10 +514,6 @@ export interface Config { * not sent to messenger you expect to - look at log output */ target: 'all' | 'first_available' | Array | MessengerName, - /** - * Messenger client load configs - */ - clients: Array, /** * Common config which applied to all messenger clients. For example channel name is same in several messengers and you * dont want to duplicate it @@ -550,7 +533,7 @@ export interface Config { * The mask will be applied to the path of the packages (workspaces). * This setting will affect the following places: * - getPackages method in '@pvm/pvm' (except 'released' and 'updated' types) - * - getUpdateState method in '@pvm/update', which affects pvm-update or pvm-release commands + * - pvm-update or pvm-release commands and update mechanic */ always_changed_workspaces?: string[], }, diff --git a/packages/pvm-types/lib/config.ts b/packages/pvm/types/config.ts similarity index 77% rename from packages/pvm-types/lib/config.ts rename to packages/pvm/types/config.ts index 99cba5d83..6cb2f925b 100644 --- a/packages/pvm-types/lib/config.ts +++ b/packages/pvm/types/config.ts @@ -6,8 +6,4 @@ export type Config = ConfigSchema & { * @deprecated needs for backward compatibility with old plugin loading system */ configLookupDir: string, - executionContext: { - dryRun: boolean, - local: boolean, - }, } diff --git a/packages/pvm/types/conventional-commit.ts b/packages/pvm/types/conventional-commit.ts new file mode 100644 index 000000000..94d48150d --- /dev/null +++ b/packages/pvm/types/conventional-commit.ts @@ -0,0 +1,93 @@ +type CCField = string | null; + +interface CCNote { + title: string, + text: string, +} + +interface CCReference { + issue: string, + + /** + * @default + * null + */ + action: CCField, + + /** + * @default + * null + */ + owner: CCField, + + /** + * @default + * null + */ + repository: CCField, + + prefix: string, + raw: string, +} + +interface CCRevert { + hash?: CCField | undefined, + header?: CCField | undefined, + [field: string]: CCField | undefined, +} + +interface BaseConventionalCommit { + /** + * @default + * null + */ + merge: CCField, + + /** + * @default + * null + */ + header: CCField, + + /** + * @default + * null + */ + body: CCField, + + /** + * @default + * null + */ + footer: CCField, + + /** + * @default + * [] + */ + notes: CCNote[], + + /** + * @default + * [] + */ + references: CCReference[], + + /** + * @default + * [] + */ + mentions: string[], + + /** + * @default + * null + */ + revert: CCRevert | null, + + type?: CCField | undefined, + scope?: CCField | undefined, + subject?: CCField | undefined, +} + +export type ConventionalCommit = BaseConventionalCommit & { [Field in Exclude]?: CCField }; diff --git a/packages/pvm-types/lib/di.ts b/packages/pvm/types/di.ts similarity index 83% rename from packages/pvm-types/lib/di.ts rename to packages/pvm/types/di.ts index f9cfb393f..bb0ff860f 100644 --- a/packages/pvm-types/lib/di.ts +++ b/packages/pvm/types/di.ts @@ -1,6 +1,6 @@ import type { Provider } from '@tinkoff/dippy' -import type { Config } from './config' -import type { RecursivePartial } from './utils' +import type { Config } from './config-schema' +import type { RecursivePartial } from './helpers' export type PluginOptions = Record diff --git a/packages/pvm-types/lib/env-schema.json b/packages/pvm/types/env-schema.json similarity index 100% rename from packages/pvm-types/lib/env-schema.json rename to packages/pvm/types/env-schema.json diff --git a/packages/pvm-types/lib/env-schema.ts b/packages/pvm/types/env-schema.ts similarity index 100% rename from packages/pvm-types/lib/env-schema.ts rename to packages/pvm/types/env-schema.ts diff --git a/packages/pvm-types/lib/git.ts b/packages/pvm/types/git.ts similarity index 100% rename from packages/pvm-types/lib/git.ts rename to packages/pvm/types/git.ts diff --git a/packages/pvm-types/lib/global.ts b/packages/pvm/types/global.ts similarity index 100% rename from packages/pvm-types/lib/global.ts rename to packages/pvm/types/global.ts diff --git a/packages/pvm/types/helpers.ts b/packages/pvm/types/helpers.ts new file mode 100644 index 000000000..abf3483ad --- /dev/null +++ b/packages/pvm/types/helpers.ts @@ -0,0 +1,7 @@ +import type { PartialDeep } from 'type-fest/source/partial-deep' + +type Opts = { + recurseIntoArrays: false, +} + +export type RecursivePartial = PartialDeep diff --git a/packages/pvm/types/host-api.ts b/packages/pvm/types/host-api.ts new file mode 100644 index 000000000..0ed9419f4 --- /dev/null +++ b/packages/pvm/types/host-api.ts @@ -0,0 +1,16 @@ +import type { Commit } from './git' +import type { Pkg } from '../lib/pkg' +import type { PvmReleaseType, SemverReleaseType } from './publish' +import type { ChangedContext } from '../mechanics/update/changed-context' +import type { VcsPlatform } from '../mechanics/vcs' +import type { ReleaseContext } from '../mechanics/update/types' +import type { ReleaseData, ReleaseDataExt } from '../mechanics/releases/types' +import type { UpdateState } from '../mechanics/update/update-state' + +export interface HostApi { + commitsToNotes(commits: Commit[], maybePkg?: Pkg | void): Promise, + releaseTypeByCommits(commits: Commit[], defaultValue?: SemverReleaseType | null): Promise, + releaseType(pkg: Pkg, changedContext: ChangedContext): Promise, + preReleaseHook(vcs: VcsPlatform, releaseContext: ReleaseContext): Promise, + attributeReleaseData(releaseData: ReleaseData, updateState: UpdateState | null): Promise, +} diff --git a/packages/pvm-types/lib/index.ts b/packages/pvm/types/index.ts similarity index 79% rename from packages/pvm-types/lib/index.ts rename to packages/pvm/types/index.ts index 398ee16ed..c3fab8b98 100644 --- a/packages/pvm-types/lib/index.ts +++ b/packages/pvm/types/index.ts @@ -8,5 +8,7 @@ export * from './pkg-meta' export * from './publish' export * from './shell' export * from './di' -export * from './platform' export * from './vcs' +export * from './host-api' +export * from './cli' +export * from './conventional-commit' diff --git a/packages/pvm-types/lib/messages.ts b/packages/pvm/types/messages.ts similarity index 100% rename from packages/pvm-types/lib/messages.ts rename to packages/pvm/types/messages.ts diff --git a/packages/pvm-types/lib/pkg-meta.ts b/packages/pvm/types/pkg-meta.ts similarity index 96% rename from packages/pvm-types/lib/pkg-meta.ts rename to packages/pvm/types/pkg-meta.ts index 34a4527a1..00bacec83 100644 --- a/packages/pvm-types/lib/pkg-meta.ts +++ b/packages/pvm/types/pkg-meta.ts @@ -13,6 +13,7 @@ export interface MetaRepository { export interface PkgMeta { version?: string, + description?: string, initialVersion?: string, name: string, dependencies?: PkgDeps, diff --git a/packages/pvm-types/lib/publish.ts b/packages/pvm/types/publish.ts similarity index 80% rename from packages/pvm-types/lib/publish.ts rename to packages/pvm/types/publish.ts index 2f66d0071..ac16367d4 100644 --- a/packages/pvm-types/lib/publish.ts +++ b/packages/pvm/types/publish.ts @@ -1,5 +1,5 @@ import type { Commit } from './git' -import type { Config } from './config' +import type { Config, Message } from '../types' export interface PkgSuccessStats { pkg: string, @@ -46,5 +46,13 @@ export interface UpdateHints { 'update-dependants-for'?: Array<{ match: string, 'release-type': PvmReleaseType | 'as-dep', + 'max-depth'?: number, }>, + 'force-release'?: { + packages: string[], + 'release-type'?: PvmReleaseType, + 'release-notes'?: string, + }, } + +export type ReleaseMessageGenerator = (releasedProps: ReleasedProps) => Promise diff --git a/packages/pvm-types/lib/shell.ts b/packages/pvm/types/shell.ts similarity index 100% rename from packages/pvm-types/lib/shell.ts rename to packages/pvm/types/shell.ts diff --git a/packages/pvm/types/utils.ts b/packages/pvm/types/utils.ts new file mode 100644 index 000000000..4b8b12c36 --- /dev/null +++ b/packages/pvm/types/utils.ts @@ -0,0 +1,15 @@ +type BuildTupleHelper = + Rest['length'] extends Length ? + readonly [...Rest] : // Terminate with readonly array (aka tuple) + BuildTupleHelper; + +export type ReadonlyTuple = + number extends Length + // Because `Length extends number` and `number extends Length`, then `Length` is not a specific finite number. + ? readonly Element[] // It's not fixed length. + : BuildTupleHelper; // Otherwise it is a fixed length tuple. + +export type UnionTupleSpread = + Rest['length'] extends Size ? + readonly [...Rest] : // Terminate with readonly array (aka tuple) + ReadonlyTuple | UnionTupleSpread; diff --git a/packages/pvm-types/lib/vcs.ts b/packages/pvm/types/vcs.ts similarity index 94% rename from packages/pvm-types/lib/vcs.ts rename to packages/pvm/types/vcs.ts index 21ee389da..d343fa741 100644 --- a/packages/pvm-types/lib/vcs.ts +++ b/packages/pvm/types/vcs.ts @@ -38,6 +38,7 @@ export interface PushOptions { skipCi?: boolean, noTags?: boolean, pushOptions?: Map, + dryRun?: boolean, } export interface PlatformReleaseTag { @@ -50,6 +51,10 @@ export interface MetaComment { note: Note, } +export interface AddTagOptions { + annotation?: string | null, +} + export interface FileCommitApi { addFiles(commitContext: TCommitContext, filePaths: string[]): void, appendFile(commitContext: TCommitContext, filePath: string, content: string): void, @@ -62,9 +67,8 @@ export interface FileCommitApi { export interface AbstractVcs extends FileCommitApi { fetchLatestSha(refName: string): Promise, - addTag(tag_name: string, ref: string): Promise, + addTag(tag_name: string, ref: string, opts: AddTagOptions): Promise, push(opts?: PushOptions): Promise, - dryRun(): void, getCurrentBranch(): string | void, getHeadRev(): string, isLastAvailableRef(rev: string): boolean, @@ -79,10 +83,6 @@ export interface PlatformRelease { description: string, } -export interface AddTagOptions { - annotation?: string | null, -} - export type GetReleaseResult = [PlatformResult.OK, PlatformRelease] | [PlatformResult.NOT_FOUND | PlatformResult.NO_SUCH_TAG, null] // eslint-disable-next-line @typescript-eslint/no-empty-interface @@ -91,7 +91,6 @@ export interface UnknownCommitContext { } export interface VcsOnly { - isDryRun: boolean, cwd: string, beginCommit(): UnknownCommitContext, rollbackCommit(commitContext: UnknownCommitContext): Promise, @@ -104,3 +103,7 @@ export interface VcsOnly { push(opts?: PushOptions): Promise, addTag(tagName: string, ref: string, opts?: AddTagOptions): Promise, } + +export interface PushError extends Error { + context: 'push', +} diff --git a/scripts/perf/create-report-comment.js b/scripts/perf/create-report-comment.js index 2de1769d3..2f7129a8d 100644 --- a/scripts/perf/create-report-comment.js +++ b/scripts/perf/create-report-comment.js @@ -1,5 +1,4 @@ -const { Pvm } = require('@pvm/pvm') -const { PLATFORM_TOKEN } = require('@pvm/tokens-core') +const { Pvm, PLATFORM_TOKEN } = require('@pvm/pvm') const fs = require('fs') async function main() { diff --git a/scripts/perf/run.js b/scripts/perf/run.js index b4849ed22..d62800ef4 100644 --- a/scripts/perf/run.js +++ b/scripts/perf/run.js @@ -2,7 +2,7 @@ const got = require('got') const fs = require('fs-extra') const path = require('path') const Handlebars = require('handlebars') -const initRepo = require('../../test/initRepo') +const initRepo = require('../../test/initRepo').default const { writeRepo } = require('../../test/writeRepo') const { start, stop } = require('../../test/gl-api-mock') const yargs = require('yargs') @@ -74,7 +74,7 @@ ${versions.map(p => p.split('/')[1]).join('\n')}`) GL_TOKEN: '___gl___', PVM_TESTING_ENV: process.env.PVM_TESTING_ENV ?? 'true', NPM_TOKEN: '123', - PVM_CONFIG_PLUGINS_V2: JSON.stringify([{ plugin: require.resolve('@pvm/gitlab/plugin') }]), + PVM_CONFIG_PLUGINS_V2: JSON.stringify([{ plugin: require.resolve('@pvm/plugin-gitlab') }]), PVM_CONFIG_GITLAB__URL: `http://localhost:${gitlabApp.httpServer.address().port}`, }, }) diff --git a/src/libs/di/README.md b/src/libs/di/README.md deleted file mode 100644 index 9922f5c41..000000000 --- a/src/libs/di/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# @pvm/di - -Intermediate module for [@tinkoff/dippy](https://www.npmjs.com/package/@tinkoff/dippy) that is used for di functionality providing \ No newline at end of file diff --git a/src/libs/di/index.ts b/src/libs/di/index.ts deleted file mode 100644 index 7c2162aa2..000000000 --- a/src/libs/di/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { Config, PluginFactory, RecursivePartial } from '@pvm/types' - -export * from '@tinkoff/dippy' - -export function declarePlugin(opts: { configExt: RecursivePartial, factory: PluginFactory} | { factory: PluginFactory} | { configExt: RecursivePartial}) { - return { - name: __filename, - ...opts, - } -} diff --git a/src/libs/di/package.json b/src/libs/di/package.json deleted file mode 100644 index 1f59b279a..000000000 --- a/src/libs/di/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "@pvm/di", - "version": "0.0.0-stub", - "exports": "./index.js", - "dependencies": { - "@pvm/types": "0.0.0-stub", - "@tinkoff/dippy": "^0.8.6" - } -} diff --git a/src/plugins/common-plugins/README.md b/src/plugins/common-plugins/README.md deleted file mode 100644 index 4dbe978ca..000000000 --- a/src/plugins/common-plugins/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# @pvm/plugin-common-plugins - -Provides set of common plugins, that should always be included \ No newline at end of file diff --git a/src/plugins/common-plugins/index.ts b/src/plugins/common-plugins/index.ts deleted file mode 100644 index eec062531..000000000 --- a/src/plugins/common-plugins/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { declarePlugin } from '@pvm/di' - -export default declarePlugin({ - configExt: { - plugins_v2: [ - { plugin: require.resolve('@pvm/plugin-core') }, - { plugin: require.resolve('@pvm/update/plugin') }, - { plugin: require.resolve('@pvm/pkgset/plugin') }, - { plugin: require.resolve('@pvm/releases/plugin') }, - { plugin: require.resolve('@pvm/artifacts/plugin') }, - { plugin: require.resolve('@pvm/vcs/plugin') }, - { plugin: require.resolve('@pvm/viz/plugin') }, - { plugin: require.resolve('@pvm/files/plugin') }, - { plugin: require.resolve('@pvm/changelog/plugin') }, - { plugin: require.resolve('@pvm/add-tag/plugin') }, - { plugin: require.resolve('@pvm/notifications/plugin') }, - ], - }, -}) diff --git a/src/plugins/common-plugins/package.json b/src/plugins/common-plugins/package.json deleted file mode 100644 index 5b6613ccf..000000000 --- a/src/plugins/common-plugins/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "@pvm/plugin-common-plugins", - "description": "temporal package that will be removed as soon as single entrypoint will be reached", - "version": "0.0.0-stub", - "exports": "./index.js", - "dependencies": { - "@pvm/di": "0.0.0-stub", - "@pvm/plugin-core": "0.0.0-stub", - "@pvm/update": "0.0.0-stub", - "@pvm/pkgset": "0.0.0-stub", - "@pvm/viz": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", - "@pvm/releases": "0.0.0-stub", - "@pvm/artifacts": "0.0.0-stub", - "@pvm/changelog": "0.0.0-stub", - "@pvm/add-tag": "0.0.0-stub", - "@pvm/files": "0.0.0-stub", - "@pvm/notifications": "0.0.0-stub" - } -} diff --git a/src/plugins/core/README.md b/src/plugins/core/README.md deleted file mode 100644 index a0848488a..000000000 --- a/src/plugins/core/README.md +++ /dev/null @@ -1 +0,0 @@ -# @pvm/plugin-base-commands \ No newline at end of file diff --git a/src/plugins/core/__tests__/cli.spec.ts b/src/plugins/core/__tests__/cli.spec.ts deleted file mode 100644 index edd0c626c..000000000 --- a/src/plugins/core/__tests__/cli.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Pvm } from '@pvm/core/lib/app' -import { CLI_EXTENSION_TOKEN, CLI_TOKEN } from '@pvm/tokens-core' -import { provide } from '@pvm/di' - -describe('@pvm/cli', () => { - it('should run provided command', () => { - let outputStore = '' - const pvm = new Pvm({ - plugins: [{ - plugin: () => ({ - providers: [provide({ - provide: CLI_EXTENSION_TOKEN, - useValue: { - command: 'cli-test', - description: 'test command', - handler: () => { - outputStore = 'command works!\n' - process.stdout.write(outputStore) - }, - }, - multi: true, - })], - }), - }], - }) - - pvm.container.get(CLI_TOKEN)({ argv: ['node.exe', 'path-to-script.js', 'cli-test'] }) - - expect(outputStore).toBe('command works!\n') - }) -}) diff --git a/src/plugins/core/commands/pvm-lint.ts b/src/plugins/core/commands/pvm-lint.ts deleted file mode 100644 index db7f76fbf..000000000 --- a/src/plugins/core/commands/pvm-lint.ts +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env node -import { Repository } from '@pvm/repository/lib' -import { logger } from '@pvm/core/lib/logger' -import { lint } from '@pvm/repository/lib/linter' - -export const command = 'lint' -export const description = 'Checks that package versions correspond to the selected settings and policies in the project.' -export const builder = { - fix: { - default: false, - desc: 'Automatically fix found bugs or versions if possible', - }, -} - -export const handler = async (flags) => { - const repo = await Repository.init(process.cwd()) - const lintResult = lint(repo, { - fix: flags.fix, - }) - - if (!lintResult.errors.length) { - logger.info('all checks passed') - } else { - lintResult.errors.forEach(error => { - logger.error(error) - }) - process.exitCode = 1 - } -} diff --git a/src/plugins/core/commands/pvm-mark-pr.ts b/src/plugins/core/commands/pvm-mark-pr.ts deleted file mode 100644 index a5eeb9488..000000000 --- a/src/plugins/core/commands/pvm-mark-pr.ts +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env node -import { getHostApi } from '@pvm/core/lib/plugins' -import { getUpdateState } from '@pvm/update/lib' -import type { Vcs } from '@pvm/vcs/lib' -import { initVcsPlatform } from '@pvm/vcs/lib' -import { getConfig } from '@pvm/core/lib/config' -import * as mdTable from '@pvm/update/lib/update-methods/md-table' -import * as graphDot from '@pvm/update/lib/update-methods/dot' -import { analyzeUpdate as analyzeUpdatedPackages } from '@pvm/update/lib/update-methods/analyze' -import { renderDot } from '@pvm/viz/lib' -import { renderReleaseContext, RenderTarget } from '@pvm/changelog/lib' -import { createReleaseContext } from '@pvm/update/lib/release/release-context' -import { VcsOnlyStenographer } from '@pvm/vcs/lib/vcs-only-stenographer' - -import type { UpdateState } from '@pvm/update/lib/update-state' -import type { Pkg } from '@pvm/core/lib/pkg' - -export const command = 'mark-pr' -export const description = `Marks merge or pull request by project labels, packages about to update, etc` -export const handler = main - -async function analyzeUpdate(vcs: Vcs, updateState: UpdateState): Promise { - const { warnings } = analyzeUpdatedPackages(updateState) - - if (warnings.length !== 0) { - const warningsAsList = warnings.map(warning => `- ${warning}`).join('\n') - await vcs.syncText('analyze-report', ` -**Dependencies between packages after update can lead to malfunctioning when installing dependencies or building a project.** - -${warningsAsList} -` - ) - } else { - await vcs.syncText('analyze-report', 'Dependencies between packages looks good.') - } -} - -async function packagesAsLabels(vcs: Vcs, updateState: UpdateState): Promise { - return vcs.ensureMrLabels(Array.from(updateState.getReleasePackages().keys()).map((pkg: Pkg) => pkg.shortName)) -} - -async function packagesTable(vcs: Vcs, updateState: UpdateState): Promise { - const md = await mdTable.run(updateState) - return vcs.syncText('packages-for-release', md || 'no packages for release') -} - -async function packagesGraph(vcs: Vcs, updateState: UpdateState): Promise { - if (!updateState.isSomethingForRelease) { - return vcs.syncText('packages-graph', 'no packages for release') - } - const dot = await graphDot.updateStateToDot(updateState) - const svg: string = await renderDot(dot) - await vcs.syncAttachment('packages-graph', Buffer.from(svg), { - filename: 'packages-graph.svg', - }) -} - -async function attachChangelog(vcs: Vcs, updateState: UpdateState): Promise { - const releaseContext = await createReleaseContext(updateState) - const changelog = releaseContext ? await renderReleaseContext(releaseContext, RenderTarget.markPr) : '' - return vcs.syncText('changelog-for-pr', changelog) -} - -async function attachMigrationProcess(vcs: Vcs): Promise { - const vcsStenographist = new VcsOnlyStenographer(vcs.cwd) - - if (!vcsStenographist.isEmpty) { - await vcs.syncText('pvm configuration migration transcript', vcsStenographist.join()) - } -} - -interface Marker { - fn(vcs: Vcs, updateState: UpdateState): Promise, - confKey: string, -} - -const markers: Marker[] = [ - { - fn: analyzeUpdate, - confKey: 'analyze_update', - }, - { - fn: packagesAsLabels, - confKey: 'packages_as_labels', - }, - { - fn: packagesTable, - confKey: 'packages_table', - }, - { - fn: packagesGraph, - confKey: 'packages_graph', - }, - { - fn: attachChangelog, - confKey: 'attach_changelog', - }, -] - -async function main(): Promise { - const conf = (await getConfig()).mark_pr - const hostApi = await getHostApi() - const vcs = await initVcsPlatform() - await vcs.beginMrAttribution() - - await attachMigrationProcess(vcs) - - const updateState = await getUpdateState() - - for (const marker of markers) { - if (conf[marker.confKey]) { - await marker.fn(vcs, updateState) - } - } - - await hostApi.plEachSeries('mark-pr', vcs, updateState) -} diff --git a/src/plugins/core/commands/pvm-notes.ts b/src/plugins/core/commands/pvm-notes.ts deleted file mode 100644 index 23f4e01b5..000000000 --- a/src/plugins/core/commands/pvm-notes.ts +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env node - -// команда обновляет release notes для последнего тэга через vcs - -import { getConfig } from '@pvm/core/lib/config' -import { log } from '@pvm/core/lib/logger' -import initVcs from '@pvm/vcs' -import { lastReleaseTag } from '@pvm/core/lib/git/last-release-tag' -import getPreviousRefForFirstRelease from '@pvm/core/lib/behaviors/previous-ref-for-initial-release' -import { makeReleaseForTagName } from '@pvm/core/lib/release-notes' -import { env } from '@pvm/core/lib/env' - -export const command = 'notes' -export const description = 'Create release notes for latest release tag based on commit messages between tags' -export const handler = pvmNotes - -async function findPrevRef(targetTag: string) { - const config = await getConfig() - const prevRelease = lastReleaseTag(config, `${targetTag}^`) - - const prevRef = prevRelease || getPreviousRefForFirstRelease(config, targetTag) - - log(`previous release is ${prevRelease || ''}`) - - return prevRef -} - -async function pvmNotes() { - const config = await getConfig() - const targetTagName = env.CI_COMMIT_TAG || lastReleaseTag(config) - const vcs = await initVcs() - - if (!targetTagName) { - throw new Error('at least one tag is required for making the release') - } - - const prevRef = await findPrevRef(targetTagName) - if (prevRef) { - await makeReleaseForTagName(vcs, targetTagName, prevRef, { - skipIfExists: true, - }) - - return targetTagName - } - return false -} diff --git a/src/plugins/core/commands/pvm-packages.ts b/src/plugins/core/commands/pvm-packages.ts deleted file mode 100644 index a3c783100..000000000 --- a/src/plugins/core/commands/pvm-packages.ts +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env node -import pprint from '@pvm/pkgset/lib/pprint' -import { getPackages } from '../packages' - -export const command = 'packages' -export const description = 'Shows the list of packages by the specified criterion' -export const builder = { - format: { - desc: `Pretty-print the package information in a given format. Format is string, with special symbols: - %p - path to package - %n - package name - %s - package name without namespace if it's present - %v - package version`, - default: '%p', - }, - list: { - desc: 'kind of packages to show', - // connected with type PackagesType in ../../lib/packages.ts - choices: ['about-to-update', 'update', 'changed', 'changed-since-release', 'affected', 'released', 'updated', 'all'], - default: 'all', - }, - filter: { - desc: `filter output by "packages filter". You can filter by package names, or by package paths starting filter with "/" symbol.`, - type: 'array' as const, - default: [], - }, -} -export const handler = main - -async function * iterateFromPromise(willBeList: Promise>): AsyncIterable { - const list = await willBeList - for (const item of list) { - yield item - } -} - -async function main(flags) { - for await (const line of pprint(iterateFromPromise(getPackages(flags.list, { filter: flags.filter })), flags.format)) { - console.log(line) - } -} diff --git a/src/plugins/core/commands/pvm-publish.ts b/src/plugins/core/commands/pvm-publish.ts deleted file mode 100644 index 268114f38..000000000 --- a/src/plugins/core/commands/pvm-publish.ts +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env node - -import { publish } from '../publish' -import { flagsBuilder } from '../publish/flags' -import type { Flags } from '../publish/flags' - -export const command = 'publish' -export const description = 'Publish packages to npm registry' -export const builder = flagsBuilder - -export const handler = async function(flags: Flags): Promise { - const publishStats = await publish(flags) - - if (publishStats.error?.length) { - process.exitCode = 1 - } -} diff --git a/src/plugins/core/commands/pvm-rewrite-notes.ts b/src/plugins/core/commands/pvm-rewrite-notes.ts deleted file mode 100644 index 30fa2430d..000000000 --- a/src/plugins/core/commands/pvm-rewrite-notes.ts +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env node - -import { log } from '@pvm/core/lib/logger' -import initVcs from '@pvm/vcs' -import { getConfig } from '@pvm/core/lib/config' -import getPreviousRefForFirstRelease from '@pvm/core/lib/behaviors/previous-ref-for-initial-release' -import { makeReleaseForTag } from '@pvm/core/lib/release-notes' -import type { PlatformReleaseTag } from '@pvm/vcs/types/index' - -export const command = 'rewrite-notes' -export const description = 'Recalculate and rewrite release notes for particular range of git tags' -export const builder = { - 'skip-first': { - desc: 'Do not overwrite release notes for first release tag', - default: false, - }, - 'only-for': { - desc: 'Overwrite release notes only for defined tag', - }, - 'stop-at': { - desc: 'Stop rewriting release notes on defined tag', - }, - 'dry-run': { - desc: '`Generate notes but not persist changes to vcs', - }, -} - -export const handler = pvmRewriteNotes - -async function pvmRewriteNotes(flags) { - const vcs = await initVcs({ dryRun: flags.dryRun }) - let nextReleaseTag: PlatformReleaseTag | null = null - - // идем от самого свежего к первому - for await (const releaseTag of vcs.releaseTagsIterator()) { - if (nextReleaseTag && (!flags.onlyFor || flags.onlyFor === nextReleaseTag.name)) { - if (flags.stopAt === nextReleaseTag.name) { - log(`You asked me stop at ${flags.stopAt}. Stopping now`) - break - } - await makeReleaseForTag(vcs, nextReleaseTag, releaseTag.name) - if (flags.onlyFor === nextReleaseTag.name) { - break - } - } - - nextReleaseTag = releaseTag - } - - if (!flags.skipFirst && nextReleaseTag && - (!flags.onlyFor || flags.onlyFor === nextReleaseTag.name) && flags.stopAt !== nextReleaseTag.name) { - const config = await getConfig() - await makeReleaseForTag( - vcs, - nextReleaseTag, - getPreviousRefForFirstRelease(config, nextReleaseTag.name) - ) - } -} diff --git a/src/plugins/core/commands/pvm-set-versions.ts b/src/plugins/core/commands/pvm-set-versions.ts deleted file mode 100644 index 5b3d21f32..000000000 --- a/src/plugins/core/commands/pvm-set-versions.ts +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env node - -import { setVersions } from '../set-versions' - -export const command = 'set-versions ' -export const description = 'Set given version for given packages' -export const builder = (yargs) => { - return yargs - .example('$0 set-versions minor -p src/components/*', 'Bump version for given packages') - .example('$0 set-versions 0.0.1 -u', 'Set version 0.0.1 for all packages and also update dependencies') - .options({ - strategy: { - alias: 's', - desc: 'Which packages we should peek up in the first place. See pvm-pkgset --help for details.', - default: 'all', - }, - 'update-dependants': { - alias: 'u', - desc: 'Update dependencies for dependants as well', - default: false, - }, - 'bump-dependants': { - alias: 'b', - desc: 'Update versions for dependants', - default: false, - }, - 'strategy-option': { - alias: 'X', - desc: 'Options for used strategy', - type: 'array' as const, - }, - 'filter-path': { - alias: 'p', - desc: `Filter packages by path. Globbing is supported. You can pass this option multiple times. Example: -p "src/co-*"`, - type: 'array' as const, - }, - }) -} - -export const handler = main - -async function main(argv): Promise { - return setVersions(argv) -} diff --git a/src/plugins/core/commands/pvm-show.ts b/src/plugins/core/commands/pvm-show.ts deleted file mode 100644 index 7b2f59bf9..000000000 --- a/src/plugins/core/commands/pvm-show.ts +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env node -import * as TOML from '@iarna/toml' - -import { wdShell } from '@pvm/core/lib/shell' -import { getConfig } from '@pvm/core/lib/config' -import { error } from '@pvm/core/lib/logger' -import { lastReleaseTag } from '@pvm/core/lib/git/last-release-tag' -import { releaseCommitsAsString } from '@pvm/core/lib/git/release-commits' -import sinceLastRelease from '@pvm/update/lib/strategies/since-last-release' -import { Repository } from '@pvm/repository' - -import type { Argv } from 'yargs' - -function pprint(val): void { - if (val === void 0) { - return - } - let pval = val - if (Array.isArray(pval)) { - pval = val.join('\n') - } else if (typeof val === 'object' && val) { - pval = JSON.stringify(val) - } - console.log(pval) -} - -function asyncPrint(fn) { - return (...args) => { - return Promise.resolve(fn(...args)) - .then(result => { - pprint(result) - }) - .catch(e => { - process.exitCode = 1 - error(e) - }) - } -} - -async function resolveLastReleaseTag(): Promise { - const config = await getConfig() - return lastReleaseTag(config) -} - -async function printChangelog(flags) { - const config = await getConfig() - const release = flags.release || 'HEAD' - let targetRef = release - const latestReleaseTag = lastReleaseTag(config, release) - const cwd = config.cwd - - if (wdShell(cwd, `git rev-list -1 ${latestReleaseTag}`) === wdShell(cwd, `git rev-list -1 ${release}`)) { - targetRef = `${release}^` - } - - const repo = new Repository(cwd, config) - const hostApi = await repo.getHostApi() - - const changedContext = await sinceLastRelease(targetRef, { - cwd, - }) - - return hostApi.commitsToNotes(changedContext.commits) -} - -async function releaseCommitsCommand(args): Promise { - const config = await getConfig() - return releaseCommitsAsString(config, { - target: args.release || 'HEAD', - format: args.format, - }) -} - -async function showConfig(): Promise { - const config = await getConfig(process.cwd()) - return TOML.stringify(config as { [key: string]: any }) -} - -export const command = 'show ' -export const description = 'show various information for repository' -export const builder = (yargs: Argv) => { - return yargs - .command(['last-release-tag', 'lrt'], `show name of latest release tag`, {}, asyncPrint(resolveLastReleaseTag)) - .command('changelog', 'show changelog for last/given release', {}, asyncPrint(printChangelog)) - .command(['release-commits', 'rc'], 'show commit titles for last/given release', { - release: { - desc: 'Specify ref of release for release-commits command. Defaults to HEAD', - }, - format: { - desc: 'Specify pretty print format for release-commits command', - default: '%s', - }, - }, asyncPrint(releaseCommitsCommand)) - .command('config', 'show current config', {}, asyncPrint(showConfig)) -} - -export const handler = function() {} diff --git a/src/plugins/core/commands/pvm-sync-tag.ts b/src/plugins/core/commands/pvm-sync-tag.ts deleted file mode 100644 index 4ec2edae5..000000000 --- a/src/plugins/core/commands/pvm-sync-tag.ts +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env node -import fs from 'fs' -import util from 'util' -import resolveFrom from 'resolve-from' -import { getConfig } from '@pvm/core/lib/config' -import lastTag from '@pvm/core/lib/git/last-tag' -import { log } from '@pvm/core/lib/logger' -import { requireDefault } from '@pvm/core/lib' -import { env } from '@pvm/core/lib/env' - -const writeFile = util.promisify(fs.writeFile) - -// TODO: кажется команда уже не нужна и устарела -export const command = 'sync-tag' -export const description = `Extracts version from git tag and writes to package.json` -export const builder = {} -export const handler = main - -async function updatePkgVersion(pkgDir, version) { - const config = await getConfig() - const pkgPath = resolveFrom(pkgDir, './package.json') - const p = requireDefault(pkgPath) - p.version = version - await writeFile(pkgPath, JSON.stringify(p, null, config.packages?.indent) + '\n') -} - -async function main() { - const { - NPM_TOKEN, - CI_COMMIT_TAG = lastTag(), - } = env - - if (!NPM_TOKEN) { - throw new Error('env variable NPM_TOKEN isn\'t defined!') - } - - const version = CI_COMMIT_TAG.substr(1) - log(`new version is ${version}`) - - const pkgDir = process.cwd() - log(`package directory is ${pkgDir}`) - - await updatePkgVersion(pkgDir, version) - log(`package.json has updated`) -} diff --git a/src/plugins/core/commands/pvm-tojson.ts b/src/plugins/core/commands/pvm-tojson.ts deleted file mode 100644 index 23694a99a..000000000 --- a/src/plugins/core/commands/pvm-tojson.ts +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env node - -import getStdin from 'get-stdin' - -export const command = 'tojson' -export const description = 'convert text to json' -export const builder = (yargs) => { - return yargs - .example('echo -e "a\\nb" | $0 tojson -t array', `convert lines to json array, ["a", "b"]`) - .example('echo hello world | $0 tojson -k foo', `wrap string to json object, {"foo": "hello world"}`) - .example('echo -e "a\\nb" | $0 tojson -t array -k foo', `convert lines to array and wrap to json object, {"foo": ["a", "b"]}`) - .option('type', { - alias: 't', - desc: `type for input, could be string or array`, - }) - .option('key', { - alias: 'k', - desc: 'key for wrapping to object', - }) -} - -export const handler = main - -async function run(flags) { - let result: any = await getStdin() - if (flags.type === 'array') { - result = result.split(/\n/) - if (result.length && result[result.length - 1] === '') { - result.pop() - } - } - if (flags.key) { - result = { - [flags.key]: result, - } - } - return result -} - -async function main(argv) { - const result = await run(argv) - console.log(JSON.stringify(result)) -} diff --git a/src/plugins/core/commands/pvm-write-versions.ts b/src/plugins/core/commands/pvm-write-versions.ts deleted file mode 100644 index 118b84a04..000000000 --- a/src/plugins/core/commands/pvm-write-versions.ts +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env node -import { setVersions } from '../set-versions' - -export const command = 'write-versions' -export const description = `Replace stub versions in package.json's with actual one's from versions file or from release tag. Alias for 'pvm set-versions none -u -s all'` -export const handler = function(): Promise { - return setVersions({ - strategy: 'all', - versionOrReleaseType: 'none', - bumpDependants: false, - filterPath: [], - strategyOption: [], - updateDependants: true, - }) -} diff --git a/src/plugins/core/index.ts b/src/plugins/core/index.ts deleted file mode 100644 index f33a48e28..000000000 --- a/src/plugins/core/index.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { createToken, declarePlugin, provide } from '@pvm/di' -import { CLI_EXTENSION_TOKEN, CLI_TOKEN } from '@pvm/tokens-core' -import * as lintCommand from './commands/pvm-lint' -import * as notesCommand from './commands/pvm-notes' -import * as markPrCommand from './commands/pvm-mark-pr' -import * as packagesCommand from './commands/pvm-packages' -import * as publishCommand from './commands/pvm-publish' -import * as rewriteNotesCommand from './commands/pvm-rewrite-notes' -import * as rewriteSetVersions from './commands/pvm-set-versions' -import * as showCommand from './commands/pvm-show' -import * as syncTagCommand from './commands/pvm-sync-tag' -import * as toJsonCommand from './commands/pvm-tojson' -import * as writeVersionsCommand from './commands/pvm-write-versions' -import { runCli } from './cli-runner' -import { publish } from './publish/index' -import { getPackages } from './packages' - -export const PUBLISH_API_TOKEN = createToken('PUBLISH_TOKEN') -export const GET_PACKAGE_API_TOKEN = createToken('GET_PACKAGES_TOKEN') - -export default declarePlugin({ - factory: function() { - return { - providers: [ - provide({ - provide: CLI_TOKEN, - useFactory({ cliExtensions }) { - return ({ argv }: { argv: string[] }) => runCli(cliExtensions ?? [], argv) - }, - deps: { - cliExtensions: { token: CLI_EXTENSION_TOKEN, optional: true, multi: true } as const, - }, - }), - provide({ - provide: CLI_EXTENSION_TOKEN, - useValue: [ - lintCommand, - markPrCommand, - notesCommand, - packagesCommand, - publishCommand, - rewriteNotesCommand, - rewriteSetVersions, - showCommand, - syncTagCommand, - toJsonCommand, - writeVersionsCommand, - ], - multi: true, - }), - provide({ - provide: GET_PACKAGE_API_TOKEN, - useValue: getPackages, - }), - provide({ - provide: PUBLISH_API_TOKEN, - useValue: publish, - }), - ], - } - }, -}) diff --git a/src/plugins/core/package.json b/src/plugins/core/package.json deleted file mode 100644 index 78260de8e..000000000 --- a/src/plugins/core/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "@pvm/plugin-core", - "version": "0.0.0-stub", - "dependencies": { - "yargs": "^16.1.1", - "@iarna/toml": "^2.2.3", - "@pvm/changelog": "0.0.0-stub", - "@pvm/di": "0.0.0-stub", - "@pvm/tokens-core": "0.0.0-stub", - "@pvm/types": "0.0.0-stub", - "@pvm/core": "0.0.0-stub", - "@pvm/pkgset": "0.0.0-stub", - "@pvm/repository": "0.0.0-stub", - "@pvm/update": "0.0.0-stub", - "@pvm/vcs": "0.0.0-stub", - "@pvm/viz": "0.0.0-stub", - "@pvm/notifications": "0.0.0-stub", - "get-stdin": "^7.0.0", - "resolve-from": "^5.0.0", - "micromatch": "^3.1.10", - "semver": "^7.3.0", - "chalk": "^4.0.0", - "cli-table": "^0.3.6", - "p-map": "^4.0.0", - "lodash": "^4.2.0" - } -} diff --git a/src/plugins/core/packages.ts b/src/plugins/core/packages.ts deleted file mode 100644 index af075ad3c..000000000 --- a/src/plugins/core/packages.ts +++ /dev/null @@ -1,71 +0,0 @@ -import pkgsetChanged from '@pvm/pkgset/lib/strategies/changed' -import pkgsetAffected from '@pvm/pkgset/lib/strategies/affected' -import pkgsetSinceRelease from '@pvm/pkgset/lib/strategies/changed-since-release' -import pkgsetReleased from '@pvm/pkgset/lib/strategies/released' -import drainItems from '@pvm/core/lib/iter/drain-items' -import { getUpdateState } from '@pvm/update/lib' -import { matchAny } from '@pvm/core/lib/pkg-match' -import fromGlobPatterns from '@pvm/pkgset/lib/from-glob-patterns' -import type { Pkg } from '@pvm/core/lib/pkg' -import { concatPackages } from '@pvm/core/lib/pkg' -import { Repository } from '@pvm/repository/lib' - -// connected with type yargs.commands['pvm-publish].options.list.choices in ../cli/commands/pvm-packages.ts -type PackagesType = 'about-to-update' | 'update' | 'changed' | 'changed-since-release' | 'affected' | 'released' | 'updated' | 'all' - -interface GetPackagesOptions { - filter?: string[], - ignoreDangerouslyOpts?: boolean, - cwd?: string, -} - -export async function getPackages(type: PackagesType = 'all', opts: GetPackagesOptions = {}): Promise { - let packages - const { ignoreDangerouslyOpts = false, cwd = process.cwd() } = opts - const repo = await Repository.init(cwd) - - let always_changed_workspaces: string[] = [] - let extraPackages: Iterable = [] - if (!ignoreDangerouslyOpts) { - const config = repo.config - always_changed_workspaces = config.dangerously_opts?.always_changed_workspaces || [] - - if (always_changed_workspaces.length) { - extraPackages = fromGlobPatterns(config, always_changed_workspaces, void 0) - } - } - - switch (type) { - case 'about-to-update': - case 'update': - // getUpdateState сам подключает always_changed_workspaces - packages = Array.from((await getUpdateState({ readonly: true, cwd })).getReleasePackages().keys()) - break - case 'changed': - packages = await drainItems(pkgsetChanged({ includeUncommited: true, cwd })) - packages = concatPackages(packages, extraPackages) - break - case 'affected': - packages = await drainItems(pkgsetAffected({ includeUncommited: true, cwd })) - break - case 'changed-since-release': - packages = await drainItems(pkgsetSinceRelease({ cwd })) - packages = concatPackages(packages, extraPackages) - break - case 'released': - case 'updated': - packages = await drainItems(pkgsetReleased({ cwd })) - break - default: - // 'all' - packages = [...repo.packagesList] - break - } - - const { filter } = opts - if (filter && filter.length) { - packages = packages.filter(pkg => matchAny(pkg, filter)) - } - - return packages -} diff --git a/src/plugins/core/publish/release-message.ts b/src/plugins/core/publish/release-message.ts deleted file mode 100644 index 726f5dc8d..000000000 --- a/src/plugins/core/publish/release-message.ts +++ /dev/null @@ -1,104 +0,0 @@ -import type { ReleasedProps, Message } from '@pvm/types' - -import { getConfig } from '@pvm/core/lib/config/index' -import path from 'path' -import fs from 'fs' -import httpreq from '@pvm/core/lib/httpreq' -import { mkdirp } from '@pvm/core/lib/fs' -import childProcess from 'child_process' -import type { HostApi } from '@pvm/core/lib/plugins/index' -import { logger } from './logger' - -interface NotifyOpts { - notifyScript?: string, - strategy?: string, - hostApi?: HostApi, -} - -export async function releaseMessage(releasedProps: ReleasedProps, opts: NotifyOpts = {}): Promise { - const config = await getConfig() - const { strategy, hostApi } = opts - const defaultScriptName = strategy === 'stale' ? 'stale' : 'release' - let defaultScriptPath - const defaultScriptsPath = path.resolve(__dirname, '../messages/notify-scripts') - const pluginNotifyScriptsPath = await hostApi?.notifyScriptsPath() - const notifyScriptsPath = pluginNotifyScriptsPath ?? defaultScriptsPath - - defaultScriptPath = path.resolve(notifyScriptsPath, `${defaultScriptName}.js`) - if (!fs.existsSync(defaultScriptPath)) { - defaultScriptPath = path.resolve(defaultScriptsPath, `${defaultScriptName}.js`) - } - - const { - notifyScript = defaultScriptPath, - } = opts - - let localScriptPath - let doCleanup - if (/^https?:\/\//.test(notifyScript)) { - logger.info(`Fetch notification script from ${notifyScript}`) - const { body } = await httpreq(notifyScript) - localScriptPath = path.join(config.cwd, 'node_modules', `pvm-notification-script.js`) - logger.debug(`save fetched script to ${localScriptPath}`) - mkdirp(path.dirname(localScriptPath)) - doCleanup = () => { - fs.unlinkSync(localScriptPath) - } - fs.writeFileSync(localScriptPath, body) - } else { - localScriptPath = path.resolve(config.cwd, notifyScript) - if (!fs.existsSync(localScriptPath)) { - localScriptPath = path.resolve(notifyScriptsPath, notifyScript.endsWith('.js') ? notifyScript : `${notifyScript}.js`) - } - } - - if (!fs.existsSync(localScriptPath)) { - throw new Error(`Couldn't locate ${notifyScript} from cwd or internal scripts directory`) - } - - const p: Promise> = new Promise((resolve, reject) => { - let resolved = false - const child = childProcess.fork(localScriptPath, [], { - stdio: 'pipe', - execArgv: ['--unhandled-rejections=strict'], - }) - child.on('error', reject) - child.on('message', (msg: any) => { - if (!resolved && msg.type === 'message') { - resolved = true - child.kill() - child.unref() - resolve(msg.message || { text: `${releasedProps.tag} has been released` }) - } - }) - child.send(releasedProps) - let stdout = '' - let stderr = '' - child.stdout!.on('data', (data) => { - stdout += data.toString() - }) - child.stderr!.on('data', (data) => { - stderr += data.toString() - }) - child.on('exit', (code) => { - if (!resolved && code !== 0) { - reject(new Error(`Notification script ${notifyScript} exited with code ${code}\n${stderr || ''}`)) - return - } - setTimeout(() => { - if (!resolved) { - resolved = true - resolve({ content: stdout }) - } - }, 0) - }) - }) - - p.finally(() => { - if (doCleanup) { - doCleanup() - } - }) - - return p -} diff --git a/src/plugins/github/index.ts b/src/plugins/github/index.ts deleted file mode 100644 index 21c618315..000000000 --- a/src/plugins/github/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { CONFIG_TOKEN, PLATFORM_TOKEN } from '@pvm/tokens-core' -import { declarePlugin, provide } from '@pvm/di' -import { GithubPlatform } from './platform' - -export default declarePlugin({ - factory: function() { - return { - providers: [ - provide({ - provide: PLATFORM_TOKEN, - useClass: GithubPlatform, - deps: { - config: CONFIG_TOKEN, - }, - }), - ], - } - }, -}) diff --git a/src/plugins/github/logger.ts b/src/plugins/github/logger.ts deleted file mode 100644 index 84e3e3fa7..000000000 --- a/src/plugins/github/logger.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { loggerFor } from '@pvm/core/lib/logger' - -export const log = loggerFor('pvm:github') diff --git a/src/tokens/core/README.md b/src/tokens/core/README.md deleted file mode 100644 index 1a96cc09d..000000000 --- a/src/tokens/core/README.md +++ /dev/null @@ -1 +0,0 @@ -# @pvm/tokens-core \ No newline at end of file diff --git a/src/tokens/core/index.ts b/src/tokens/core/index.ts deleted file mode 100644 index d84b810eb..000000000 --- a/src/tokens/core/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { Config, BasePlatformInterface } from '@pvm/types' - -import { createToken } from '@pvm/di' -import type { Argv, Options } from 'yargs' - -export const CONFIG_TOKEN = createToken('CONFIG') -export const CWD_TOKEN = createToken('CWD_TOKEN') -/** - * @deprecated use new plugin system and DI instead - */ -export const HOST_API = createToken('HOST_API') - -export const PLATFORM_TOKEN = createToken>('PLATFORM_TOKEN') - -type Command = { - command: string, - aliases?: string, - description: string, - builder?: ((yargs: Argv) => Argv) | { [key: string]: Options }, - handler:(flags: { [arg: string]: unknown }) => any | Promise, -} -export const CLI_EXTENSION_TOKEN = createToken('CLI_EXTENSION_TOKEN', { multi: true }) -export const CLI_TOKEN = createToken<(opts: { argv: string[] }) => void>('CLI_TOKEN') diff --git a/src/tokens/core/package.json b/src/tokens/core/package.json deleted file mode 100644 index a4bb1fbaa..000000000 --- a/src/tokens/core/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "@pvm/tokens-core", - "version": "0.0.0-stub", - "exports": "./index.js", - "dependencies": { - "@pvm/di": "0.0.0-stub", - "@pvm/types": "0.0.0-stub", - "yargs": "^16.1.1" - } -} diff --git a/test/executors.js b/test/executors.js deleted file mode 100644 index bd07f789c..000000000 --- a/test/executors.js +++ /dev/null @@ -1,45 +0,0 @@ -const path = require('path') -const runShell = require('../packages/pvm-core/lib/shell/run').default -const execShell = require('../packages/pvm-core/lib/shell/exec').default - -const PVM_ENV_CHECK_COMMAND = 'pvm _eval ' - -const runner = (spawner, repo, cmd, opts = {}) => { - const localBinPath = path.join(process.cwd(), 'node_modules/.bin') - - const newEnv = { - ...process.env, - PVM_TESTING_ENV: 'true', - ...opts.env, - ...repo.env, - PATH: [process.env.PATH, localBinPath].join(path.delimiter), - Path: [process.env.Path, localBinPath].join(path.delimiter), - NODE_PATH: path.resolve(__dirname, '../packages'), - } - - // Исполняем команду всё, что передано после PVM_ENV_CHECK_COMMAND, чтобы проверить окружение, в котором будут - // исполняться команды pvm - if (cmd.startsWith(PVM_ENV_CHECK_COMMAND)) { - cmd = cmd.replace(PVM_ENV_CHECK_COMMAND, '') - } - - return spawner(cmd, { - cwd: repo.dir, - ...opts, - env: newEnv, - }) -} - -const runScript = (repo, cmd, opts) => { - return runner(runShell, repo, cmd, opts) -} - -const execScript = (repo, cmd, opts = {}) => { - const execOpts = Object.assign({ - printStderr: true, - }, opts) - return runner(execShell, repo, cmd, execOpts) -} - -exports.runScript = runScript -exports.execScript = execScript diff --git a/test/executors.ts b/test/executors.ts new file mode 100644 index 000000000..f499fcab5 --- /dev/null +++ b/test/executors.ts @@ -0,0 +1,48 @@ +import path from 'path' +import runShell from '../packages/pvm/lib/shell/run' +import execShell from '../packages/pvm/lib/shell/exec' +import type { RepoTestApi } from './types' +import type { ExecShellOptions, RunShellOptions } from '@pvm/pvm' + +const PVM_ENV_CHECK_COMMAND = 'pvm _eval ' + +function runner(spawner: typeof runShell, repo: RepoTestApi, cmd: string, opts: RunShellOptions): ReturnType +function runner(spawner: typeof execShell, repo: RepoTestApi, cmd: string, opts: ExecShellOptions): ReturnType +function runner(spawner: typeof execShell | typeof runShell, repo: RepoTestApi, cmd: string, opts: RunShellOptions | ExecShellOptions): ReturnType { + const localBinPath = path.join(process.cwd(), 'node_modules/.bin') + + const newEnv: Record = { + ...process.env, + PVM_TESTING_ENV: 'true', + ...opts.env, + ...repo.env, + PATH: [process.env.PATH, localBinPath].join(path.delimiter), + Path: [process.env.Path, localBinPath].join(path.delimiter), + NODE_PATH: path.resolve(__dirname, '../packages'), + } + + newEnv.NODE_OPTIONS = `${newEnv.NODE_OPTIONS ? `${newEnv.NODE_OPTIONS} ` : ''}--enable-source-maps` + + // Исполняем команду всё, что передано после PVM_ENV_CHECK_COMMAND, чтобы проверить окружение, в котором будут + // исполняться команды pvm + if (cmd.startsWith(PVM_ENV_CHECK_COMMAND)) { + cmd = cmd.replace(PVM_ENV_CHECK_COMMAND, '') + } + + return spawner(cmd, { + cwd: repo.dir, + ...opts, + env: newEnv, + }) +} + +export const runScript = (repo: RepoTestApi, cmd: string, opts: RunShellOptions = {}): ReturnType => { + return runner(runShell, repo, cmd, opts) +} + +export const execScript = (repo: RepoTestApi, cmd: string, opts: ExecShellOptions = {}): ReturnType => { + const execOpts = Object.assign({ + printStderr: true, + }, opts) + return runner(execShell, repo, cmd, execOpts) +} diff --git a/test/fixtures/users.js b/test/fixtures/users.ts similarity index 69% rename from test/fixtures/users.js rename to test/fixtures/users.ts index d4126b708..7762926e0 100644 --- a/test/fixtures/users.js +++ b/test/fixtures/users.ts @@ -1,5 +1,11 @@ -const users = [ +export type User = { + id: number, + username: string, + name: string, +} + +export const users: User[] = [ { id: 1, username: 'default', @@ -52,22 +58,18 @@ const users = [ }, ] -function mapUsers(ids, wrap = true) { +export function mapUsers(ids: number[], wrap: true): Array<{ user: User }> +export function mapUsers(ids: number[], wrap?: false): Array +export function mapUsers(ids: number[], wrap = true): Array<{ user: User } | User> { return ids.reduce((acc, id) => { const user = users.find(u => u.id === id) if (user) { acc.push(wrap ? { user } : user) } return acc - }, []) + }, [] as Array) } -function getUser(username) { +export function getUser(username: string) { return users.find(u => u.username === username) } - -module.exports = { - users, - mapUsers, - getUser, -} diff --git a/test/git/addCommit.js b/test/git/addCommit.ts similarity index 77% rename from test/git/addCommit.js rename to test/git/addCommit.ts index 8238c39c3..b236094a1 100644 --- a/test/git/addCommit.js +++ b/test/git/addCommit.ts @@ -1,13 +1,13 @@ -const assert = require('assert') -const path = require('path') -const fs = require('fs') -const __unsafe_shell = require('../../packages/pvm-core/lib/shell').cwdShell -const getGitConfigTools = require('../gitConfig') +import assert from 'assert' +import path from 'path' +import fs from 'fs' +import { cwdShell as __unsafe_shell } from '../../packages/pvm/lib/shell' +import { getGitConfigTools } from '../gitConfig' -function addCommit(repoDir, commit) { - const gitShell = (cmd, opts = {}) => __unsafe_shell(cmd, { ...opts, cwd: repoDir }) +function addCommit(repoDir: string, commit: { commit_message: string, start_branch?: string, branch?: string, actions: any[] }) { + const gitShell = (cmd: string, opts = {}) => __unsafe_shell(cmd, { ...opts, cwd: repoDir }) - const isFileInitiallyExists = (filePath) => { + const isFileInitiallyExists = (filePath: string) => { try { gitShell(`git cat-file -e HEAD:"${filePath}"`) return true @@ -82,8 +82,8 @@ function addCommit(repoDir, commit) { } } -module.exports = async (repoDir, commit) => { - const gitShell = (cmd, opts = {}) => __unsafe_shell(cmd, { ...opts, cwd: repoDir }) +export default async (repoDir: string, commit: { commit_message: string, start_branch?: string, branch?: string, actions: any[] }) => { + const gitShell = (cmd: string, opts = {}) => __unsafe_shell(cmd, { ...opts, cwd: repoDir }) const gitConfigTools = getGitConfigTools(gitShell) return gitConfigTools.runInPreparedEnvironment(() => addCommit(repoDir, commit)) } diff --git a/test/git/data.js b/test/git/data.ts similarity index 93% rename from test/git/data.js rename to test/git/data.ts index f5f0f9c57..82a10ed65 100644 --- a/test/git/data.js +++ b/test/git/data.ts @@ -26,7 +26,7 @@ const defaults = { }, } -function dataFor(dir) { +export function dataFor(dir: string) { if (!stores.has(dir)) { const store = new Configstore(dir, defaults, { configPath: path.join(dir, '.git/gl/data.json'), @@ -35,5 +35,3 @@ function dataFor(dir) { } return stores.get(dir) } - -exports.dataFor = dataFor diff --git a/test/git/gl/commits.js b/test/git/gl/commits.js deleted file mode 100644 index 34aad73c3..000000000 --- a/test/git/gl/commits.js +++ /dev/null @@ -1,21 +0,0 @@ -const gitLog = require('@pvm/core/lib/git/log').default -const makeTransormer = require('./transformCommit') - -async function commits(repoDir, revRange = 'HEAD', opts = {}) { - const spawnOpts = { cwd: repoDir } - - const commits = await gitLog({ - _: [revRange], - oneline: true, - reverse: true, - ...opts, - }, spawnOpts) - const { transform, incDate } = makeTransormer() - - return commits.map(c => { - incDate() - return transform(c) - }) -} - -module.exports = commits diff --git a/test/git/gl/commits.ts b/test/git/gl/commits.ts new file mode 100644 index 000000000..e7c941092 --- /dev/null +++ b/test/git/gl/commits.ts @@ -0,0 +1,19 @@ +import gitLog from '../../../packages/pvm/lib/git/log' +import { makeTransformer } from './transformCommit' + +export default async function commits(repoDir: string, revRange = 'HEAD', opts = {}) { + const spawnOpts = { cwd: repoDir } + + const commits = await gitLog({ + _: [revRange], + oneline: true, + reverse: true, + ...opts, + }, spawnOpts) + const { transform, incDate } = makeTransformer() + + return commits.map(c => { + incDate() + return transform(c) + }) +} diff --git a/test/git/gl/commitsToTags.ts b/test/git/gl/commitsToTags.ts index c22f0a1b1..892789fc2 100644 --- a/test/git/gl/commitsToTags.ts +++ b/test/git/gl/commitsToTags.ts @@ -1,14 +1,22 @@ -import makeTransformer from './transformCommit' +import { makeTransformer } from './transformCommit' import { tagNotes } from '../tagNotes' -import shell from '../../../packages/pvm-core/lib/shell' +import type { Commit } from '@pvm/pvm' +import { shell } from '@pvm/pvm' +import type { GitlabCommit } from '../../types' -const makeReducer = (cwd, opts: { onlyReleases?: boolean } = {}) => { - const gitShell = cmd => shell(cmd, { cwd }) +const makeReducer = (cwd: string, opts: { onlyReleases?: boolean } = {}) => { + const gitShell = (cmd: string) => shell(cmd, { cwd }) const { incDate, transform } = makeTransformer() - return (acc, c) => { + return (acc: Array<{ + name: string, + message: string, + target: string, + commit: GitlabCommit, + release: { tag_name: string, description: string } | null, + }>, c: Commit) => { const sha = c.commit.long const tagNames = gitShell(`git tag --points-at ${sha}`).split(/\s+/).filter(s => s.length > 0) if (!tagNames.length) { diff --git a/test/git/gl/tags.js b/test/git/gl/tags.ts similarity index 64% rename from test/git/gl/tags.js rename to test/git/gl/tags.ts index 2f2461ccb..ac3963e00 100644 --- a/test/git/gl/tags.js +++ b/test/git/gl/tags.ts @@ -1,7 +1,7 @@ -const reduceToTags = require('./commitsToTags').default -const gitLog = require('@pvm/core/lib/git/log').default +import reduceToTags from './commitsToTags' +import gitLog from '../../../packages/pvm/lib/git/log' -async function gitTags(repoDir, onlyReleases = true) { +export async function getTags(repoDir: string, onlyReleases = true) { const spawnOpts = { cwd: repoDir } // --tags --decorate=short --simplify-by-decoration --oneline --reverse const commits = await gitLog({ @@ -15,5 +15,3 @@ async function gitTags(repoDir, onlyReleases = true) { onlyReleases, }), []) } - -module.exports = gitTags diff --git a/test/git/gl/transformCommit.js b/test/git/gl/transformCommit.ts similarity index 79% rename from test/git/gl/transformCommit.js rename to test/git/gl/transformCommit.ts index 7d9fde642..e78af005d 100644 --- a/test/git/gl/transformCommit.js +++ b/test/git/gl/transformCommit.ts @@ -1,7 +1,10 @@ +import type { Commit } from '@pvm/pvm' +import type { GitlabCommit } from '../../types' + const addSeconds = require('date-fns/addSeconds') // берем коммит от git-log-parser и преобразовываем в формат коммита гитлаба -const transform = (c, processDate) => { +const transform = (c: Commit, processDate: (d: Date) => string): GitlabCommit => { const sha = c.commit.long return { id: sha, @@ -18,7 +21,7 @@ const transform = (c, processDate) => { } } -function makeTransormer() { +export function makeTransformer() { let i = 0 const baseDate = new Date('2018-11-27T12:00:00.000Z') @@ -31,10 +34,8 @@ function makeTransormer() { incDate() { i++ }, - transform(c) { + transform(c: Commit) { return transform(c, fakeDate) }, } } - -module.exports = makeTransormer diff --git a/test/git/tagNotes.js b/test/git/tagNotes.ts similarity index 58% rename from test/git/tagNotes.js rename to test/git/tagNotes.ts index 4ae83561f..ab2ae391c 100644 --- a/test/git/tagNotes.js +++ b/test/git/tagNotes.ts @@ -1,24 +1,19 @@ -const path = require('path') -const fs = require('fs-extra') -const { promisify } = require('util') -const writeFile = promisify(fs.writeFile) +import path from 'path' +import fs from 'fs-extra' -function safeTagName(tagName) { +function safeTagName(tagName: string) { return tagName.replace(/\//g, '_') } // на данный момент здесь нет различий между пустым release notes и отсутствием релиза // поэтому это надо учитывать при написании тестов -const tagNotes = (dir, tagName) => { +export const tagNotes = (dir: string, tagName: string) => { const tagPath = path.join(dir, `.git/releases/${safeTagName(tagName)}`) return fs.existsSync(tagPath) ? fs.readFileSync(tagPath, 'utf-8').trim() : '' } -const setTagNotes = async (dir, tagName, notes) => { +export const setTagNotes = async (dir: string, tagName: string, notes: string) => { const fullPath = path.join(dir, `.git/releases/${safeTagName(tagName)}`) - return writeFile(fullPath, notes) + return fs.writeFile(fullPath, notes) } - -exports.tagNotes = tagNotes -exports.setTagNotes = setTagNotes diff --git a/test/gitConfig.js b/test/gitConfig.ts similarity index 90% rename from test/gitConfig.js rename to test/gitConfig.ts index 6ab393cc8..5e5e4cab1 100644 --- a/test/gitConfig.js +++ b/test/gitConfig.ts @@ -3,7 +3,7 @@ const { GITLAB_USER_NAME = 'Jest Agent', } = process.env -module.exports = function getGitConfigTools(gitShell) { +export function getGitConfigTools(gitShell: (cmd: string) => string) { return { getUserConfig() { let name @@ -32,7 +32,7 @@ module.exports = function getGitConfigTools(gitShell) { gitShell(`git config --unset user.name`) }, - async runInPreparedEnvironment(runner) { + async runInPreparedEnvironment(runner: () => any) { const { name, email } = this.getUserConfig() const shouldPrepareEnv = !name || !email @@ -49,7 +49,7 @@ module.exports = function getGitConfigTools(gitShell) { return runResult }, - async runInPureEnvironment(runner) { + async runInPureEnvironment(runner: () => any) { const { name, email } = this.getUserConfig() const shouldPurifyEnv = name || email diff --git a/test/gl-api-mock/approvals.js b/test/gl-api-mock/approvals.ts similarity index 59% rename from test/gl-api-mock/approvals.js rename to test/gl-api-mock/approvals.ts index fd9709fb2..b7acb5e91 100644 --- a/test/gl-api-mock/approvals.js +++ b/test/gl-api-mock/approvals.ts @@ -1,13 +1,13 @@ -const express = require('express') -const repoRouterPlugin = require('../platform-mock-helpers/repo-router-plugin').default -const { mapUsers } = require('../fixtures/users') +import express from 'express' +import repoRouterPlugin from '../platform-mock-helpers/repo-router-plugin' +import { mapUsers } from '../fixtures/users' const router = express.Router() repoRouterPlugin(router) -router.get('/projects/:id/approvals', async (req, res, next) => { +router.get('/projects/:id/approvals', async (_req, res, next) => { try { - const approvals = req.repoData.get('project_approvals') + const approvals = res.app.locals.repoData.get('project_approvals') approvals.approvers = mapUsers(approvals.approvers_ids) res.json(approvals) } catch (e) { @@ -16,9 +16,9 @@ router.get('/projects/:id/approvals', async (req, res, next) => { }) // https://docs.gitlab.com/ee/api/merge_request_approvals.html#get-configuration-1 -router.get('/projects/:id/merge_requests/:merge_request_iid/approvals', async (req, res, next) => { +router.get('/projects/:id/merge_requests/:merge_request_iid/approvals', async (_req, res, next) => { try { - const approvals = req.repoData.get('mr_approvals') + const approvals = res.app.locals.repoData.get('mr_approvals') approvals.approvers = mapUsers(approvals.approvers_ids) res.json(approvals) } catch (e) { @@ -30,8 +30,8 @@ router.get('/projects/:id/merge_requests/:merge_request_iid/approvals', async (r router.post('/projects/:id/merge_requests/:merge_request_iid/approvals', async (req, res, next) => { try { const { approvals_required } = req.body - req.repoData.set('mr_approvals.approvals_required', approvals_required) - res.json(req.repoData.get('mr_approvals')) + res.app.locals.repoData.set('mr_approvals.approvals_required', approvals_required) + res.json(res.app.locals.repoData.get('mr_approvals')) } catch (e) { next(e) } @@ -41,11 +41,11 @@ router.post('/projects/:id/merge_requests/:merge_request_iid/approvals', async ( router.put('/projects/:id/merge_requests/:merge_request_iid/approvers', async (req, res, next) => { try { const { approver_ids } = req.body - req.repoData.set('mr_approvals.approvers_ids', approver_ids) - res.json(req.repoData.get('mr_approvals')) + res.app.locals.repoData.set('mr_approvals.approvers_ids', approver_ids) + res.json(res.app.locals.repoData.get('mr_approvals')) } catch (e) { next(e) } }) -module.exports = router +export default router diff --git a/test/gl-api-mock/commits.js b/test/gl-api-mock/commits.js deleted file mode 100644 index e6e04e0db..000000000 --- a/test/gl-api-mock/commits.js +++ /dev/null @@ -1,39 +0,0 @@ -const express = require('express') -const addCommit = require('../git/addCommit') -const getCommits = require('../git/gl/commits') -const { paginate, pagingQuery } = require('../platform-mock-helpers/paging') -const repoRouterPlugin = require('../platform-mock-helpers/repo-router-plugin').default - -const router = express.Router() - -repoRouterPlugin(router) - -router.get('/projects/:id/repository/commits', async (req, res, next) => { - try { - const commits = await getCommits(res.locals.repoDir, req.query.ref_name) - - const pagingOpts = { - sortMap: { - updated: ['created_at'], - }, - toComparable: a => new Date(a), - } - - res.sendPaginated(paginate(commits, pagingQuery(req.query), pagingOpts)) - } catch (e) { - next(e) - } -}) - -// https://docs.gitlab.com/ee/api/commits.html#create-a-commit-with-multiple-files-and-actions -router.post('/projects/:id/repository/commits', async (req, res, next) => { - try { - const commit = await addCommit(res.locals.repoDir, req.body) - - res.json(commit) - } catch (e) { - next(e) - } -}) - -module.exports = router diff --git a/test/gl-api-mock/commits.ts b/test/gl-api-mock/commits.ts new file mode 100644 index 000000000..d7a274a8e --- /dev/null +++ b/test/gl-api-mock/commits.ts @@ -0,0 +1,39 @@ +import express from 'express' +import addCommit from '../git/addCommit' +import getCommits from '../git/gl/commits' +import { paginate, pagingQuery } from '../platform-mock-helpers/paging' +import repoRouterPlugin from '../platform-mock-helpers/repo-router-plugin' + +const router = express.Router() + +repoRouterPlugin(router) + +router.get('/projects/:id/repository/commits', async (req, res, next) => { + try { + const commits = await getCommits(res.app.locals.repoDir, req.query.ref_name as string) + + const pagingOpts = { + sortMap: { + updated: ['created_at'], + }, + toComparable: (a: any) => new Date(a), + } + + res.app.locals.sendPaginated(paginate(commits, pagingQuery(req.query), pagingOpts)) + } catch (e) { + next(e) + } +}) + +// https://docs.gitlab.com/ee/api/commits.html#create-a-commit-with-multiple-files-and-actions +router.post('/projects/:id/repository/commits', async (req, res, next) => { + try { + const commit = await addCommit(res.app.locals.repoDir, req.body) + + res.json(commit) + } catch (e) { + next(e) + } +}) + +export default router diff --git a/test/gl-api-mock/fixtures-and-fakes.js b/test/gl-api-mock/fixtures-and-fakes.ts similarity index 67% rename from test/gl-api-mock/fixtures-and-fakes.js rename to test/gl-api-mock/fixtures-and-fakes.ts index cbfee553a..d7254d253 100644 --- a/test/gl-api-mock/fixtures-and-fakes.js +++ b/test/gl-api-mock/fixtures-and-fakes.ts @@ -1,8 +1,8 @@ -const express = require('express') -const repoRouterPlugin = require('../platform-mock-helpers/repo-router-plugin').default -const { users } = require('../fixtures/users') +import express from 'express' +import repoRouterPlugin from '../platform-mock-helpers/repo-router-plugin' +import { users } from '../fixtures/users' -const router = express.Router() +export const router = express.Router() repoRouterPlugin(router) router.get('/projects/:id/merge_requests', (req, res) => { @@ -28,7 +28,7 @@ router.get('/projects/:id/merge_requests', (req, res) => { }) // https://docs.gitlab.com/ee/api/commits.html#list-merge-requests-associated-with-a-commit -router.get('/projects/:projectId/repository/commits/:id/merge_requests', async (req, res, next) => { +router.get('/projects/:projectId/repository/commits/:id/merge_requests', async (req, res) => { res.json([ { id: 1, @@ -40,15 +40,15 @@ router.get('/projects/:projectId/repository/commits/:id/merge_requests', async ( username: 'pushkin', name: 'Alexander Pushkin', }, - ...this.mergeRequestForCommit?.[req.params.id], + ...res.app.locals.mergeRequestForCommit?.[req.params.id], }, ]) - delete this.mergeRequestForCommit?.[req.params.id] + delete res.app.locals.mergeRequestForCommit?.[req.params.id] }) router.post('/merge-request-for-commit/:commitId', (req, res) => { - this.mergeRequestForCommit = this.mergeRequestForCommit || {} - this.mergeRequestForCommit[req.params.commitId] = req.body + res.app.locals.mergeRequestForCommit = res.app.locals.mergeRequestForCommit || {} + res.app.locals.mergeRequestForCommit[req.params.commitId] = req.body res.status(200) res.send() }) @@ -64,4 +64,4 @@ router.get('/users', (req, res) => { res.json(response) }) -module.exports = router +export default router diff --git a/test/gl-api-mock/index.js b/test/gl-api-mock/index.ts similarity index 59% rename from test/gl-api-mock/index.js rename to test/gl-api-mock/index.ts index d5ef544d3..fe24fca23 100644 --- a/test/gl-api-mock/index.js +++ b/test/gl-api-mock/index.ts @@ -1,34 +1,43 @@ // создает репозиторий вместе с gitlab-like сервисом -const fs = require('fs') -const express = require('express') -const bodyParser = require('body-parser') -const { reposDir } = require('../repos-dir') +import fs from 'fs' +import type { Response } from 'express' +import express from 'express' +import bodyParser from 'body-parser' +import { reposDir } from '../repos-dir' + +import fixtures_and_fakes from './fixtures-and-fakes' +import tags from './tags' +import commits from './commits' +import approvals from './approvals' +import version from './version' +import slack_hook from './slack-hook' const app = express() app.use(bodyParser.json()) app.locals.reposDir = reposDir -function sendp(res, paginated) { +function sendp(res: Response, paginated: [any[], Record]) { const [list, headers] = paginated res.set(headers) res.json(list) } -app.use((req, res, next) => { - res.sendPaginated = (paginated) => sendp(res, paginated) +app.use((_req, res, next) => { + res.app.locals.sendPaginated = (paginated: [any[], Record]) => sendp(res, paginated) next() }) -app.use('/api/v4', require('./fixtures-and-fakes')) -app.use('/api/v4', require('./tags')) -app.use('/api/v4', require('./commits')) -app.use('/api/v4', require('./approvals')) -app.use('/api/v4', require('./version')) -app.use('/slack-hook', require('./slack-hook')) +app.use('/api/v4', fixtures_and_fakes) +app.use('/api/v4', tags) +app.use('/api/v4', commits) +app.use('/api/v4', approvals) +app.use('/api/v4', version) +app.use('/slack-hook', slack_hook) -app.use(function(err, req, res, next) { +// @ts-ignore +app.use(function(err: any, _req, res, _next) { fs.writeFileSync('gl-api-error.log', String(err.stack), { flag: 'w', }) @@ -39,7 +48,7 @@ app.use(function(err, req, res, next) { const start = () => { return new Promise((resolve, reject) => { // eslint-disable-next-line prefer-const - let httpServer + let httpServer: any const successCb = () => { const serverAddress = httpServer.address() console.log('gitlab mock server listening on', serverAddress) @@ -51,16 +60,18 @@ const start = () => { .on('error', (err) => { reject(err) }) + // @ts-ignore app.httpServer = httpServer }) } const stop = () => { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { + // @ts-ignore const httpServer = app.httpServer if (httpServer && httpServer.listening) { - httpServer.close(e => { + httpServer.close((e: any) => { if (e) { console.error(`Couldn't stop mock server!`, e.toString()) reject(e) diff --git a/test/gl-api-mock/slack-hook.js b/test/gl-api-mock/slack-hook.ts similarity index 72% rename from test/gl-api-mock/slack-hook.js rename to test/gl-api-mock/slack-hook.ts index 37c4c6ade..26f39275c 100644 --- a/test/gl-api-mock/slack-hook.js +++ b/test/gl-api-mock/slack-hook.ts @@ -1,4 +1,4 @@ -const express = require('express') +import express from 'express' const router = express.Router() @@ -7,4 +7,4 @@ router.post('/', (req, res) => { res.json({ ok: true, body: req.body }) }) -module.exports = router +export default router diff --git a/test/gl-api-mock/tags.js b/test/gl-api-mock/tags.ts similarity index 61% rename from test/gl-api-mock/tags.js rename to test/gl-api-mock/tags.ts index 5f0d72a42..42e0804ce 100644 --- a/test/gl-api-mock/tags.js +++ b/test/gl-api-mock/tags.ts @@ -1,14 +1,22 @@ -const express = require('express') -const getTags = require('../git/gl/tags') -const shell = require('../../packages/pvm-core/lib/shell').default -const commitsToTags = require('../git/gl/commitsToTags').default -const gitLog = require('@pvm/core/lib/git/log').default -const { tagNotes, setTagNotes } = require('../git/tagNotes') -const { paginate, pagingQuery } = require('../platform-mock-helpers/paging') -const repoRouterPlugin = require('../platform-mock-helpers/repo-router-plugin').default -const getGitConfigTools = require('../gitConfig') - -const stats = { +import express from 'express' +import { getTags } from '../git/gl/tags' +import { shell } from '../../packages/pvm/lib/shell' + +import commitsToTags from '../git/gl/commitsToTags' +import gitLog from '../../packages/pvm/lib/git/log' +import { setTagNotes, tagNotes } from '../git/tagNotes' + +import { paginate, pagingQuery } from '../platform-mock-helpers/paging' + +import repoRouterPlugin from '../platform-mock-helpers/repo-router-plugin' +import { getGitConfigTools } from '../gitConfig' +import type { RequestHandler } from 'express' + +const stats: { + tags: Record +} = { tags: { }, } @@ -26,16 +34,16 @@ router.get('/projects/:id/repository/tags', async (req, res, next) => { stats.tags[req.params.id] = stats.tags[req.params.id] || { reqsCount: 0 } stats.tags[req.params.id].reqsCount += 1 try { - const tags = await getTags(res.locals.repoDir, false) + const tags = await getTags(res.app.locals.repoDir, false) const pagingOpts = { sortMap: { updated: ['commit', 'created_at'], }, - toComparable: a => new Date(a), + toComparable: (a: any) => new Date(a), } - res.sendPaginated(paginate(tags, pagingQuery(req.query), pagingOpts)) + res.app.locals.sendPaginated(paginate(tags, pagingQuery(req.query), pagingOpts)) } catch (e) { next(e) } @@ -43,7 +51,7 @@ router.get('/projects/:id/repository/tags', async (req, res, next) => { router.get('/projects/:id/repository/tags/:tag_name', async (req, res, next) => { try { - const tags = await getTags(res.locals.repoDir, false) + const tags = await getTags(res.app.locals.repoDir, false) const tag = tags.find(tag => tag.name === req.params.tag_name) if (tag) { res.json(tag) @@ -58,8 +66,8 @@ router.get('/projects/:id/repository/tags/:tag_name', async (req, res, next) => // https://docs.gitlab.com/ee/api/tags.html#create-a-new-tag router.post('/projects/:id/repository/tags', async (req, res, next) => { try { - const spawnOpts = { cwd: res.locals.repoDir } - const gitShell = (cmd, opts = {}) => shell(cmd, Object.assign(opts, spawnOpts)) + const spawnOpts = { cwd: res.app.locals.repoDir } + const gitShell = (cmd: string, opts = {}) => shell(cmd, Object.assign(opts, spawnOpts)) const gitConfigTools = getGitConfigTools(gitShell) const { tag_name, ref, message } = req.body @@ -77,7 +85,7 @@ router.post('/projects/:id/repository/tags', async (req, res, next) => { _: ['HEAD', '-n1'], }, spawnOpts) - const tag = commits.reduce(commitsToTags(res.locals.repoDir), []).filter(t => t.name === tag_name)[0] + const tag = commits.reduce(commitsToTags(res.app.locals.repoDir), []).filter(t => t.name === tag_name)[0] res.json(tag) } catch (e) { @@ -86,14 +94,14 @@ router.post('/projects/:id/repository/tags', async (req, res, next) => { }) // https://docs.gitlab.com/ee/api/releases/#create-a-release -const releaseRoute = async (req, res, next) => { +const releaseRoute: RequestHandler = async (req, res, next) => { try { - const currentRelease = tagNotes(res.locals.repoDir, req.body.tag_name) + const currentRelease = tagNotes(res.app.locals.repoDir, req.body.tag_name) if (currentRelease && req.method === 'POST') { res.sendStatus(409) return } - await setTagNotes(res.locals.repoDir, req.body.tag_name, req.body.description) + await setTagNotes(res.app.locals.repoDir, req.body.tag_name, req.body.description) res.json({ tag_name: req.body.tag_name, @@ -108,4 +116,4 @@ router.route('/projects/:id/releases') .post(releaseRoute) .put(releaseRoute) -module.exports = router +export default router diff --git a/test/gl-api-mock/version.js b/test/gl-api-mock/version.js deleted file mode 100644 index a14c98177..000000000 --- a/test/gl-api-mock/version.js +++ /dev/null @@ -1,11 +0,0 @@ -const express = require('express') - -const router = express.Router() - -router.get('/version', (req, res) => { - res.json({ - version: '11.6.0-ee', - }) -}) - -module.exports = router diff --git a/test/gl-api-mock/version.ts b/test/gl-api-mock/version.ts new file mode 100644 index 000000000..c7f62c233 --- /dev/null +++ b/test/gl-api-mock/version.ts @@ -0,0 +1,11 @@ +import express from 'express' + +const router = express.Router() + +router.get('/version', (_req, res) => { + res.json({ + version: '11.6.0-ee', + }) +}) + +export default router diff --git a/test/globalSetup.js b/test/globalSetup.js index 7cefad612..aeb9531cc 100644 --- a/test/globalSetup.js +++ b/test/globalSetup.js @@ -1,7 +1,7 @@ const { start } = require('./gl-api-mock') const fs = require('fs') const path = require('path') -const shell = require('../packages/pvm-core/lib/shell').cwdShell +const shell = require('../packages/pvm/lib/shell').cwdShell const { reposDir } = require('./repos-dir') async function setup() { diff --git a/test/helpers.js b/test/helpers.js deleted file mode 100644 index 21153f06a..000000000 --- a/test/helpers.js +++ /dev/null @@ -1,40 +0,0 @@ -const fs = require('fs') -const assert = require('assert') -const path = require('path') -const util = require('util') -const sprout = require('sprout-data') -const TOML = require('@iarna/toml') - -const writeFile = util.promisify(fs.writeFile) - -function writeConfig(repo, config, configFormat = 'json') { - const configPath = path.join(repo.dir, `.pvm.${configFormat}`) - assert.ok( - configFormat === 'json' || configFormat === 'toml' || configFormat === 'js', - `Config format should be one of "toml", "json" or "js". Got "${configFormat}" instead.` - ) - if (fs.existsSync(configPath)) { - assert.ok( - configFormat !== 'js', - `Merging of configs is not supported for ".js" config.` - ) - const contents = fs.readFileSync(configPath).toString('utf-8') - const existsConfig = configFormat === 'json' ? JSON.parse(contents) : TOML.parse(contents) - config = sprout.deepMerge(existsConfig, config) - } - - let newContents - switch (configFormat) { - case 'json': - newContents = JSON.stringify(config, null, 2) - break - case 'toml': - newContents = TOML.stringify(config) - break - case 'js': - newContents = `module.exports = ${config}` - } - return writeFile(configPath, newContents) -} - -exports.writeConfig = writeConfig diff --git a/test/helpers.ts b/test/helpers.ts new file mode 100644 index 000000000..35568d62f --- /dev/null +++ b/test/helpers.ts @@ -0,0 +1,48 @@ +import fs from 'fs' +import assert from 'assert' +import path from 'path' +import util from 'util' +import * as sprout from 'sprout-data' +import TOML from '@iarna/toml' +import type { Config, RecursivePartial } from '@pvm/pvm' + +const writeFile = util.promisify(fs.writeFile) + +export function writeConfig | string>(repo: { dir: string }, config: T, passedFormat?: T extends string ? 'js' : 'json' | 'toml'): Promise { + const configFormat = passedFormat ?? 'json' + const configPath = path.join(repo.dir, `.pvm.${configFormat}`) + assert.ok( + configFormat === 'json' || configFormat === 'toml' || configFormat === 'js', + `Config format should be one of "toml", "json" or "js". Got "${configFormat}" instead.` + ) + if (fs.existsSync(configPath)) { + if (configFormat === 'js') { + throw new Error(`Merging of configs is not supported for ".js" config.`) + } + + // fix inability of ts to infer config type from configFormat type assertion + if (typeof config === 'string') { + throw new Error('Config in string and js format. Merge is impossible') + } + + const contents = fs.readFileSync(configPath).toString('utf-8') + const existsConfig = configFormat === 'json' ? JSON.parse(contents) : TOML.parse(contents) + config = sprout.deepMerge(existsConfig, config) + } + + let newContents + switch (configFormat) { + case 'json': + newContents = JSON.stringify(config, null, 2) + break + case 'toml': + newContents = TOML.stringify(config as any) + break + case 'js': + newContents = `module.exports = ${config}` + break + default: + throw new Error('Unknown format') + } + return writeFile(configPath, newContents) +} diff --git a/test/initRepo.js b/test/initRepo.ts similarity index 72% rename from test/initRepo.js rename to test/initRepo.ts index c1583b44e..a908b2f24 100644 --- a/test/initRepo.js +++ b/test/initRepo.ts @@ -1,33 +1,33 @@ -const path = require('path') -const fs = require('fs') -const fse = require('fs-extra') -const { getConfig, clearConfigCacheFor } = require('../packages/pvm-core/lib/config') -const { lastReleaseTag } = require('../packages/pvm-core/lib/git/last-release-tag') -const httpreq = require('../packages/pvm-core/lib/httpreq').default -const __unsafe_shell = require('../packages/pvm-core/lib/shell').default -const { pkgTagRe } = require('../packages/pvm-core/lib/tag-meta') -const { loadPkg } = require('../packages/pvm-core/lib/pkg') -const { getTagAnnotation } = require('../packages/pvm-core/lib/git/commands') -const { getHostApi } = require('../packages/pvm-core/lib/plugins') -const { getUpdateState } = require('../packages/pvm-update/lib/index') -const { setTagNotes, tagNotes } = require('./git/tagNotes') -const { reposDir } = require('./repos-dir') -const { writeConfig } = require('./helpers') -const { runScript, execScript } = require('./executors') -const { dataFor } = require('./git/data') -const { mapUsers, getUser } = require('./fixtures/users') -const getGitConfigTools = require('./gitConfig') -const os = require('os') -const { - taggedCacheManager, - CacheTag, -} = require('@pvm/core/lib/memoize') +import { HOST_API_TOKEN, Pvm } from '@pvm/pvm' +import type { Config, RecursivePartial } from '@pvm/pvm' + +import { CacheTag, taggedCacheManager } from '../packages/pvm/lib/memoize' +import os from 'os' +import cp from 'child_process' +import { getGitConfigTools } from './gitConfig' +import type { User } from './fixtures/users' +import { getUser, mapUsers } from './fixtures/users' +import { dataFor } from './git/data' +import { execScript, runScript } from './executors' +import { writeConfig } from './helpers' +import { reposDir } from './repos-dir' +import { setTagNotes, tagNotes } from './git/tagNotes' +import { getTagAnnotation } from '../packages/pvm/lib/git/commands' +import { loadPkg } from '../packages/pvm/lib/pkg' +import { pkgTagRe } from '../packages/pvm/lib/tag-meta' +import { shell as __unsafe_shell } from '../packages/pvm/lib/shell' +import { httpreq } from '../packages/pvm/lib/httpreq' +import { lastReleaseTag } from '../packages/pvm/lib/git/last-release-tag' +import fse from 'fs-extra' +import fs from 'fs' +import path from 'path' +import type { RepoTestApi } from './types' const isPkgTag = pkgTagRe.test.bind(pkgTagRe) const pvmRoot = path.resolve(__dirname, '..') -function processPackageRoot(repoDir) { +function processPackageRoot(repoDir: string) { const pkgPath = path.join(repoDir, 'package.json') if (fs.existsSync(pkgPath)) { const pkgStr = fs.readFileSync(pkgPath).toString('utf8') @@ -38,7 +38,22 @@ function processPackageRoot(repoDir) { } } -const initRepo = async (name, config, repoOpts = {}) => { +function linkNodeModules(cwd: string) { + const source = path.resolve('node_modules') + const target = path.join(cwd, 'node_modules') + if (os.platform() === 'win32') { + cp.execSync(`mklink /D "${target}" "${source}"`) + } else { + cp.execSync(`ln -s "${source}" "${target}"`) + } +} + +const initRepo = async (name: string, config?: RecursivePartial | string, repoOpts: { + cwd?: string, + configFormat?: 'json' | 'toml' | 'js' + empty?: boolean + linkNodeModules?: boolean +} = {}): Promise => { let fullRepoDir = name let projectRoot = repoOpts.cwd ?? fullRepoDir @@ -55,7 +70,7 @@ const initRepo = async (name, config, repoOpts = {}) => { fs.mkdirSync(repoDir, { recursive: true, }) - } catch (e) { + } catch (e: any) { if (e.code === 'EEXIST') { return initRepo(baseName, config) } @@ -80,7 +95,7 @@ const initRepo = async (name, config, repoOpts = {}) => { await writeConfig({ dir: projectRoot }, config, repoOpts.configFormat) } - const gitShell = (cmd, opts = {}) => __unsafe_shell(cmd, { ...opts, cwd: fullRepoDir }).trim() + const gitShell = (cmd: string, opts = {}) => __unsafe_shell(cmd, { ...opts, cwd: fullRepoDir }).trim() const gitConfigTools = getGitConfigTools(gitShell) @@ -91,28 +106,40 @@ const initRepo = async (name, config, repoOpts = {}) => { gitShell('"mkdir" -p .git/gl') const repoData = dataFor(fullRepoDir) - let repoConfig = await getConfig(projectRoot) - const result = { + function makePvmApp() { + return new Pvm({ + cwd: projectRoot, + }) + } + + if (repoOpts.linkNodeModules) { + await linkNodeModules(projectRoot) + } + + let repoApp = makePvmApp() + + const repoTestApi: RepoTestApi = { dir: projectRoot, cwd: projectRoot, data: repoData, - get config() { - return repoConfig - }, + config: repoApp.getConfig(), + di: repoApp.container, async updateConfig(config) { + if (repoOpts.configFormat === 'js') { + throw new Error('Config update impossible for js format. Consider to use writeConfig instead') + } await writeConfig({ dir: this.cwd }, config, repoOpts.configFormat) - clearConfigCacheFor(this.cwd) - repoConfig = await getConfig(this.cwd) + repoApp = makePvmApp() + this.config = repoApp.getConfig() }, async syncConfig() { - clearConfigCacheFor(this.cwd) - repoConfig = await getConfig(this.cwd) + repoApp = makePvmApp() }, - async getHostApi() { - return await getHostApi(this.cwd) + getHostApi() { + return repoApp.container.get(HOST_API_TOKEN) }, - approvers(pickAttr = '') { + approvers(pickAttr?: keyof User) { const users = mapUsers(repoData.get('mr_approvals.approvers_ids'), false).sort((a, b) => { if (a.username === b.username) { return 0 @@ -124,7 +151,7 @@ const initRepo = async (name, config, repoOpts = {}) => { } return users }, - setApprovers(usernames) { + setApprovers(usernames: string[]) { repoData.set('mr_approvals.approvers_ids', usernames.reduce((acc, username) => { const user = getUser(username) if (user) { @@ -133,16 +160,14 @@ const initRepo = async (name, config, repoOpts = {}) => { throw new Error(`no such user ${username}`) } return acc - }, [])) + }, [] as number[])) }, shell: gitShell, lastReleaseTag() { - return lastReleaseTag(repoConfig) + return lastReleaseTag(this.config) }, getUpdateState() { - return getUpdateState({ - cwd: this.cwd, - }) + return repoApp.getUpdateState() }, readPkg(pkgPath) { return JSON.parse( @@ -159,7 +184,7 @@ const initRepo = async (name, config, repoOpts = {}) => { 'utf-8' ) }, - pkgVersion(pkgPath) { + pkgVersion(pkgPath: string) { return this.readPkg(pkgPath).version }, tags(ref = 'HEAD') { @@ -182,7 +207,7 @@ const initRepo = async (name, config, repoOpts = {}) => { fs.mkdirSync(path.resolve(this.cwd, dir), { recursive: true, }) - } catch (e) { + } catch (e: any) { if (e.code !== 'EEXIST') { throw e } @@ -217,7 +242,7 @@ const initRepo = async (name, config, repoOpts = {}) => { if (!Array.isArray(filepaths)) { filepaths = [filepaths] } - const cmd = [] + const cmd: string[] = [] const createdDirs = Object.create(null) for (const filepath of filepaths) { if (!(filepath in createdDirs)) { @@ -246,17 +271,11 @@ const initRepo = async (name, config, repoOpts = {}) => { async annotatedTag(tagName, annotation, ref = 'HEAD') { await this.runScript(`git tag --file=- ${tagName} ${ref}`, { input: annotation }) }, - async loadPkg(pkgPath, ref = void 0) { + loadPkg(pkgPath, ref = void 0) { return loadPkg(this.config, pkgPath, { cwd: this.cwd, ref: ref }) }, async linkNodeModules() { - const source = path.resolve('node_modules') - const target = path.join(this.cwd, 'node_modules') - if (os.platform() === 'win32') { - await runScript(this, `mklink /D "${target}" "${source}"`) - } else { - await runScript(this, `ln -s "${source}" "${target}"`) - } + linkNodeModules(this.cwd) }, async commit(message) { if (!message) { @@ -284,7 +303,7 @@ const initRepo = async (name, config, repoOpts = {}) => { getTagAnnotation(tagName) { return getTagAnnotation(this.cwd, tagName) }, - readFile(relPath, encoding = 'utf8') { + readFile(relPath, encoding: 'utf8' | 'ascii' | 'hex' = 'utf8') { return fs.readFileSync(path.resolve(this.cwd, relPath)).toString(encoding) }, existsPath(relPath) { @@ -306,7 +325,7 @@ const initRepo = async (name, config, repoOpts = {}) => { const initialSetupPath = path.join(fullRepoDir, '_setup.js') - let setupFunc = null + let setupFunc: null | ((repoTestApi: RepoTestApi) => void) = null if (fs.existsSync(initialSetupPath)) { setupFunc = require(initialSetupPath) fs.unlinkSync(initialSetupPath) @@ -333,13 +352,12 @@ const initRepo = async (name, config, repoOpts = {}) => { gitShell(`git fetch`) gitShell(`git fetch origin`) } - result.env.PVM_CONFIG_SEARCH_FROM = result.dir if (setupFunc) { - await setupFunc(result) + await setupFunc(repoTestApi) } - return result + return repoTestApi } -module.exports = initRepo +export default initRepo diff --git a/test/jest.setup.js b/test/jest.setup.js index bde19feae..dc85422ff 100644 --- a/test/jest.setup.js +++ b/test/jest.setup.js @@ -1,14 +1,3 @@ -const initRepo = require('./initRepo') -const { writeRepo } = require('./writeRepo') -const { runScript, execScript } = require('./executors') -const { writeConfig } = require('./helpers') - -global.initRepo = initRepo -global.runScript = runScript -global.execScript = execScript -global.writeConfig = writeConfig -global.writeRepo = writeRepo - Object.assign(process.env, { PVM_CONFIG_SEARCH_FROM: __dirname, PVM_CONFIG_JIRA__URL: 'https://jira.example.com', @@ -20,5 +9,5 @@ Object.assign(process.env, { PVM_TESTING_ENV: process.env.PVM_TESTING_ENV ?? 'true', NPM_TOKEN: '123', PVM_LL: process.env.PVM_LL || 'debug', - PVM_CONFIG_PLUGINS_V2: JSON.stringify([{ plugin: require.resolve('@pvm/gitlab/plugin') }]), + PVM_CONFIG_PLUGINS_V2: JSON.stringify([{ plugin: require.resolve('@pvm/plugin-gitlab') }]), }) diff --git a/test/npm-registry-mock/index.js b/test/npm-registry-mock/index.ts similarity index 69% rename from test/npm-registry-mock/index.js rename to test/npm-registry-mock/index.ts index fb9ae3dda..c37a7c166 100644 --- a/test/npm-registry-mock/index.js +++ b/test/npm-registry-mock/index.ts @@ -1,9 +1,15 @@ -const path = require('path') -const fs = require('fs-extra') -const { spawn } = require('child_process') -const getPort = require('get-port') +import path from 'path' +import fs from 'fs-extra' +import { spawn } from 'child_process' +import getPort from 'get-port' + +export interface NpmRegistryMock { + stop: () => void, + clear: () => void, + registryUrl: string +} -async function runRegistryMockServer() { +export async function runRegistryMockServer() { const npmRegistryMockPath = path.join(require('../mock-dir').mockDir, 'npm') if (fs.existsSync(npmRegistryMockPath)) { @@ -17,10 +23,10 @@ async function runRegistryMockServer() { const preparedConfig = fs.readFileSync(path.join(__dirname, 'verdaccio.config.yaml'), 'utf-8') .replace('$[STORAGE_PATH]', dbDirectory) fs.outputFileSync(preparedConfigPath, preparedConfig, 'utf-8') - let killTimeout - const freePort = await getPort() + let killTimeout: any + const freePort: string = (await getPort()).toString() - return new Promise(function(resolve, reject) { + return new Promise(function(resolve, reject) { const registryProc = spawn(`node`, [`node_modules/verdaccio/bin/verdaccio`, `--config`, preparedConfigPath, `--listen`, freePort ], { stdio: ['pipe', 'pipe', 'inherit'], }) @@ -33,8 +39,11 @@ async function runRegistryMockServer() { clearTimeout(killTimeout) resolve({ stop: registryProc.kill.bind(registryProc), - clear: () => fs.removeSync(dbDirectory) && fs.mkdirpSync(dbDirectory), - registryUrl: /(http:\/\/.*?\/)/.exec(logLine)[1], + clear: () => { + fs.removeSync(dbDirectory) + fs.mkdirpSync(dbDirectory) + }, + registryUrl: /(http:\/\/.*?\/)/.exec(logLine)?.[1]!, }) } }) @@ -50,5 +59,3 @@ async function runRegistryMockServer() { }, 5000) }) } - -module.exports.runRegistryMockServer = runRegistryMockServer diff --git a/test/platform-mock-helpers/paging.js b/test/platform-mock-helpers/paging.ts similarity index 74% rename from test/platform-mock-helpers/paging.js rename to test/platform-mock-helpers/paging.ts index 36a60ea7f..d01bb47b9 100644 --- a/test/platform-mock-helpers/paging.js +++ b/test/platform-mock-helpers/paging.ts @@ -1,10 +1,14 @@ const { get } = require('sprout-data') -function paginate(list, pagingQuery, opts = {}) { +export function paginate(list: any[], pagingQuery: { page: number, per_page: number, order_by: string, sort?: string}, opts: { + sortMap?: Record, + cmp?: (a: any, b: any) => number, + toComparable?: (a: any) => any +} = {}) { const { page, per_page, order_by, sort = 'desc' } = pagingQuery - const defaultComparator = (a, b) => { + const defaultComparator = (a: any, b: any) => { return sort === 'asc' ? a - b : b - a } @@ -40,7 +44,7 @@ function paginate(list, pagingQuery, opts = {}) { ] } -function pagingQuery(query, order_by_def = 'updated') { +export function pagingQuery(query: Record, order_by_def = 'updated') { const { sort = 'desc', order_by = order_by_def } = query const page = Number(query.page || 1) const per_page = Number(query.per_page || 20) @@ -52,6 +56,3 @@ function pagingQuery(query, order_by_def = 'updated') { sort, } } - -exports.paginate = paginate -exports.pagingQuery = pagingQuery diff --git a/test/platform-mock-helpers/repo-router-plugin.ts b/test/platform-mock-helpers/repo-router-plugin.ts index 72e364104..979cc08dc 100644 --- a/test/platform-mock-helpers/repo-router-plugin.ts +++ b/test/platform-mock-helpers/repo-router-plugin.ts @@ -2,15 +2,15 @@ import fs from 'fs' import path from 'path' import { dataFor } from '../git/data' -export default function repoRouterPlugin(router) { - router.param('id', function(req, res, next) { +export default function repoRouterPlugin(router: any) { + router.param('id', function(req: any, res: any, next: any) { const { reposDir } = req.app.locals - res.locals.repoDir = path.join(reposDir, req.params.id) - res.locals.repoData = dataFor(res.locals.repoDir) + res.app.locals.repoDir = path.join(reposDir, req.params.id) + res.app.locals.repoData = dataFor(res.app.locals.repoDir) - if (!fs.existsSync(res.locals.repoDir)) { - next(new Error(`There is no directory ${res.locals.repoDir}`)) + if (!fs.existsSync(res.app.locals.repoDir)) { + next(new Error(`There is no directory ${res.app.locals.repoDir}`)) } else { next() } diff --git a/test/repos-dir.js b/test/repos-dir.js deleted file mode 100644 index d7c67fc01..000000000 --- a/test/repos-dir.js +++ /dev/null @@ -1,4 +0,0 @@ -const os = require('os') -const path = require('path') - -exports.reposDir = path.join(os.tmpdir(), 'pvm__repos') diff --git a/test/repos-dir.ts b/test/repos-dir.ts new file mode 100644 index 000000000..048785f54 --- /dev/null +++ b/test/repos-dir.ts @@ -0,0 +1,4 @@ +import os from 'os' +import path from 'path' + +export const reposDir = path.join(os.tmpdir(), 'pvm__repos') diff --git a/test/repos/local-plugins/pvm-local/local.js b/test/repos/local-plugins/pvm-local/local.js deleted file mode 100644 index 0eb2a0c78..000000000 --- a/test/repos/local-plugins/pvm-local/local.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = async (pluginsApi) => { - pluginsApi.provides('git.push_remote', async () => { - console.log('git.push_remote executed') - return 'remote' - }) - - await Promise.resolve() - console.log(`local plugin loaded sucessfully. Branch: ${require('child_process').execSync('git rev-parse --abbrev-ref HEAD', { cwd: pluginsApi.cwd })}`) -} diff --git a/test/repos/mono-conventional-c/package.json b/test/repos/mono-conventional-c/package.json index e17e4f70a..a2d12e2df 100644 --- a/test/repos/mono-conventional-c/package.json +++ b/test/repos/mono-conventional-c/package.json @@ -3,8 +3,5 @@ "private": true, "workspaces": [ "src/*" - ], - "dependencies": { - "@pvm/plugin-conventional-changelog": "not meant to be installed" - } + ] } diff --git a/test/repos/pvm-provider/package.json b/test/repos/pvm-provider/package.json deleted file mode 100644 index 7d739a54a..000000000 --- a/test/repos/pvm-provider/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "monouno", - "private": true, - "workspaces": [ - "src/*" - ], - "devDependencies": { - "@company/pvm": "file:./provider-dep" - } -} diff --git a/test/repos/pvm-provider/provider-dep/configDefaults.js b/test/repos/pvm-provider/provider-dep/configDefaults.js deleted file mode 100644 index d03b1ac86..000000000 --- a/test/repos/pvm-provider/provider-dep/configDefaults.js +++ /dev/null @@ -1,6 +0,0 @@ - -module.exports = { - changelog: { - path: 'changelog-provider-test.md', - }, -} diff --git a/test/repos/pvm-provider/provider-dep/package.json b/test/repos/pvm-provider/provider-dep/package.json deleted file mode 100644 index ad559b967..000000000 --- a/test/repos/pvm-provider/provider-dep/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "@company/pvm", - "version": "0.1.0", - "pvm": { - "provider": true, - "configDefaults": "./configDefaults.js" - }, - "dependencies": { - "@company/pvm-plugin-dep": "file:./pvm-plugin-dep" - } -} diff --git a/test/repos/pvm-provider/provider-dep/pvm-plugin-dep/package.json b/test/repos/pvm-provider/provider-dep/pvm-plugin-dep/package.json deleted file mode 100644 index a042ea1d5..000000000 --- a/test/repos/pvm-provider/provider-dep/pvm-plugin-dep/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "@company/pvm-plugin-dep", - "version": "0.1.0", - "main": "plugin-dep.js" -} diff --git a/test/repos/pvm-provider/provider-dep/pvm-plugin-dep/plugin-dep.js b/test/repos/pvm-provider/provider-dep/pvm-plugin-dep/plugin-dep.js deleted file mode 100644 index f14a10f0f..000000000 --- a/test/repos/pvm-provider/provider-dep/pvm-plugin-dep/plugin-dep.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = function(api) { - api.provides('test.fn', () => 'test.fn') -} diff --git a/test/scenarios/__fixtures__/boot-test.js b/test/scenarios/__fixtures__/boot-test.js index 04b3271c2..24fbcb06d 100644 --- a/test/scenarios/__fixtures__/boot-test.js +++ b/test/scenarios/__fixtures__/boot-test.js @@ -1,2 +1,2 @@ process.chdir(process.argv[1]) -require('@pvm/core/lib/node-boot') +require('@pvm/pvm/lib/node-boot') diff --git a/test/scenarios/__fixtures__/failing-slack-plugin.ts b/test/scenarios/__fixtures__/failing-slack-plugin.ts new file mode 100644 index 000000000..91a5d22e1 --- /dev/null +++ b/test/scenarios/__fixtures__/failing-slack-plugin.ts @@ -0,0 +1,28 @@ +import type { MessengerClientConfig } from '@pvm/pvm' +import { declarePlugin, Notificator, provide, AbstractMessengerClient } from '@pvm/pvm' +import { CONFIG_TOKEN, CWD_TOKEN, MESSENGER_CLIENT_TOKEN } from '@pvm/pvm/tokens' + +export default declarePlugin({ + factory: (opts: MessengerClientConfig & { name?: string }) => ({ + providers: [ + provide({ + provide: MESSENGER_CLIENT_TOKEN, + useFactory: ({ config }) => Notificator.createClient(// @ts-ignore + class FailingClient extends AbstractMessengerClient { + isReady() { return true } + // @ts-ignore + internalSendMessage() { + throw new Error('Send failed') + } + }, config, { + name: 'slack', + ...opts, + }), + deps: { + config: CONFIG_TOKEN, + cwd: CWD_TOKEN, + }, + }), + ], + }), +}) diff --git a/test/scenarios/__fixtures__/not-ready-slack-plugin.ts b/test/scenarios/__fixtures__/not-ready-slack-plugin.ts new file mode 100644 index 000000000..c32f14edd --- /dev/null +++ b/test/scenarios/__fixtures__/not-ready-slack-plugin.ts @@ -0,0 +1,27 @@ +import type { MessengerClientConfig } from '@pvm/pvm' +import { declarePlugin, Notificator, provide, AbstractMessengerClient } from '@pvm/pvm' +import { CONFIG_TOKEN, CWD_TOKEN, MESSENGER_CLIENT_TOKEN } from '@pvm/pvm/tokens' + +export default declarePlugin({ + factory: (opts: MessengerClientConfig & { name?: string }) => ({ + providers: [ + provide({ + provide: MESSENGER_CLIENT_TOKEN, + useFactory: ({ config }) => Notificator.createClient(// @ts-ignore + class FailingClient extends AbstractMessengerClient { + isReady() { return false } + // @ts-ignore + internalSendMessage() { + } + }, config, { + name: 'slack', + ...opts, + }), + deps: { + config: CONFIG_TOKEN, + cwd: CWD_TOKEN, + }, + }), + ], + }), +}) diff --git a/test/scenarios/__snapshots__/pvm-changelog.spec.js.snap b/test/scenarios/__snapshots__/pvm-changelog.spec.ts.snap similarity index 63% rename from test/scenarios/__snapshots__/pvm-changelog.spec.js.snap rename to test/scenarios/__snapshots__/pvm-changelog.spec.ts.snap index a0503c94d..78b48b99e 100644 --- a/test/scenarios/__snapshots__/pvm-changelog.spec.js.snap +++ b/test/scenarios/__snapshots__/pvm-changelog.spec.ts.snap @@ -6,10 +6,18 @@ exports[`pvm/changelog [mono] in default config should use package version for p change a again +List of updated packages: +- a@1.2.0 +- b@2.0.2 + ## v1.1.0 **2018.11.27** -change a" +change a + +List of updated packages: +- a@1.1.0 +- b@2.0.1" `; exports[`pvm/changelog [nomono] should not generate empty section if there are no commits since release 1`] = ` @@ -18,15 +26,24 @@ exports[`pvm/changelog [nomono] should not generate empty section if there are n The Captain’s Daughter +List of updated packages: +- simple-one@2.0.0 + ## v1.1.0 **2018.11.27** Dubrovsky +List of updated packages: +- simple-one@1.1.0 + ## v1.0.0 **2018.11.27** -Eugene Onegin" +Eugene Onegin + +List of updated packages: +- simple-one@1.0.0" `; exports[`pvm/changelog should able to regenerate changelog from scratch 1`] = ` @@ -35,8 +52,17 @@ exports[`pvm/changelog should able to regenerate changelog from scratch 1`] = ` change b and c +List of updated packages: +- b@2.2.0 +- c@1.0.0 + ## release-2018.11.27-Gorno-Altaysk **2018.11.27** -change a and b" +change a and b + +List of updated packages: +- a@1.1.0 +- b@2.1.0 +- c@1.0.0-beta.1" `; diff --git a/test/scenarios/__snapshots__/pvm-publish.spec.js.snap b/test/scenarios/__snapshots__/pvm-publish.spec.js.snap deleted file mode 100644 index 074d7920c..000000000 --- a/test/scenarios/__snapshots__/pvm-publish.spec.js.snap +++ /dev/null @@ -1,100 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`pvm/publish multi-package: get version for publishing from git 1`] = ` -"{ - \\"success\\": [ - { - \\"pkg\\": \\"a\\", - \\"registryVersion\\": null, - \\"publishedVersion\\": \\"10.0.0\\", - \\"type\\": \\"success\\" - }, - { - \\"pkg\\": \\"b\\", - \\"registryVersion\\": null, - \\"publishedVersion\\": \\"20.0.0-rc.1\\", - \\"type\\": \\"success\\" - }, - { - \\"pkg\\": \\"c\\", - \\"registryVersion\\": null, - \\"publishedVersion\\": \\"0.0.1\\", - \\"type\\": \\"success\\" - } - ], - \\"skipped\\": [], - \\"error\\": [] -}" -`; - -exports[`pvm/publish single-package: get version for publishing from git 1`] = ` -"{ - \\"success\\": [ - { - \\"pkg\\": \\"two-releases\\", - \\"registryVersion\\": null, - \\"publishedVersion\\": \\"10.0.0\\", - \\"type\\": \\"success\\" - } - ], - \\"skipped\\": [], - \\"error\\": [] -}" -`; - -exports[`pvm/publish команда pvm publish успешно отрабатывает c опцией output-stats 1`] = ` -"{ - \\"success\\": [ - { - \\"pkg\\": \\"@tinkoff-boxy/desktop-product-footer\\", - \\"registryVersion\\": null, - \\"publishedVersion\\": \\"2.0.1\\", - \\"type\\": \\"success\\" - }, - { - \\"pkg\\": \\"a\\", - \\"registryVersion\\": null, - \\"publishedVersion\\": \\"1.0.1\\", - \\"type\\": \\"success\\" - }, - { - \\"pkg\\": \\"d\\", - \\"registryVersion\\": null, - \\"publishedVersion\\": \\"1.1.0\\", - \\"type\\": \\"success\\" - } - ], - \\"skipped\\": [], - \\"error\\": [] -}" -`; - -exports[`pvm/publish паблиш на релизном тэге вот-с-таким-кейсом 1`] = ` -"{ - \\"success\\": [ - { - \\"pkg\\": \\"a\\", - \\"registryVersion\\": null, - \\"publishedVersion\\": \\"1.0.0\\", - \\"type\\": \\"success\\" - } - ], - \\"skipped\\": [], - \\"error\\": [] -}" -`; - -exports[`pvm/publish паблиш с замапленной папки 1`] = ` -"{ - \\"success\\": [ - { - \\"pkg\\": \\"c\\", - \\"registryVersion\\": null, - \\"publishedVersion\\": \\"1.0.0-beta.1\\", - \\"type\\": \\"success\\" - } - ], - \\"skipped\\": [], - \\"error\\": [] -}" -`; diff --git a/test/scenarios/__snapshots__/pvm-publish.spec.ts.snap b/test/scenarios/__snapshots__/pvm-publish.spec.ts.snap new file mode 100644 index 000000000..75eda9621 --- /dev/null +++ b/test/scenarios/__snapshots__/pvm-publish.spec.ts.snap @@ -0,0 +1,100 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`pvm/publish multi-package: get version for publishing from git 1`] = ` +"{ + "success": [ + { + "pkg": "a", + "registryVersion": null, + "publishedVersion": "10.0.0", + "type": "success" + }, + { + "pkg": "b", + "registryVersion": null, + "publishedVersion": "20.0.0-rc.1", + "type": "success" + }, + { + "pkg": "c", + "registryVersion": null, + "publishedVersion": "0.0.1", + "type": "success" + } + ], + "skipped": [], + "error": [] +}" +`; + +exports[`pvm/publish single-package: get version for publishing from git 1`] = ` +"{ + "success": [ + { + "pkg": "two-releases", + "registryVersion": null, + "publishedVersion": "10.0.0", + "type": "success" + } + ], + "skipped": [], + "error": [] +}" +`; + +exports[`pvm/publish команда pvm publish успешно отрабатывает c опцией output-stats 1`] = ` +"{ + "success": [ + { + "pkg": "@tinkoff-boxy/desktop-product-footer", + "registryVersion": null, + "publishedVersion": "2.0.1", + "type": "success" + }, + { + "pkg": "a", + "registryVersion": null, + "publishedVersion": "1.0.1", + "type": "success" + }, + { + "pkg": "d", + "registryVersion": null, + "publishedVersion": "1.1.0", + "type": "success" + } + ], + "skipped": [], + "error": [] +}" +`; + +exports[`pvm/publish паблиш на релизном тэге вот-с-таким-кейсом 1`] = ` +"{ + "success": [ + { + "pkg": "a", + "registryVersion": null, + "publishedVersion": "1.0.0", + "type": "success" + } + ], + "skipped": [], + "error": [] +}" +`; + +exports[`pvm/publish паблиш с замапленной папки 1`] = ` +"{ + "success": [ + { + "pkg": "c", + "registryVersion": null, + "publishedVersion": "1.0.0-beta.1", + "type": "success" + } + ], + "skipped": [], + "error": [] +}" +`; diff --git a/test/scenarios/__snapshots__/pvm-update.spec.js.snap b/test/scenarios/__snapshots__/pvm-update.spec.ts.snap similarity index 68% rename from test/scenarios/__snapshots__/pvm-update.spec.js.snap rename to test/scenarios/__snapshots__/pvm-update.spec.ts.snap index 192f24345..b4920602f 100644 --- a/test/scenarios/__snapshots__/pvm-update.spec.js.snap +++ b/test/scenarios/__snapshots__/pvm-update.spec.ts.snap @@ -9,21 +9,21 @@ digraph p { concentrate=true; center=true; fontname=Helvetica - labelloc=\\"t\\" + labelloc="t" ranksep=0.5 node [fontname=Helvetica fontsize=20] edge [color=grey fontname=Helvetica] subgraph cluster_0 { - label=legend color=\\"#eeeeee\\" style=filled - new[tooltip=\\"release-type: new\\" shape=ellipse color=\\"#11ccbb\\"] + label=legend color="#eeeeee" style=filled + new[tooltip="release-type: new" shape=ellipse color="#11ccbb"] } subgraph cluster_1 { penwidth=0; - label=\\"Packages about to update\\"; + label="Packages about to update"; - new[label=\\"new@1.0.0\\" tooltip=\\"release-type: new\\" shape=ellipse color=\\"#11ccbb\\"] + new[label="new@1.0.0" tooltip="release-type: new" shape=ellipse color="#11ccbb"] } } " diff --git a/test/scenarios/pvm-add-tag.spec.js b/test/scenarios/pvm-add-tag.spec.ts similarity index 88% rename from test/scenarios/pvm-add-tag.spec.js rename to test/scenarios/pvm-add-tag.spec.ts index 626e1ea38..207e852e0 100644 --- a/test/scenarios/pvm-add-tag.spec.js +++ b/test/scenarios/pvm-add-tag.spec.ts @@ -1,4 +1,7 @@ -const lastTag = require('../../packages/pvm-core/lib/git/last-tag').default +import initRepo from '../initRepo' +import { runScript } from '../executors' + +const lastTag = require('../../packages/pvm/lib/git/last-tag').default describe('pvm/add-tag', () => { it('должен учитывать конфиг', async () => { diff --git a/test/scenarios/pvm-changelog.spec.js b/test/scenarios/pvm-changelog.spec.ts similarity index 97% rename from test/scenarios/pvm-changelog.spec.js rename to test/scenarios/pvm-changelog.spec.ts index 738536056..1d2fc27d2 100644 --- a/test/scenarios/pvm-changelog.spec.js +++ b/test/scenarios/pvm-changelog.spec.ts @@ -1,5 +1,7 @@ -const fs = require('fs') -const path = require('path') +import fs from 'fs' +import path from 'path' +import initRepo from '../initRepo' +import { writeRepo } from '../writeRepo' describe('pvm/changelog', () => { it('[nomono] should not generate empty section if there are no commits since release', async () => { @@ -138,7 +140,7 @@ describe('pvm/changelog', () => { await repo.runScript('pvm changelog make') expect(repo.shell('cat changelog.md')).toMatchSnapshot() - }) + }, 500000) it('should include upcoming release in case append-upcoming-release option', async () => { const repo = await initRepo('monorepo-new', { diff --git a/test/scenarios/pvm-core.spec.js b/test/scenarios/pvm-core.spec.ts similarity index 78% rename from test/scenarios/pvm-core.spec.js rename to test/scenarios/pvm-core.spec.ts index 3783448bf..3d8300b63 100644 --- a/test/scenarios/pvm-core.spec.js +++ b/test/scenarios/pvm-core.spec.ts @@ -1,4 +1,7 @@ -const { loadPkg } = require('../../packages/pvm-core/lib/pkg') +import initRepo from '../initRepo' +import { writeRepo } from '../writeRepo' + +const { loadPkg } = require('../../packages/pvm/lib/pkg') const path = require('path') describe('pvm-core', () => { @@ -20,14 +23,14 @@ describe('pvm-core', () => { it('config loader should load config from cwd folder', async () => { const repo = await initRepo(writeRepo({ name: 'config-load', - spec: 'configCwd@1.0.0', + spec: 'src/configCwd@1.0.0', })) - await repo.writeFile('configCwd/.pvm.toml', `[test] + await repo.writeFile('src/configCwd/.pvm.toml', `[test] test = 'test'`) const { stdout } = await repo.execScript('pvm show config', { - cwd: path.resolve(repo.cwd, 'configCwd'), + cwd: path.resolve(repo.cwd, 'src', 'configCwd'), }) expect(stdout).toMatch('[test]') @@ -36,10 +39,10 @@ test = 'test'`) it('update-hints.toml should load from cwd, not git root', async () => { const repoPath = writeRepo({ name: 'config-load', - spec: 'configCwd@1.0.0', + spec: 'src/configCwd@1.0.0', }) const repo = await initRepo(repoPath, {}, { - cwd: path.join(repoPath, 'configCwd'), + cwd: path.join(repoPath, 'src', 'configCwd'), }) await repo.writeFile('update-hints.toml', `release-type = 'major'`, 'hints') @@ -62,6 +65,6 @@ test = 'test'`) const upPkg = updateState.updateReasonMap.keys().next().value expect(upPkg.name).toBe('workspace-pkg') - expect(updateState.updateReasonMap.get(upPkg)).toBe('by_commits') + expect(updateState.updateReasonMap.get(upPkg)).toBe('changed') }) }) diff --git a/test/scenarios/pvm-files.spec.js b/test/scenarios/pvm-files.spec.ts similarity index 85% rename from test/scenarios/pvm-files.spec.js rename to test/scenarios/pvm-files.spec.ts index c225ae818..346d12cbe 100644 --- a/test/scenarios/pvm-files.spec.js +++ b/test/scenarios/pvm-files.spec.ts @@ -1,5 +1,7 @@ -const getFiles = require('../../packages/pvm-files').default -const path = require('path') +import initRepo from '../initRepo' +import { execScript } from '../executors' +import path from 'path' +import getFiles from '@pvm/pvm/mechanics/files/files' describe('pvm/files', () => { it('should work for relative', async () => { @@ -7,7 +9,7 @@ describe('pvm/files', () => { await repo.writeFile('src/a/for-collect.js', 'Some script', `Change a`) - const res = await getFiles('src/*/*.js', { + const res = await getFiles(repo.di, 'src/*/*.js', { cwd: repo.dir, strategy: 'affected', includeUncommited: true, @@ -22,7 +24,7 @@ describe('pvm/files', () => { await repo.writeFile('src/a/for-collect.js', 'Some script', `Change a`) - const res = await getFiles('src/*/*.js', { + const res = await getFiles(repo.di, 'src/*/*.js', { cwd: repo.dir, strategy: 'affected', includeUncommited: true, @@ -37,7 +39,7 @@ describe('pvm/files', () => { await repo.writeFile('src/c/for-collect.js', 'Some script') await repo.writeFile('src/root.js', 'Some script', `Change root`) - const res = await getFiles('src/root.js', { + const res = await getFiles(repo.di, 'src/root.js', { cwd: repo.dir, strategy: 'affected', includeRoot: true, @@ -54,7 +56,7 @@ describe('pvm/files', () => { await repo.writeFile('src/b/for-collect.js', 'Some script', 'Change b') await repo.writeFile('src/for-collect.js', 'Some script', `Change root`) - const res = await getFiles('src/**/for-collect.js', { + const res = await getFiles(repo.di, 'src/**/for-collect.js', { cwd: repo.dir, strategy: 'affected', includeRoot: true, @@ -72,7 +74,7 @@ describe('pvm/files', () => { }) await repo.writeFile('src/for-collect.js', 'Some script', `Change root`) - const res = await getFiles('src/**/for-collect.js', { + const res = await getFiles(repo.di, 'src/**/for-collect.js', { cwd: repo.dir, strategy: 'affected', includeUncommited: false, diff --git a/test/scenarios/pvm-git-branch-storage.spec.js b/test/scenarios/pvm-git-branch-storage.spec.js deleted file mode 100644 index e580299d6..000000000 --- a/test/scenarios/pvm-git-branch-storage.spec.js +++ /dev/null @@ -1,49 +0,0 @@ -const { getConfig } = require('@pvm/core/lib/config') -const { GitBranchStorage } = require('@pvm/artifacts/lib/backend/git-branch-storage') - -describe('pvm-git-branch-storage', () => { - it('config and plugins should load from main worktree', async () => { - const repo = await initRepo('local-plugins', { - update: { - include_root: true, - }, - plugins: { - local_plugins: [ - 'pvm-local/local.js', - ], - }, - plugins_v2: [ - { - plugin: './pvm-plugin-v2/plugin.js', - }, - ], - changelog: { - enabled: true, - storage: { - type: 'branch', - branch: 'pvm-artifacts', - }, - }, - }) - - await repo.writeFile('change_trigger.txt', 'change', 'change') - - const { stdout } = await repo.execScript('pvm update') - - expect(stdout).toMatch(/local plugin loaded sucessfully. Branch: pvm-artifacts/) - expect(stdout).toMatch(/plugin_v2 loaded successfully/) - }) - - it('defaults for new worktree cwd should be taken from main worktree config', async () => { - const repo = await initRepo('pvm-provider') - const gitBranchStorage = new GitBranchStorage({ - cwd: repo.cwd, - branch: 'pvm-artifacts', - }) - await gitBranchStorage.init() - console.log(gitBranchStorage.workingDir) - const config = await getConfig(gitBranchStorage.workingDir) - - expect(config.changelog.path).toEqual('changelog-provider-test.md') - }) -}) diff --git a/test/scenarios/pvm-git-branch-storage.spec.ts b/test/scenarios/pvm-git-branch-storage.spec.ts new file mode 100644 index 000000000..5b7e619d4 --- /dev/null +++ b/test/scenarios/pvm-git-branch-storage.spec.ts @@ -0,0 +1,29 @@ +import initRepo from '../initRepo' + +describe('pvm-git-branch-storage', () => { + it('config and plugins should load from main worktree', async () => { + const repo = await initRepo('local-plugins', { + update: { + include_root: true, + }, + plugins_v2: [ + { + plugin: './pvm-plugin-v2/plugin.js', + }, + ], + changelog: { + enabled: true, + storage: { + type: 'branch', + branch: 'pvm-artifacts', + }, + }, + }) + + await repo.writeFile('change_trigger.txt', 'change', 'change') + + const { stdout } = await repo.execScript('pvm update') + + expect(stdout).toMatch(/plugin_v2 loaded successfully/) + }) +}) diff --git a/test/scenarios/pvm-local-plugins.spec.js b/test/scenarios/pvm-local-plugins.spec.js deleted file mode 100644 index 3fb1fc25c..000000000 --- a/test/scenarios/pvm-local-plugins.spec.js +++ /dev/null @@ -1,15 +0,0 @@ - -describe('pvm/local-plugins', () => { - it('should load local plugins', async () => { - const repo = await initRepo('local-plugins', { - plugins: { - local_plugins: [ - 'pvm-local/local.js', - ], - }, - }) - - const { stdout } = await repo.execScript('pvm update') - expect(stdout).toMatch(/local plugin loaded sucessfully/) - }) -}) diff --git a/test/scenarios/pvm-notes.spec.js b/test/scenarios/pvm-notes.spec.ts similarity index 92% rename from test/scenarios/pvm-notes.spec.js rename to test/scenarios/pvm-notes.spec.ts index 490c544d8..e791f8ce4 100644 --- a/test/scenarios/pvm-notes.spec.js +++ b/test/scenarios/pvm-notes.spec.ts @@ -1,3 +1,5 @@ +import initRepo from '../initRepo' +import { runScript } from '../executors' describe('pvm/notes', () => { it('релизные ноты из одного коммита', async () => { diff --git a/test/scenarios/pvm-notification.spec.js b/test/scenarios/pvm-notification.spec.ts similarity index 78% rename from test/scenarios/pvm-notification.spec.js rename to test/scenarios/pvm-notification.spec.ts index cbd13c606..0ba3e628d 100644 --- a/test/scenarios/pvm-notification.spec.js +++ b/test/scenarios/pvm-notification.spec.ts @@ -1,8 +1,14 @@ -const path = require('path') -const { runMessengerMocker } = require('../slack-mock') +import type { SlackMock } from '../slack-mock' +import { runMessengerMocker } from '../slack-mock' + +import { execScript, runScript } from '../executors' +import initRepo from '../initRepo' +import type { Message } from '@pvm/pvm' +import type { Request, Response } from 'express' +import type { RepoTestApi } from '../types' describe('pvm-notification', () => { - let slackMocker + let slackMocker: SlackMock beforeAll(async () => { slackMocker = await runMessengerMocker() }) @@ -21,16 +27,6 @@ describe('pvm-notification', () => { const repo = await initRepo('simple-one', { notifications: { target: 'all', - clients: [ - { - name: 'slack', - pkg: '@pvm/slack', - }, - { - name: 'another_slack', - pkg: '@pvm/slack', - }, - ], client_configs: { slack: { channel: 'c1', @@ -40,6 +36,18 @@ describe('pvm-notification', () => { }, }, }, + plugins_v2: [{ + plugin: require.resolve('@pvm/plugin-slack'), + options: { + name: 'slack', + }, + }, + { + plugin: require.resolve('@pvm/plugin-slack'), + options: { + name: 'another_slack', + }, + }], }) await runScript(repo, 'pvm notification send -m hello', { @@ -73,22 +81,12 @@ describe('pvm-notification', () => { it('should send all messages and throw error if some failed', async () => { const slackRequests = collectSlackRequests(slackMocker) - const repo = await initRepo('simple-one') - await repo.linkNodeModules() - const failingMessengerClientPath = await createFailingMessengerClient(repo) + const repo = await initRepo('simple-one', {}, { + linkNodeModules: true, + }) await repo.updateConfig({ notifications: { target: 'all', - clients: [ - { - name: 'slack', - pkg: failingMessengerClientPath, - }, - { - name: 'another_slack', - pkg: '@pvm/slack', - }, - ], client_configs: { slack: { channel: 'c1', @@ -98,6 +96,18 @@ describe('pvm-notification', () => { }, }, }, + plugins_v2: [{ + plugin: require.resolve('./__fixtures__/failing-slack-plugin'), + options: { + name: 'failing_slack', + }, + }, + { + plugin: require.resolve('@pvm/plugin-slack'), + options: { + name: 'another_slack', + }, + }], }) await expect(runScript(repo, 'pvm notification send -m hello', { @@ -119,20 +129,22 @@ describe('pvm-notification', () => { await repo.updateConfig({ notifications: { target: 'all', - clients: [ - { - name: 'slack', - pkg: '@pvm/slack', - }, - { - name: 'another_slack', - pkg: '@pvm/slack', - }, - ], clients_common_config: { channel: 'c1', }, }, + plugins_v2: [{ + plugin: require.resolve('@pvm/plugin-slack'), + options: { + name: 'slack', + }, + }, + { + plugin: require.resolve('@pvm/plugin-slack'), + options: { + name: 'another_slack', + }, + }], }) await runScript(repo, 'pvm notification send -m hello', { @@ -155,23 +167,12 @@ describe('pvm-notification', () => { describe('target = first_available', () => { it('should work', async () => { const slackRequests = collectSlackRequests(slackMocker) - const repo = await initRepo('simple-one') - await repo.linkNodeModules() - const notReadyMessageClientPath = await createNotReadyMessageClient(repo) + const repo = await initRepo('simple-one', {}, { + linkNodeModules: true, + }) await repo.updateConfig({ notifications: { target: 'all', - order: ['slack', 'another_slack'], - clients: [ - { - name: 'slack', - pkg: notReadyMessageClientPath, - }, - { - name: 'another_slack', - pkg: '@pvm/slack', - }, - ], client_configs: { slack: { channel: 'c1', @@ -181,6 +182,18 @@ describe('pvm-notification', () => { }, }, }, + plugins_v2: [{ + plugin: require.resolve('./__fixtures__/not-ready-slack-plugin'), + options: { + name: 'slack', + }, + }, + { + plugin: require.resolve('@pvm/plugin-slack'), + options: { + name: 'another_slack', + }, + }], }) await runScript(repo, 'pvm notification send -m hello', { @@ -204,16 +217,6 @@ describe('pvm-notification', () => { await repo.updateConfig({ notifications: { target: 'another_slack', - clients: [ - { - name: 'slack', - pkg: '@pvm/slack', - }, - { - name: 'another_slack', - pkg: '@pvm/slack', - }, - ], client_configs: { slack: { channel: 'c1', @@ -223,6 +226,18 @@ describe('pvm-notification', () => { }, }, }, + plugins_v2: [{ + plugin: require.resolve('@pvm/plugin-slack'), + options: { + name: 'slack', + }, + }, + { + plugin: require.resolve('@pvm/plugin-slack'), + options: { + name: 'another_slack', + }, + }], }) await runScript(repo, 'pvm notification send -m hello', { @@ -244,16 +259,6 @@ describe('pvm-notification', () => { await repo.updateConfig({ notifications: { target: ['another_slack', 'slack'], - clients: [ - { - name: 'slack', - pkg: '@pvm/slack', - }, - { - name: 'another_slack', - pkg: '@pvm/slack', - }, - ], client_configs: { slack: { channel: 'c1', @@ -263,6 +268,18 @@ describe('pvm-notification', () => { }, }, }, + plugins_v2: [{ + plugin: require.resolve('@pvm/plugin-slack'), + options: { + name: 'slack', + }, + }, + { + plugin: require.resolve('@pvm/plugin-slack'), + options: { + name: 'another_slack', + }, + }], }) await runScript(repo, 'pvm notification send -m hello', { @@ -288,32 +305,27 @@ describe('pvm-notification', () => { describe('cli', () => { describe('common', () => { - let repo + let repo: RepoTestApi const testCLI = testCLIFactory(() => ({ repo, slackMocker })) beforeAll(async () => { repo = await initRepo('simple-one', { - notifications: { - clients: [ - { - name: 'slack', - pkg: '@pvm/slack', - }, - { - name: 'another_slack', - pkg: '@pvm/slack', - }, - ], - client_configs: { - slack: { + plugins_v2: [ + { + plugin: require.resolve('@pvm/plugin-slack'), + options: { channel: 'c1', }, - another_slack: { + }, + { + plugin: require.resolve('@pvm/plugin-slack'), + options: { + name: 'another_slack', channel: 'c2', }, }, - }, + ], }) }) testCLI( @@ -392,25 +404,20 @@ describe('pvm-notification', () => { }) describe('mattermost', () => { - let repo + let repo: RepoTestApi const testCLI = testCLIFactory(() => ({ repo, slackMocker })) beforeAll(async () => { repo = await initRepo('simple-one', { - notifications: { - clients: [ - { - name: 'mattermost', - pkg: '@pvm/mattermost', - }, - ], - client_configs: { - mattermost: { + plugins_v2: [ + { + plugin: require.resolve('@pvm/plugin-mattermost'), + options: { channel: 'm1', }, }, - }, + ], }) }) @@ -521,7 +528,7 @@ describe('pvm-notification', () => { }) describe('slack', () => { - let repo + let repo: RepoTestApi const testCLI = testCLIFactory(() => ({ repo, @@ -530,25 +537,26 @@ describe('pvm-notification', () => { beforeAll(async () => { repo = await initRepo('simple-one', { - notifications: { - clients: [ - { - name: 'slack', - pkg: '@pvm/slack', - }, - ], - client_configs: { - slack: { + plugins_v2: [ + { + plugin: require.resolve('@pvm/plugin-slack'), + options: { channel: 'c1', }, }, - }, + ], }) }) it('should be backward compatible with slack_nofitication', async () => { const slackRequests = collectSlackRequests(slackMocker) - const repo = await initRepo('simple-one') + const repo = await initRepo('simple-one', { + plugins_v2: [ + { + plugin: require.resolve('@pvm/plugin-slack'), + }, + ], + }) await repo.updateConfig({ slack_notification: { channel: 'c2', @@ -557,12 +565,6 @@ describe('pvm-notification', () => { }, notifications: { target: ['slack'], - clients: [ - { - name: 'slack', - pkg: '@pvm/slack', - }, - ], }, }) @@ -630,9 +632,6 @@ describe('pvm-notification', () => { attachments: [{ title: '​*attachment*​', text: '​*text*​', - obj: { - test: 123, - }, }], }, { @@ -641,9 +640,6 @@ describe('pvm-notification', () => { attachments: [{ title: '**attachment**', text: '**text**', - obj: { - test: 123, - }, }], }, } @@ -652,10 +648,10 @@ describe('pvm-notification', () => { }) }) -function collectSlackRequests(slackMocker, cb = () => {}) { - const slackRequests = [] +function collectSlackRequests(slackMocker: SlackMock, cb: ({ body, res, reqIndex }: { body: any, res: Response, reqIndex: number }) => void = () => {}) { + const slackRequests: { body: Record, res: Response }[] = [] let reqIndex = 0 - slackMocker.spy((req, res) => { + slackMocker.spy((req: Request, res: Response) => { slackRequests.push({ body: req.body, res }) // eslint-disable-next-line node/no-callback-literal @@ -666,39 +662,17 @@ function collectSlackRequests(slackMocker, cb = () => {}) { return slackRequests } -async function createFailingMessengerClient(repo) { - const fileName = 'broken_messenger_client.js' - await repo.writeFile(fileName, ` -const AbstractMessengerClient = require('@pvm/notifications').AbstractMessengerClient -module.exports.MessengerClient = class Client extends AbstractMessengerClient { - isReady() { return true } - async internalSendMessage() { - throw new Error('Send failed') - } -} - `) - - return path.join(repo.cwd, fileName) -} - -async function createNotReadyMessageClient(repo) { - const fileName = 'broken_messenger_client.js' - await repo.writeFile(fileName, ` -const AbstractMessengerClient = require('@pvm/notifications').AbstractMessengerClient -module.exports.MessengerClient = class Client extends AbstractMessengerClient { - isReady() { return false } - internalSendMessage() { - - } -} - `) - - return path.join(repo.cwd, fileName) -} - -function testCLIFactory(contextReceiver) { +function testCLIFactory(contextReceiver: () => { repo: RepoTestApi, slackMocker: SlackMock }) { return function testCLI( - cmd, conditions, inputConfig = {} + cmd: string, conditions: Partial<{ + requestsCount: number, + content: string, + attachments: Message['attachments'], + channel: string | string[], + target: string, + stderr: string | RegExp + }>, + inputConfig: Partial<{ env: Record, testName: string, message: Record, stdin: string, statusCode: (opts: { body: Record, res: Response, reqIndex: number}) => number, only: boolean }> = {} ) { const { requestsCount, @@ -723,12 +697,12 @@ function testCLIFactory(contextReceiver) { repo.writeFile('msg.json', JSON.stringify(message)) } - const slackRequests = collectSlackRequests(slackMocker, ({ req, res, reqIndex }) => { + const slackRequests = collectSlackRequests(slackMocker, ({ body, res, reqIndex }) => { if (statusCode) { - res.status(statusCode({ req, res, reqIndex })) + res.status(statusCode({ body, res, reqIndex })) } }) - const webhookMode = env?.PVM_MATTERMOST_INCOMING_WEBHOOK + const webhookMode = !!env?.PVM_MATTERMOST_INCOMING_WEBHOOK let procStderr try { const proc = await execScript(repo, cmd, { @@ -744,7 +718,7 @@ function testCLIFactory(contextReceiver) { }, }) procStderr = proc.stderr - } catch (e) { + } catch (e: any) { procStderr = e.stderr } slackMocker.clear() @@ -763,6 +737,11 @@ function testCLIFactory(contextReceiver) { slackRequests.forEach(({ body }, i) => { const appliedTarget = Array.isArray(target) ? target[i] : target const appliedChannel = Array.isArray(channel) ? channel[i] : channel + + if (!appliedChannel) { + throw new Error('Requests more than messengers') + } + // eslint-disable-next-line jest/no-conditional-expect expect(body).toMatchObject({ ...(content !== undefined ? messageByTarget(appliedTarget, content, { webhookMode }) : {}), @@ -775,7 +754,7 @@ function testCLIFactory(contextReceiver) { } } -function messageByTarget(target, content, { webhookMode } = {}) { +function messageByTarget(target: 'mattermost' | 'slack', content: string, { webhookMode }: { webhookMode?: boolean } = {}) { switch (target) { case 'mattermost': return { @@ -795,7 +774,7 @@ function messageByTarget(target, content, { webhookMode } = {}) { } } -function channelByTarget(target, channel, { webhookMode } = {}) { +function channelByTarget(target: 'mattermost' | 'slack', channel: string, { webhookMode }: { webhookMode?: boolean } = {}) { switch (target) { case 'mattermost': return { @@ -809,7 +788,7 @@ function channelByTarget(target, channel, { webhookMode } = {}) { } } -function attachmentsByTarget(target, attachments) { +function attachmentsByTarget(target: 'mattermost' | 'slack', attachments: Message['attachments']) { switch (target) { case 'mattermost': return { diff --git a/test/scenarios/pvm-packages.spec.js b/test/scenarios/pvm-packages.spec.ts similarity index 76% rename from test/scenarios/pvm-packages.spec.js rename to test/scenarios/pvm-packages.spec.ts index 6b56c4145..2a7b01c39 100644 --- a/test/scenarios/pvm-packages.spec.js +++ b/test/scenarios/pvm-packages.spec.ts @@ -1,3 +1,6 @@ +import initRepo from '../initRepo' +import { runScript } from '../executors' + describe('pvm-packages', () => { it.concurrent('listing update should include dependants of changed packages', async () => { const repo = await initRepo('monorepo-new') @@ -15,8 +18,8 @@ describe('pvm-packages', () => { plugins_v2: [{ plugin: () => ({ providers: [ - require('${require.resolve('@pvm/di').replace(/\\/g, '/')}').provide({ - provide: require('${require.resolve('@pvm/tokens-core').replace(/\\/g, '/')}').PLATFORM_TOKEN, + require('${require.resolve('@pvm/pvm').replace(/\\/g, '/')}').provide({ + provide: require('${require.resolve('@pvm/pvm').replace(/\\/g, '/')}').PLATFORM_TOKEN, useValue: null, }), ], diff --git a/test/scenarios/pvm-pkgset.spec.js b/test/scenarios/pvm-pkgset.spec.ts similarity index 92% rename from test/scenarios/pvm-pkgset.spec.js rename to test/scenarios/pvm-pkgset.spec.ts index 009a33c1e..cbdbb93a4 100644 --- a/test/scenarios/pvm-pkgset.spec.js +++ b/test/scenarios/pvm-pkgset.spec.ts @@ -1,5 +1,10 @@ -const drainItems = require('../../packages/pvm-core/lib/iter/drain-items').default -const { pkgset } = require('../../packages/pvm-pkgset') +import { execScript } from '../executors' +import initRepo from '../initRepo' +import { writeRepo } from '../writeRepo' +import type { Config, RecursivePartial } from '@pvm/pvm' + +import { pkgset } from '@pvm/pvm/mechanics/pkgset/pkgset' +import drainItems from '../../packages/pvm/lib/iter/drain-items' describe('pvm/pkgset', () => { it('список изменившихся пакетов, плоский workspace', async () => { @@ -104,18 +109,18 @@ describe('pvm/pkgset', () => { }) describe('strategy/affected', () => { - async function testAffected(config, touched = [], output = []) { - const repo = await initRepo('mono-pkgset-affected', config.constructor === Object ? config : { + async function testAffected(config: RecursivePartial | Config['pkgset']['affected_files'], touched: string[] = [], output: string[] = []) { + const repo = await initRepo('mono-pkgset-affected', Array.isArray(config) ? { pkgset: { affected_files: config, }, - }) + } : config) for (const t of touched) { await repo.touch(t, `Change ${t}`) } - const res = await drainItems(pkgset('affected', { + const res = await drainItems(pkgset(repo.di, 'affected', { cwd: repo.dir, f: '%n', includeUncommited: true, @@ -260,7 +265,6 @@ c@0.3.0`) private: true, spec: 'src/__never-published-pkg__@0.0.1', }) - // @ts-ignore const repo = await initRepo(repoPath) const { stdout } = await repo.execScript('pvm pkgset -s stale') @@ -274,7 +278,6 @@ c@0.3.0`) private: true, spec: 'src/lodash@0.0.1', }) - // @ts-ignore const repo = await initRepo(repoPath) const { stdout } = await repo.execScript('pvm pkgset -s stale') @@ -288,7 +291,6 @@ c@0.3.0`) private: true, spec: 'src/lodash@10000.0.0', }) - // @ts-ignore const repo = await initRepo(repoPath) const { stdout } = await repo.execScript('pvm pkgset -s stale') diff --git a/test/scenarios/pvm-plugin-conventional-changelog.spec.js b/test/scenarios/pvm-plugin-conventional-changelog.spec.ts similarity index 74% rename from test/scenarios/pvm-plugin-conventional-changelog.spec.js rename to test/scenarios/pvm-plugin-conventional-changelog.spec.ts index 6f16af263..4e285412b 100644 --- a/test/scenarios/pvm-plugin-conventional-changelog.spec.js +++ b/test/scenarios/pvm-plugin-conventional-changelog.spec.ts @@ -1,18 +1,23 @@ -const { runRegistryMockServer } = require('../npm-registry-mock') +import type { NpmRegistryMock } from '../npm-registry-mock' +import { runRegistryMockServer } from '../npm-registry-mock' +import type { RepoTestApi } from '../types' +import initRepo from '../initRepo' +import { runScript } from '../executors' +import { writeRepo } from '../writeRepo' -function ccTagNotes(repo, tagName) { +function ccTagNotes(repo: RepoTestApi, tagName: string) { const notes = repo.tagNotes(tagName) return notes.split(repo.dir).join('') } -async function makeConvCommits(repo) { +async function makeConvCommits(repo: RepoTestApi) { await repo.touch('src/a/nf', `feat(pencil): add 'graphiteWidth' option`) await repo.touch('src/b/nf', `perf(pencil): remove graphiteWidth option\n\nBREAKING CHANGE: The graphiteWidth option has been removed. The default graphite width of 10mm is always used for performance reason.`) await repo.touch('src/c/nf', `fix(graphite): stop graphite breaking when width < 0.1\n\nCloses #28`) await repo.touch('src/d/nf', `feat(oil)!: support major commits via excl\n\nCloses #PVM-166`) } -async function makeNonConvCommits(repo) { +async function makeNonConvCommits(repo: RepoTestApi) { await repo.touch('src/c/nff', `set graphite width max to 0.2\n\nCloses #29`) } @@ -25,12 +30,14 @@ describe('pvm-plugin/conventional-changelog', () => { }, }, changelog: { - opts: { - 'builtin.list': { - show_date: false, - }, + renderer: { + type: 'builtin.list', + show_date: false, }, }, + plugins_v2: [{ + plugin: require.resolve('@pvm/plugin-conventional-changelog'), + }], }) await makeConvCommits(repo) await repo.linkNodeModules() @@ -53,12 +60,14 @@ describe('pvm-plugin/conventional-changelog', () => { }, }, changelog: { - opts: { - 'builtin.list': { - show_date: false, - }, + renderer: { + type: 'builtin.list', + show_date: false, }, }, + plugins_v2: [{ + plugin: require.resolve('@pvm/plugin-conventional-changelog'), + }], }) await makeConvCommits(repo) await repo.linkNodeModules() @@ -74,27 +83,26 @@ describe('pvm-plugin/conventional-changelog', () => { update: { default_release_type: 'none' }, - plugins: { + plugins_v2: [{ + plugin: "${require.resolve('@pvm/plugin-conventional-changelog').replace(/\\/g, '/')}", options: { - '@pvm/plugin-conventional-changelog': { - whatBump: (commits) => { - return commits.every(c => c.type === 'chore') ? null : 'patch' - }, + whatBump: (commits) => { + return commits.every(c => c.type === 'chore') ? null : 'patch' }, - }, - }, + } + }] }`, { configFormat: 'js' }) await repo.linkNodeModules() await repo.touch('src/a/nf', `chore: ci changes`) let updateState = await repo.getUpdateState() - let pkgA = updateState.repo.pkgset.get('a') + let pkgA = updateState.repo.pkgset.get('a')! expect(updateState.newVersions.get(pkgA)).toBe('1.0.0') expect(updateState.getReleasePackages().get(pkgA)).toBeFalsy() await repo.touch('src/a/up', `fix: version bump change`) updateState = await repo.getUpdateState() - pkgA = updateState.repo.pkgset.get('a') + pkgA = updateState.repo.pkgset.get('a')! expect(updateState.newVersions.get(pkgA)).toBe('1.0.1') expect(updateState.getReleasePackages().get(pkgA)).toBeTruthy() }, 45000) @@ -103,7 +111,13 @@ describe('pvm-plugin/conventional-changelog', () => { it('should not create release on chore: commit', async () => { const repoPath = writeRepo({ name: 'release-type-builder', spec: 'src/a@1.0.0,src/b@1.0.0' }) - const repo = await initRepo(repoPath) + const repo = await initRepo(repoPath, { + plugins_v2: [{ + plugin: require.resolve('@pvm/plugin-conventional-changelog'), + }, { + plugin: require.resolve('@pvm/plugin-conventional-semantic-release'), + }], + }) await repo.updatePkg('.', { dependencies: { '@pvm/plugin-conventional-changelog': 'not meant to be installed', @@ -120,7 +134,13 @@ describe('pvm-plugin/conventional-changelog', () => { it('should create patch release on fix: commit', async () => { const repoPath = writeRepo({ name: 'release-type-builder', spec: 'src/a@1.0.0,src/b@1.0.0' }) - const repo = await initRepo(repoPath) + const repo = await initRepo(repoPath, { + plugins_v2: [{ + plugin: require.resolve('@pvm/plugin-conventional-changelog'), + }, { + plugin: require.resolve('@pvm/plugin-conventional-semantic-release'), + }], + }) await repo.updatePkg('.', { dependencies: { '@pvm/plugin-conventional-changelog': 'not meant to be installed', @@ -142,25 +162,23 @@ describe('pvm-plugin/conventional-changelog', () => { const repoPath = writeRepo({ name: 'release-type-builder', spec: 'src/a@1.0.0,src/b@1.0.0' }) const repo = await initRepo(repoPath, { - plugins: { + plugins_v2: [{ + plugin: require.resolve('@pvm/plugin-conventional-changelog'), + }, + { + plugin: require.resolve('@pvm/plugin-conventional-semantic-release'), options: { - '@pvm/plugin-conventional-semantic-release': { - releaseRules: [ - { - type: 'fix', - release: 'major', - }, - ], - }, + releaseRules: [ + { + type: 'fix', + release: 'major', + }, + ], }, }, + ], }) - await repo.updatePkg('.', { - dependencies: { - '@pvm/plugin-conventional-changelog': 'not meant to be installed', - '@pvm/plugin-conventional-semantic-release': 'not meant to be installed', - }, - }) + await repo.linkNodeModules() await repo.touch('src/a/nf', `fix: some fix`) @@ -174,7 +192,7 @@ describe('pvm-plugin/conventional-changelog', () => { }) describe('publish', () => { - let npmControls + let npmControls: NpmRegistryMock beforeAll(async () => { npmControls = await runRegistryMockServer() }) @@ -192,6 +210,9 @@ describe('pvm-plugin/conventional-changelog', () => { versioning: { unified_versions_for: ['*'], }, + plugins_v2: [{ + plugin: require.resolve('@pvm/plugin-conventional-changelog'), + }], }) await repo.tag('v1.0.0', 'initial release') @@ -204,6 +225,7 @@ describe('pvm-plugin/conventional-changelog', () => { await runScript(repo, `pvm publish -r ${npmControls.registryUrl}`, { printStderr: true, stdio: ['pipe', 'pipe', { + // @ts-ignore write: message => { output += message }, @@ -229,12 +251,14 @@ describe('pvm-plugin/conventional-changelog', () => { }, }, changelog: { - opts: { - 'builtin.list': { - show_date: false, - }, + renderer: { + type: 'builtin.list', + show_date: false, }, }, + plugins_v2: [{ + plugin: require.resolve('@pvm/plugin-conventional-changelog'), + }], }) await makeConvCommits(repo) await repo.linkNodeModules() @@ -242,6 +266,7 @@ describe('pvm-plugin/conventional-changelog', () => { await runScript(repo, `pvm publish -r ${npmControls.registryUrl} -s stale`, { printStderr: true, stdio: ['pipe', 'pipe', { + // @ts-ignore write: message => { output += message }, diff --git a/test/scenarios/pvm-provider.spec.js b/test/scenarios/pvm-provider.spec.js deleted file mode 100644 index 6a9a6140f..000000000 --- a/test/scenarios/pvm-provider.spec.js +++ /dev/null @@ -1,16 +0,0 @@ -describe('pvm-provider', () => { - it('should load configDefaults from pvm-provider', async () => { - const repo = await initRepo('pvm-provider') - await repo.runScript('npm install') - await repo.syncConfig() - expect(repo.config.changelog.path).toEqual('changelog-provider-test.md') - }) - - it('should load plugins from pvm-provider deps', async () => { - const repo = await initRepo('pvm-provider') - await repo.runScript('npm install') - await repo.syncConfig() - const hostApi = await repo.getHostApi() - expect(hostApi.run('test.fn')).toEqual('test.fn') - }) -}) diff --git a/test/scenarios/pvm-publish.spec.js b/test/scenarios/pvm-publish.spec.ts similarity index 91% rename from test/scenarios/pvm-publish.spec.js rename to test/scenarios/pvm-publish.spec.ts index 6b623628e..3353ce6ef 100644 --- a/test/scenarios/pvm-publish.spec.js +++ b/test/scenarios/pvm-publish.spec.ts @@ -1,14 +1,23 @@ -const fs = require('fs') -const path = require('path') -const { runRegistryMockServer } = require('../npm-registry-mock') -const { runMessengerMocker } = require('../slack-mock') -const fsExtra = require('fs-extra') -const execShell = require('@pvm/core/lib/shell/exec').default - -function readStats(repo, statsName = 'publish-stats.json') { +import fs from 'fs' +import path from 'path' +import type { NpmRegistryMock } from '../npm-registry-mock' +import { runRegistryMockServer } from '../npm-registry-mock' + +import type { SlackMock } from '../slack-mock' +import { runMessengerMocker } from '../slack-mock' + +import fsExtra from 'fs-extra' +import execShell from '@pvm/pvm/lib/shell/exec' +import type { RepoTestApi } from '../types' +import { execScript, runScript } from '../executors' +import initRepo from '../initRepo' +import type { PublishedStats } from '@pvm/pvm' +import { writeRepo } from '../writeRepo' + +function readStats(repo: RepoTestApi, statsName = 'publish-stats.json'): PublishedStats { const rawStr = fs.readFileSync(path.join(repo.dir, statsName)).toString('utf8') - const body = JSON.parse(rawStr) - body.success.sort((a, b) => { + const body: any = JSON.parse(rawStr) + body.success.sort((a: any, b: any) => { if (a.pkg === b.pkg) { return 0 } @@ -18,7 +27,7 @@ function readStats(repo, statsName = 'publish-stats.json') { return -1 }) - body.success.forEach((x) => { + body.success.forEach((x: any) => { delete x.absPath delete x.manifestPath Object.keys(x).forEach(k => { @@ -31,7 +40,7 @@ function readStats(repo, statsName = 'publish-stats.json') { return body } -function readStatsAsStr(repo, statsName = 'publish-stats.json') { +function readStatsAsStr(repo: RepoTestApi, statsName = 'publish-stats.json') { return JSON.stringify(readStats(repo, statsName), null, 2) } @@ -41,6 +50,12 @@ async function nativePublish({ version, tag, registry, +}: { + repo: RepoTestApi, + pkgPath: string, + version: string, + tag: string, + registry: string, }) { await repo.updatePkg(pkgPath, { version, @@ -50,15 +65,15 @@ async function nativePublish({ } describe('pvm/publish', () => { - let npmControls - let testPublish + let npmControls: NpmRegistryMock + let testPublish: (repo: RepoTestApi, cmdArgsStr: string, env?: Record) => Promise beforeAll(async () => { npmControls = await runRegistryMockServer() testPublish = function testPublish(repo, cmdArgsStr, env) { return runScript(repo, `pvm publish -r ${npmControls.registryUrl} ${cmdArgsStr}`, { env: { ...process.env, - PVM_FORCE_TEST_PUBLISH: true, + PVM_FORCE_TEST_PUBLISH: 'true', ...env, }, }) @@ -159,7 +174,7 @@ describe('pvm/publish', () => { await testPublish(repo, ` -o publish-stats.json`) const stats = readStats(repo) - const successNames = stats.success.map(desc => desc.pkg) + const successNames = stats.success.map((desc) => desc.pkg) expect(successNames).not.toContain('foo') }) @@ -304,9 +319,9 @@ describe('pvm/publish', () => { await repo.runScript(`pvm publish --dry-run -o publish-stats.json -s all`) const pkgs = readStats(repo).success - expect(pkgs.find(p => p.pkg === 'a').publishedVersion).toBe('2.0.0') - expect(pkgs.find(p => p.pkg === 'b').publishedVersion).toBe('2.0.0') - expect(pkgs.find(p => p.pkg === 'c').publishedVersion).toBe('0.44.1') + expect(pkgs.find(p => p.pkg === 'a')?.publishedVersion).toBe('2.0.0') + expect(pkgs.find(p => p.pkg === 'b')?.publishedVersion).toBe('2.0.0') + expect(pkgs.find(p => p.pkg === 'c')?.publishedVersion).toBe('0.44.1') }) it('publish command should fail if some packages failed to publish', async () => { @@ -336,7 +351,7 @@ describe('pvm/publish', () => { }) describe('canary', () => { - let slackMocker + let slackMocker: SlackMock beforeAll(async () => { slackMocker = await runMessengerMocker() }) @@ -449,17 +464,16 @@ describe('pvm/publish', () => { }) it('should pass canary:$release info and commits from first commit to current HEAD to slack message', async () => { - const slackRequestsBody = [] + const slackRequestsBody: Array> = [] slackMocker.spy((req) => { slackRequestsBody.push(req.body) }) const repo = await initRepo('simple-one', { - notifications: { - clients: [{ - name: 'slack', - pkg: '@pvm/slack', - }], - }, + plugins_v2: [ + { + plugin: require.resolve('@pvm/plugin-slack'), + }, + ], }) await testPublish(repo, `-s all --canary --notify --message-channel test`, { ...process.env, @@ -483,17 +497,16 @@ describe('pvm/publish', () => { }) it('should pass release name along with canary prefix in notification message', async () => { - const slackRequestsBody = [] + const slackRequestsBody: Array> = [] slackMocker.spy((req) => { slackRequestsBody.push(req.body) }) const repo = await initRepo('simple-one', { - notifications: { - clients: [{ - name: 'slack', - pkg: '@pvm/slack', - }], - }, + plugins_v2: [ + { + plugin: require.resolve('@pvm/plugin-slack'), + }, + ], }) await repo.touch('modification_1.txt', 'modification_1') @@ -522,17 +535,16 @@ describe('pvm/publish', () => { }) it('should pass messageChannel to message from flags', async () => { - const slackRequestsBody = [] + const slackRequestsBody: Array> = [] slackMocker.spy((req) => { slackRequestsBody.push(req.body) }) const repo = await initRepo('simple-one', { - notifications: { - clients: [{ - name: 'slack', - pkg: '@pvm/slack', - }], - }, + plugins_v2: [ + { + plugin: require.resolve('@pvm/plugin-slack'), + }, + ], }) await testPublish(repo, `--canary --message-channel test-channel`, { @@ -547,17 +559,16 @@ describe('pvm/publish', () => { }) it('should send error notification to messageChannel if publication failed', async () => { - const slackRequestsBody = [] + const slackRequestsBody: Array> = [] slackMocker.spy((req) => { slackRequestsBody.push(req.body) }) const repo = await initRepo('simple-one', { - notifications: { - clients: [{ - name: 'slack', - pkg: '@pvm/slack', - }], - }, + plugins_v2: [ + { + plugin: require.resolve('@pvm/plugin-slack'), + }, + ], }) await expect(testPublish(repo, `-r invalid-reg --canary --message-channel test-channel`, { @@ -570,17 +581,16 @@ describe('pvm/publish', () => { }) it('should send error notification to messageChannel if publication partially failed', async () => { - const slackRequestsBody = [] + const slackRequestsBody: Array> = [] slackMocker.spy((req) => { slackRequestsBody.push(req.body) }) const repo = await initRepo('monorepo-new', { - notifications: { - clients: [{ - name: 'slack', - pkg: '@pvm/slack', - }], - }, + plugins_v2: [ + { + plugin: require.resolve('@pvm/plugin-slack'), + }, + ], }) repo.updatePkg('src/a', { diff --git a/test/scenarios/pvm-releases.spec.js b/test/scenarios/pvm-releases.spec.ts similarity index 97% rename from test/scenarios/pvm-releases.spec.js rename to test/scenarios/pvm-releases.spec.ts index 832f7aafd..c80ca821e 100644 --- a/test/scenarios/pvm-releases.spec.js +++ b/test/scenarios/pvm-releases.spec.ts @@ -1,3 +1,4 @@ +import initRepo from '../initRepo' describe('releases', () => { it('should generate ReleaseList artifact from scratch', async () => { diff --git a/test/scenarios/pvm-rewrite-notes.spec.js b/test/scenarios/pvm-rewrite-notes.spec.ts similarity index 69% rename from test/scenarios/pvm-rewrite-notes.spec.js rename to test/scenarios/pvm-rewrite-notes.spec.ts index 281ecbbe9..70c1d8160 100644 --- a/test/scenarios/pvm-rewrite-notes.spec.js +++ b/test/scenarios/pvm-rewrite-notes.spec.ts @@ -1,3 +1,5 @@ +import initRepo from '../initRepo' + describe('pvm/rewrite-notes', () => { it('should rewrite notes', async () => { const repo = await initRepo('monorepo-new') @@ -8,7 +10,7 @@ describe('pvm/rewrite-notes', () => { await repo.runScript('pvm rewrite-notes') - expect(() => repo.tagNotes('release-one', 'change a')).not.toThrow() - expect(() => repo.tagNotes('release-two', 'change b')).not.toThrow() + expect(() => repo.tagNotes('release-one')).not.toThrow() + expect(() => repo.tagNotes('release-two')).not.toThrow() }) }) diff --git a/test/scenarios/pvm-set-versions.spec.js b/test/scenarios/pvm-set-versions.spec.ts similarity index 92% rename from test/scenarios/pvm-set-versions.spec.js rename to test/scenarios/pvm-set-versions.spec.ts index 4f7d54399..8c519396e 100644 --- a/test/scenarios/pvm-set-versions.spec.js +++ b/test/scenarios/pvm-set-versions.spec.ts @@ -1,3 +1,6 @@ +import { runScript } from '../executors' +import initRepo from '../initRepo' +import { writeRepo } from '../writeRepo' describe('pvm/set-versions', () => { it('подъем версий по маске', async () => { diff --git a/test/scenarios/pvm-show.spec.js b/test/scenarios/pvm-show.spec.ts similarity index 94% rename from test/scenarios/pvm-show.spec.js rename to test/scenarios/pvm-show.spec.ts index 638486405..3d4d484d5 100644 --- a/test/scenarios/pvm-show.spec.js +++ b/test/scenarios/pvm-show.spec.ts @@ -1,3 +1,5 @@ +import initRepo from '../initRepo' + describe('pvm-show', () => { it.concurrent('pvm show release-commits should work without releases', async () => { const repo = await initRepo('monorepo-new') diff --git a/test/scenarios/pvm-sync-tag.spec.js b/test/scenarios/pvm-sync-tag.spec.ts similarity index 100% rename from test/scenarios/pvm-sync-tag.spec.js rename to test/scenarios/pvm-sync-tag.spec.ts diff --git a/test/scenarios/pvm-test-self-check.spec.js b/test/scenarios/pvm-test-self-check.spec.ts similarity index 95% rename from test/scenarios/pvm-test-self-check.spec.js rename to test/scenarios/pvm-test-self-check.spec.ts index b84e770b8..da01295d6 100644 --- a/test/scenarios/pvm-test-self-check.spec.js +++ b/test/scenarios/pvm-test-self-check.spec.ts @@ -1,3 +1,5 @@ +import initRepo from '../initRepo' + describe('pvm-test-self-check', () => { // Отключен self-check локально т.к. не хочу трогать глобально настроенного пользователя if (process.env.CI) { diff --git a/test/scenarios/pvm-upconf.spec.js b/test/scenarios/pvm-upconf.spec.ts similarity index 93% rename from test/scenarios/pvm-upconf.spec.js rename to test/scenarios/pvm-upconf.spec.ts index 41e2bc4e9..707439b7a 100644 --- a/test/scenarios/pvm-upconf.spec.js +++ b/test/scenarios/pvm-upconf.spec.ts @@ -1,3 +1,6 @@ +import { writeRepo } from '../writeRepo' +import initRepo from '../initRepo' + describe.skip('pvm-upconf', () => { it('should migrate versioning from file-based to unified-one', async () => { const repoPath = writeRepo({ name: 'upconf-file-tag', spec: 'src/a@0.0.0-stub,src/b@0.0.0-stub,src/c@0.0.0-stub' }) diff --git a/test/scenarios/pvm-update.spec.js b/test/scenarios/pvm-update.spec.ts similarity index 93% rename from test/scenarios/pvm-update.spec.js rename to test/scenarios/pvm-update.spec.ts index 384896616..526dbe292 100644 --- a/test/scenarios/pvm-update.spec.js +++ b/test/scenarios/pvm-update.spec.ts @@ -1,15 +1,20 @@ -const dedent = require('dedent') -const semver = require('semver') -const { deepMerge } = require('sprout-data') - -const { UpdateReasonType } = require('@pvm/update/lib/update-state') - -const revParse = require('@pvm/core/lib/git/rev-parse').default -const path = require('path') -const { reposDir } = require('../repos-dir') -const runShell = require('../../packages/pvm-core/lib/shell/run').default -const { execScript } = require('../executors') -const got = require('got') +// @ts-ignore +import dedent from 'dedent' +import semver from 'semver' +import { deepMerge } from 'sprout-data' +import { UpdateReasonType } from '@pvm/pvm/mechanics/update/update-state' +import revParse from '@pvm/pvm/lib/git/rev-parse' +import path from 'path' +import { reposDir } from '../repos-dir' +import runShell from '../../packages/pvm/lib/shell/run' +import { execScript, runScript } from '../executors' + +import got from 'got' +import initRepo from '../initRepo' +import { writeConfig } from '../helpers' +import { writeRepo } from '../writeRepo' +import type { ReleaseData } from '@pvm/pvm/mechanics/releases/types' +import type { RepoTestApi } from '../types' const doTagsPlease = { tagging: { @@ -417,14 +422,14 @@ describe('pvm/update', () => { await repo.touch('src/b/nf', 'change nf') await repo.runScript('pvm update') expect(repo.existsPath('releaseList.json')).toBeTruthy() - const releaseList = JSON.parse(repo.readFile('releaseList.json')) + const releaseList = JSON.parse(repo.readFile('releaseList.json')) as ReleaseData[] expect(releaseList).toHaveLength(1) expect(releaseList[0].packages).toHaveLength(2) const forcedPackage = releaseList[0].packages.find(pkg => pkg.name === 'a') expect(forcedPackage).toBeDefined() - expect(forcedPackage.updateReason).toEqual('always_changed') + expect(forcedPackage?.updateReason).toEqual('always_changed') }) it.concurrent('update reason for force released package', async () => { @@ -448,14 +453,14 @@ describe('pvm/update', () => { ) await repo.runScript('pvm update') expect(repo.existsPath('releaseList.json')).toBeTruthy() - const releaseList = JSON.parse(repo.readFile('releaseList.json')) + const releaseList = JSON.parse(repo.readFile('releaseList.json')) as ReleaseData[] expect(releaseList).toHaveLength(1) expect(releaseList[0].packages).toHaveLength(2) const forcedPackage = releaseList[0].packages.find(pkg => pkg.name === 'a') expect(forcedPackage).toBeDefined() - expect(forcedPackage.updateReason).toEqual('hints') + expect(forcedPackage?.updateReason).toEqual('hints') }) it.concurrent('versioning.source = file should work', async () => { @@ -579,7 +584,7 @@ describe('pvm/update', () => { update: { dependants_release_type: 'minor', }, - }, doTagsPlease)) + } as const, doTagsPlease)) await repo.touch('src/{c,d}/nf', 'update c and d') await repo.runScript('pvm update') @@ -648,7 +653,7 @@ describe('pvm/update', () => { await repo.touch('src/c/nf', `feat: minor up`) const { newVersions, repo: innerRepo } = await repo.getUpdateState() - expect(newVersions.get(innerRepo.pkgset.get('a'))).toBe('0.1.1') + expect(newVersions.get(innerRepo.pkgset.get('a')!)).toBe('0.1.1') }) it('обновление депендантов на преминор не должно ломать yarn install', async () => { @@ -680,8 +685,8 @@ describe('pvm/update', () => { await repo.touch('pkg/a/change.txt', 'release trigger') await repo.touch('pkg/d/change.txt', 'release trigger') - const pkgC = await repo.loadPkg('pkg/c', 'HEAD') - const pkgB = await repo.loadPkg('pkg/b', 'HEAD') + const pkgC = await repo.loadPkg('pkg/c', 'HEAD')! + const pkgB = await repo.loadPkg('pkg/b', 'HEAD')! const updateState = await repo.getUpdateState() expect(updateState.updateReasonMap.get(pkgB)).toBe('dependant') @@ -712,8 +717,8 @@ describe('pvm/update', () => { await repo.touch('pkg/a/change.txt', 'release trigger') await repo.touch('pkg/d/change.txt', 'release trigger') - const pkgC = await repo.loadPkg('pkg/c', 'HEAD') - const pkgB = await repo.loadPkg('pkg/b', 'HEAD') + const pkgC = await repo.loadPkg('pkg/c', 'HEAD')! + const pkgB = await repo.loadPkg('pkg/b', 'HEAD')! const updateState = await repo.getUpdateState() expect(updateState.newVersions.get(pkgB)).toBe('3.0.0') @@ -739,7 +744,7 @@ describe('pvm/update', () => { await repo.commitAll('update hints, change a and e') await repo.runScript('pvm update') - const cDep = repo.readPkg('src/b').dependencies.c + const cDep = repo.readPkg('src/b').dependencies?.c expect(cDep).toEqual('1.3.0') }) @@ -991,7 +996,7 @@ describe('pvm/update', () => { }) const aVersion = repo.pkgVersion('src/a') - const bVersion = repo.pkgVersion('src/b') + const bVersion = repo.pkgVersion('src/b')! await repo.touch(['src/a/__tests__/*.md', 'src/b/foo.md'], 'update a') await repo.runScript('pvm update') expect(repo.pkgVersion('src/a')).toEqual(aVersion) @@ -1010,7 +1015,9 @@ describe('pvm/update', () => { }, release: { tag_only: true, - disable_changelog: false, + }, + changelog: { + enabled: false, }, }) @@ -1178,7 +1185,6 @@ make "d"`) const repo = await initRepo(repoPath, { versioning: { source: 'tag', - per_package: false, unified_versions_for: ['*'], }, }) @@ -1192,7 +1198,6 @@ make "d"`) const repo = await initRepo(repoPath, { versioning: { source: 'tag', - per_package: false, unified_versions_for: ['*'], }, }) @@ -1271,7 +1276,7 @@ make "d"`) const lastReleaseTag = repo.lastReleaseTag() expect(lastReleaseTag).toEqual('v0.45.0') - expect((await repo.loadPkg('src/new')).version).toEqual('0.45.0') + expect((await repo.loadPkg('src/new'))?.version).toEqual('0.45.0') }) it.concurrent('new package in SUG', async () => { @@ -1298,8 +1303,8 @@ make "d"`) const lastReleaseTag = repo.lastReleaseTag() expect(lastReleaseTag).toEqual('v2.0.0#Silver-Fox') - expect((await repo.loadPkg('src/new')).version).toEqual('0.45.0') - expect((await repo.loadPkg('src/b')).version).toEqual('0.45.0') + expect((await repo.loadPkg('src/new'))?.version).toEqual('0.45.0') + expect((await repo.loadPkg('src/b'))?.version).toEqual('0.45.0') }) it.concurrent('SUG with release_tag_package', async () => { @@ -1307,6 +1312,8 @@ make "d"`) versioning: { unified: true, source: 'tag', + }, + tagging: { release_tag_package: 'c', }, update: { @@ -1326,9 +1333,9 @@ c@0.1.0`) const lastReleaseTag = repo.lastReleaseTag() expect(lastReleaseTag).toEqual('v0.2.0') - expect((await repo.loadPkg('src/a')).version).toEqual('0.2.0') - expect((await repo.loadPkg('src/b')).version).toEqual('0.2.0') - expect((await repo.loadPkg('src/c')).version).toEqual('0.2.0') + expect((await repo.loadPkg('src/a'))?.version).toEqual('0.2.0') + expect((await repo.loadPkg('src/b'))?.version).toEqual('0.2.0') + expect((await repo.loadPkg('src/c'))?.version).toEqual('0.2.0') }) it.concurrent('move pkg from SUG to MUG', async () => { @@ -1357,8 +1364,8 @@ c@0.1.0`) const lastReleaseTag = repo.lastReleaseTag() expect(lastReleaseTag).toEqual('v0.45.0') - expect((await repo.loadPkg('src/c')).version).toEqual('0.45.0') - expect((await repo.loadPkg('src/d')).version).toEqual('2.1.1') + expect((await repo.loadPkg('src/c'))?.version).toEqual('0.45.0') + expect((await repo.loadPkg('src/d'))?.version).toEqual('2.1.1') }) it.concurrent('move package from MUG to SUG', async () => { @@ -1387,9 +1394,9 @@ c@0.1.0`) const lastReleaseTag = repo.lastReleaseTag() expect(lastReleaseTag).toEqual(expect.stringMatching(/^v2.1.1/)) - expect((await repo.loadPkg('src/a')).version).toEqual('2.1.1') - expect((await repo.loadPkg('src/b')).version).toEqual('0.45.0') - expect((await repo.loadPkg('src/d')).version).toEqual('0.45.0') + expect((await repo.loadPkg('src/a'))?.version).toEqual('2.1.1') + expect((await repo.loadPkg('src/b'))?.version).toEqual('0.45.0') + expect((await repo.loadPkg('src/d'))?.version).toEqual('0.45.0') }) // на данный момент кейс не поддерживается @@ -1419,9 +1426,9 @@ c@0.1.0`) const lastReleaseTag = repo.lastReleaseTag() expect(lastReleaseTag).toEqual(expect.stringMatching(/^v10.20.30/)) - expect((await repo.loadPkg('src/b')).version).toEqual('2.1.1') - expect((await repo.loadPkg('src/c')).version).toEqual('0.45.0') - expect((await repo.loadPkg('src/d')).version).toEqual('0.45.0') + expect((await repo.loadPkg('src/b'))?.version).toEqual('2.1.1') + expect((await repo.loadPkg('src/c'))?.version).toEqual('0.45.0') + expect((await repo.loadPkg('src/d'))?.version).toEqual('0.45.0') }) it.concurrent('packages from SUG should have own versioning', async () => { @@ -1450,9 +1457,9 @@ c@0.1.0`) const lastReleaseTag = repo.lastReleaseTag() expect(lastReleaseTag).toEqual(expect.stringMatching(/^v2\.0\.0#.*/)) expect(repo.getTagAnnotation(lastReleaseTag)).toEqual(expect.stringMatching(/.*\n---\nb@0.45.0\nc@0.45.0\s*$/)) - expect((await repo.loadPkg('src/a')).version).toEqual('2.0.0') - expect((await repo.loadPkg('src/b')).version).toEqual('0.45.0') - expect((await repo.loadPkg('src/c')).version).toEqual('0.45.0') + expect((await repo.loadPkg('src/a'))?.version).toEqual('2.0.0') + expect((await repo.loadPkg('src/b'))?.version).toEqual('0.45.0') + expect((await repo.loadPkg('src/c'))?.version).toEqual('0.45.0') }) it('independent packages should have own versioning', async () => { @@ -1481,9 +1488,9 @@ c@0.1.0`) const lastReleaseTag = repo.lastReleaseTag() expect(lastReleaseTag).toEqual(expect.stringMatching(/^v2\.0\.0#.*/)) expect(repo.getTagAnnotation(lastReleaseTag)).toEqual(expect.stringMatching(/.*\n---\nb@0.1.0\nc@0.0.1\s*$/)) - expect((await repo.loadPkg('src/a')).version).toEqual('2.0.0') - expect((await repo.loadPkg('src/b')).version).toEqual('0.1.0') - expect((await repo.loadPkg('src/c')).version).toEqual('0.0.1') + expect((await repo.loadPkg('src/a'))?.version).toEqual('2.0.0') + expect((await repo.loadPkg('src/b'))?.version).toEqual('0.1.0') + expect((await repo.loadPkg('src/c'))?.version).toEqual('0.0.1') }) it.concurrent('should take root pkg name for release annotation', async () => { @@ -1510,7 +1517,7 @@ c@0.1.0`) expect(repo.pkgVersion('src/c')).toEqual('1.0.0') const lastReleaseTag = repo.lastReleaseTag() - expect(repo.getTagAnnotation(lastReleaseTag)).toEqual(expect.stringMatching(new RegExp(`^${(await repo.loadPkg('.')).name}`))) + expect(repo.getTagAnnotation(lastReleaseTag)).toEqual(expect.stringMatching(new RegExp(`^${(await repo.loadPkg('.'))?.name}`))) }) it.concurrent('should take unified packages by pattern', async () => { @@ -1542,13 +1549,13 @@ c@0.1.0`) await repo.touch('main/tool/nf', 'touch main tool') await repo.runScript('pvm update') - expect((await repo.loadPkg('src/a')).version).toEqual('2.0.0') - expect((await repo.loadPkg('src/b')).version).toEqual('2.0.0') + expect((await repo.loadPkg('src/a'))?.version).toEqual('2.0.0') + expect((await repo.loadPkg('src/b'))?.version).toEqual('2.0.0') // independent_packages > unified - expect((await repo.loadPkg('src/c')).version).toEqual('0.44.1') + expect((await repo.loadPkg('src/c'))?.version).toEqual('0.44.1') // unified_versions_for > unified - expect((await repo.loadPkg('main/tool')).version).toEqual('0.6.0') - expect((await repo.loadPkg('tools/x')).version).toEqual('0.6.0') + expect((await repo.loadPkg('main/tool'))?.version).toEqual('0.6.0') + expect((await repo.loadPkg('tools/x'))?.version).toEqual('0.6.0') }) it.concurrent('should bump minor when breaking change and respect_zero_major_version applied', async () => { @@ -1561,8 +1568,14 @@ c@0.1.0`) autolint: false, respect_zero_major_version: true, }, + plugins_v2: [ + { + plugin: '@pvm/plugin-conventional-changelog', + }, + ], + }, { + linkNodeModules: true, }) - await repo.linkNodeModules() await repo.tag('v0.1.0', `release --- @@ -1577,8 +1590,8 @@ BREAKING CHANGE: do minor `) const { newVersions, repo: innerRepo } = await repo.getUpdateState() - const pkgA = innerRepo.pkgset.get('a') - expect(newVersions.get(pkgA)).toBe('0.2.0') + const pkgA = innerRepo.pkgset.get('a')! + expect(newVersions.get(pkgA))?.toBe('0.2.0') }) }) @@ -1612,7 +1625,7 @@ BREAKING CHANGE: do minor const newPkg = repo.readPkg('src/new') expect(newPkg.version).toEqual('10.1.0') - expect(newPkg.dependencies.a).toEqual('10.1.0') + expect(newPkg.dependencies?.a).toEqual('10.1.0') expect(repo.pkgVersion('src/a')).toEqual('10.1.0') }) @@ -1632,15 +1645,15 @@ BREAKING CHANGE: do minor const bPkg = repo.readPkg('src/b') expect(bPkg.version).toEqual('10.2.0') - expect(bPkg.dependencies.a).toEqual('10.2.0') + expect(bPkg.dependencies?.a).toEqual('10.2.0') }) it.concurrent('should correct handle multiple unified groups with dependencies between', async () => { const repo = await initRepo('ugroups', { versioning: { unified_versions_for: [ - '/src/*', - '@utils/*', + ['/src/*'], + ['@utils/*'], ], }, }) @@ -1673,7 +1686,6 @@ BREAKING CHANGE: do minor }) it(`unversioned package should not affect baseline version`, async () => { - // @ts-ignore const repo = await initRepo('dedicated') // проверяем что все версии меньше 0 const versions = JSON.parse(repo.readFile('versions.json')) @@ -1938,7 +1950,7 @@ BREAKING CHANGE: do minor }) describe('packages rename when unified grouping enabled', () => { - async function commonChangePreparation(repo) { + async function commonChangePreparation(repo: RepoTestApi) { await repo.writeFile('src/a/package.json', JSON.stringify({ 'name': '@namespace/a', 'version': '0.0.0-stub', @@ -1989,8 +2001,8 @@ c@0.1.1 await commonChangePreparation(repo) const { newVersions, wantedReleaseTypes, repo: innerRepo, updateReasonMap } = await repo.getUpdateState() - const pkgA = innerRepo.pkgset.get('@namespace/a') - const pkgB = innerRepo.pkgset.get('@namespace/b') + const pkgA = innerRepo.pkgset.get('@namespace/a')! + const pkgB = innerRepo.pkgset.get('@namespace/b')! expect(newVersions.get(pkgA)).toBe('0.0.1') expect(newVersions.get(pkgB)).toBe('0.0.1') expect(wantedReleaseTypes.has(pkgA)).toBeTruthy() @@ -2036,8 +2048,8 @@ c@0.1.1 await commonChangePreparation(repo) const { newVersions, wantedReleaseTypes, repo: innerRepo, updateReasonMap } = await repo.getUpdateState() - const pkgA = innerRepo.pkgset.get('@namespace/a') - const pkgB = innerRepo.pkgset.get('@namespace/b') + const pkgA = innerRepo.pkgset.get('@namespace/a')! + const pkgB = innerRepo.pkgset.get('@namespace/b')! expect(newVersions.get(pkgA)).toBe('0.1.1') expect(newVersions.get(pkgB)).toBe('0.1.1') expect(wantedReleaseTypes.has(pkgA)).toBeTruthy() @@ -2049,7 +2061,7 @@ c@0.1.1 describe('update hints in merge request', () => { afterEach(() => { - process.env.CI_PROJECT_ID = 111 + process.env.CI_PROJECT_ID = '111' }) it('update hints should be used', async () => { @@ -2075,7 +2087,7 @@ major = '*' process.env.CI_PROJECT_ID = 'WITHOUT_MR' const { newVersions, repo: innerRepo } = await repo.getUpdateState() - const pkg = innerRepo.pkgset.get('simple-one') + const pkg = innerRepo.pkgset.get('simple-one')! expect(newVersions.get(pkg)).toBe('1.0.0') }) }) diff --git a/test/scenarios/pvm-vcs.spec.js b/test/scenarios/pvm-vcs.spec.ts similarity index 85% rename from test/scenarios/pvm-vcs.spec.js rename to test/scenarios/pvm-vcs.spec.ts index e5940c5cb..8aeb43ac3 100644 --- a/test/scenarios/pvm-vcs.spec.js +++ b/test/scenarios/pvm-vcs.spec.ts @@ -1,3 +1,6 @@ +import initRepo from '../initRepo' +import { runScript } from '../executors' + describe('pvm/vcs', () => { it('pvm-vcs is-branch-actual should exit with code 0 if branch is actual', async () => { const repo = await initRepo('mono-empty') diff --git a/test/scenarios/pvm-viz.spec.js b/test/scenarios/pvm-viz.spec.ts similarity index 80% rename from test/scenarios/pvm-viz.spec.js rename to test/scenarios/pvm-viz.spec.ts index 1adccda76..62f0991e0 100644 --- a/test/scenarios/pvm-viz.spec.js +++ b/test/scenarios/pvm-viz.spec.ts @@ -1,3 +1,5 @@ +import initRepo from '../initRepo' +import { runScript } from '../executors' describe('pvm/viz', () => { it('должен рисовать граф для зависимостей с ^', async () => { @@ -6,6 +8,5 @@ describe('pvm/viz', () => { await repo.touch(['src/b/nf', 'src/a/nf'], 'update packages') await runScript(repo, 'pvm update -p dot > update-diff.dot') - await runScript(repo, 'pvm viz update-diff.dot > update-diff.svg') }) }) diff --git a/test/slack-mock/index.js b/test/slack-mock/index.ts similarity index 67% rename from test/slack-mock/index.js rename to test/slack-mock/index.ts index 53aa4f27f..12022ec07 100644 --- a/test/slack-mock/index.js +++ b/test/slack-mock/index.ts @@ -1,10 +1,11 @@ -const express = require('express') +import type { Request, Response } from 'express' +import express from 'express' const MESSENGER_MOCK_PORT_BASE = 4356 -const occupiedPorts = [] +const occupiedPorts: number[] = [] function findFreePort() { - let port = MESSENGER_MOCK_PORT_BASE + let port: number = MESSENGER_MOCK_PORT_BASE // eslint-disable-next-line no-empty while (occupiedPorts.indexOf(port) !== -1) { port++ @@ -12,9 +13,16 @@ function findFreePort() { return port } -module.exports.runMessengerMocker = async function runMessengerMocker() { - return new Promise((resolve, reject) => { - let spies = [] +export type SlackMock = { + mockerUrl: string, + spy(spyHandler: (req: Request, res: Response) => void): (() => void), + stop(): Promise, + clear: () => void, +} + +export async function runMessengerMocker() { + return new Promise((resolve, reject) => { + let spies: Array<(req: Request, res: Response) => void> = [] const port = findFreePort() occupiedPorts.push(port) @@ -30,14 +38,14 @@ module.exports.runMessengerMocker = async function runMessengerMocker() { console.log('messenger mock server listening on', port) resolve({ mockerUrl: `http://localhost:${port}`, - spy(spyHandler) { + spy(spyHandler: (req: Request, res: Response) => void) { spies.push(spyHandler) return () => { spies.splice(spies.indexOf(spyHandler), 1) } }, stop: () => { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { server.close((err) => { if (err) { reject(err) @@ -53,7 +61,7 @@ module.exports.runMessengerMocker = async function runMessengerMocker() { }, }) }) - .on('error', (err) => { + .on('error', (err: any) => { if (err.code === 'EADDRINUSE') { runMessengerMocker() .then(resolve, reject) diff --git a/test/types.ts b/test/types.ts new file mode 100644 index 000000000..b95de5978 --- /dev/null +++ b/test/types.ts @@ -0,0 +1,103 @@ +import type { + Config, + Container, ExecShellOptions, + HostApi, + PkgMeta, + RecursivePartial, RunShellOptions, +} from '@pvm/pvm' +import type { Pkg } from '@pvm/pvm/lib/pkg' +import type { ExecSyncOptions } from 'child_process' +import type { UpdateState } from '@pvm/pvm/mechanics/update/update-state' +import type { ExecResult } from '../packages/pvm/lib/shell/exec' +import type { User } from './fixtures/users' + +export interface RepoTestApi { + dir: string, + cwd: string, + // todo: remove if not used + data: any, + config: Config, + di: Container, + env: { + CI_PROJECT_ID: string, + CI_COMMIT_SHA: string, + CI_COMMIT_REF_NAME: string, + }, + head: string, + shell(cmd: string, opts?: ExecSyncOptions): string, + updateConfig(config: RecursivePartial): Promise, + syncConfig(): Promise, + getHostApi(): HostApi, + approvers(pickAttr?: keyof User): Array | Array, + setApprovers(usernames: string[]): void + lastReleaseTag(): string, + getUpdateState(): Promise, + readPkg(pkgPath: string): PkgMeta, + updatePkg(pkgPath: string, patch: RecursivePartial): void, + pkgVersion(pkgPath: string): string | undefined, + tags(ref?: string): string[], + pkgTags(ref?: string): string[], + pkgTagsAll(): string[], + runScript(cmd: string, opts?: RunShellOptions): Promise, + execScript(cmd: string, opts?: ExecShellOptions): Promise, + mkdir(dir: string): void, + glApiStats(resourceId: string): Promise> + addPkg(pkgPath: string, pkg: PkgMeta): Promise, + writeFile(filepath: string, contents: string, commit?: string): Promise, + rm(path: string): Promise, + touch(filepaths: string[] | string, commitMessage?: string): Promise, + tag(tagName: string, notes?: string): Promise, + annotatedTag(tagName: string, annotation: string, ref?: string): Promise, + loadPkg(pkgPath: string, ref?: string): Pkg | null, + linkNodeModules(): Promise, + commit(message: string): Promise, + commitAll(message: string): Promise, + lastReleaseNotes(): string, + tagNotes(tagName: string): string, + getTagAnnotation(tagName: string): string, + readFile(relPath: string, encoding?: 'utf8' | 'ascii' | 'hex'): string, + existsPath(relPath: string): boolean, +} + +export type PkgDir = string +export type PkgName = string +export type PkgPath = `${PkgDir}/${PkgName}` +export type PkgVersion = string +export type PkgSpec = `${PkgPath}@${PkgVersion}` + +export type RepoSpec = { + name: string, + version?: PkgVersion, + spec: `${PkgSpec}` | `${PkgSpec},${PkgSpec}` | `${PkgSpec},${PkgSpec},${PkgSpec}` | `${PkgSpec},${PkgSpec},${PkgSpec},${PkgSpec}` | PkgSpec[], + deps?: Record + private?: boolean +} + +export type RepoPkg = { + name: PkgName, + path: `${PkgDir}/${PkgName}`, + version: PkgVersion, + dependencies?: Record +} + +export type Repo = { + packages: Map, + name: PkgName, + version?: PkgVersion, + workspaces: Set, + private?: boolean +} + +export type GitlabCommit = { + id: string, + short_id: string, + title: string, + created_at: string, + message: string, + author_name: string, + author_email: string, + author_date: string, + committer_name: string, + committer_email: string, + committer_date: string, +} diff --git a/test/writeRepo.js b/test/writeRepo.ts similarity index 67% rename from test/writeRepo.js rename to test/writeRepo.ts index fe42ffd23..0918e2789 100644 --- a/test/writeRepo.js +++ b/test/writeRepo.ts @@ -1,11 +1,13 @@ // make repository by text spec -const fs = require('fs') -const path = require('path') -const { reposDir } = require('./repos-dir') +import fs from 'fs' +import path from 'path' +// @ts-ignore +import { reposDir } from './repos-dir' +import type { PkgPath, PkgSpec, PkgVersion, Repo, RepoPkg, RepoSpec } from './types' // makeRepo('any_name', 'src/a@1.0.0,src/b@1.0.0', { b: 'a'}) -function splitPkgPath(pkgPath) { +function splitPkgPath(pkgPath: string): [string, string] { const firstIndexOfSlash = pkgPath.indexOf('/') return [ pkgPath.substring(0, firstIndexOfSlash), @@ -13,20 +15,20 @@ function splitPkgPath(pkgPath) { ] } -function parseSpec({ name, version, spec, deps = {} }) { - const rep = { +function parseSpec({ name, version, spec, deps = {} }: RepoSpec): Repo { + const rep: Repo = { packages: new Map(), name, version, + workspaces: new Set(), } - const packagesSpec = Array.isArray(spec) ? spec : spec.split(',') + const packagesSpec = (Array.isArray(spec) ? spec : spec.split(',')) as PkgSpec[] for (const pkgSpec of packagesSpec) { - const [pkgPath, version] = pkgSpec.split('@') + const [pkgPath, version] = pkgSpec.split('@') as [PkgPath, PkgVersion] const [pkgDir, pkgName] = splitPkgPath(pkgPath) - rep.workspaces = rep.workspaces || new Set() rep.workspaces.add(`${pkgDir}/*`) - const pkg = { + const pkg: RepoPkg = { name: pkgName, path: pkgPath, version, @@ -38,16 +40,16 @@ function parseSpec({ name, version, spec, deps = {} }) { if (!rep.packages.has(pkgName)) { throw new Error(`Invalided repo deps spec, there is no ${pkgName} package`) } - const pkg = rep.packages.get(pkgName) + const pkg = rep.packages.get(pkgName)! const deps = typeof depSpec === 'string' ? [depSpec] : depSpec - const dependencies = {} + const dependencies: RepoPkg['dependencies'] = {} for (const depName of deps) { if (!rep.packages.has(depName)) { throw new Error(`Invalided repo deps spec, there is no ${depName} package`) } - dependencies[depName] = rep.packages.get(depName).version + dependencies[depName] = rep.packages.get(depName)!.version } pkg.dependencies = dependencies @@ -56,7 +58,7 @@ function parseSpec({ name, version, spec, deps = {} }) { return rep } -function rootPkgTemplate(rep) { +function rootPkgTemplate(rep: Repo) { return JSON.stringify({ name: rep.name, version: rep.version, @@ -65,7 +67,7 @@ function rootPkgTemplate(rep) { }, null, 2) } -function pkgTemplate(pkg) { +function pkgTemplate(pkg: RepoPkg) { const json = { name: pkg.name, version: pkg.version, @@ -75,13 +77,13 @@ function pkgTemplate(pkg) { return JSON.stringify(json, null, 2) } -function mkdirp(dir) { +function mkdirp(dir: string) { fs.mkdirSync(dir, { recursive: true, }) } -function makeRepoByStructure(targetDir, rep) { +function makeRepoByStructure(targetDir: string, rep: Repo) { fs.writeFileSync(path.join(targetDir, 'package.json'), rootPkgTemplate(rep)) for (const pkg of rep.packages.values()) { mkdirp(path.join(targetDir, pkg.path)) @@ -89,7 +91,7 @@ function makeRepoByStructure(targetDir, rep) { } } -function takeDirAndMakeRepo(commonDir, rep) { +function takeDirAndMakeRepo(commonDir: string, rep: Repo): string { const baseName = rep.name let name = baseName let repoDir = `${commonDir}/${name}` @@ -102,8 +104,8 @@ function takeDirAndMakeRepo(commonDir, rep) { fs.mkdirSync(repoDir, { recursive: true, }) - } catch (e) { - if (e.code === 'EEXIST') { + } catch (e: unknown) { + if ((e as { code?: string }).code === 'EEXIST') { return takeDirAndMakeRepo(baseName, rep) } throw e @@ -113,9 +115,7 @@ function takeDirAndMakeRepo(commonDir, rep) { return repoDir } -function writeRepo(repoSpec) { +export function writeRepo(repoSpec: RepoSpec) { const rep = parseSpec(repoSpec) return takeDirAndMakeRepo(reposDir, rep) } - -exports.writeRepo = writeRepo diff --git a/tsconfig.json b/tsconfig.json index 1e6b2ae1d..aa64d0959 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,10 @@ { "compilerOptions": { - "allowSyntheticDefaultImports": true, + "strict": true, + "noImplicitAny": true, + "skipLibCheck": true, "esModuleInterop": true, + "allowSyntheticDefaultImports": true, "target": "es2018", "experimentalDecorators": true, "resolveJsonModule": true, @@ -24,17 +27,15 @@ "module": "CommonJS", "noUnusedLocals": true, "noUnusedParameters": true, - "noImplicitAny": false, - "sourceMap": false, + "sourceMap": true, "importsNotUsedAsValues": "error", "paths": { "@octokit/oauth-app": ["../type-overrides/octokit--oauth-app"], - } + }, }, "include": [ "packages", "typedoc", - "src", "test" ], "exclude": [ @@ -42,7 +43,5 @@ "tools", "docs", "declarations", -// "**/test/**/*.ts", -// "**/*.spec.ts" ] } diff --git a/tsconfig.strict.json b/tsconfig.strict.json deleted file mode 100644 index 01e1ab5ef..000000000 --- a/tsconfig.strict.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "strict": true, - "noImplicitAny": true, - "skipLibCheck": true, - "esModuleInterop": true - }, - "include": [ - "packages/pvm-core/lib/env.ts", - "packages/pvm-types/lib/env-schema.ts" - ] -} diff --git a/website/docs/book/plugins/configuring.md b/website/docs/book/plugins/configuring.md deleted file mode 100644 index 49c5a8571..000000000 --- a/website/docs/book/plugins/configuring.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -id: plugins-configuring -title: Конфигурирование плагинов ---- - -Передача опций в плагин осуществляется через конфигурационный файл -```toml -[plugins] -local_plugins = ['src/changelog-plugin'] - -[plugins.options.'src/changelog-plugin'] -format = 'lite' -``` - -Необходимо, чтобы имя плагина в `plugins.options` совпадало с именем, по которому -pvm загружает плагин. Так если плагин загружался автоматически, то в качестве -имени нужно использовать имя пакета, а если плагин загружался через `local_plugins`, то -нужно указывать относительный путь до плагина. \ No newline at end of file diff --git a/website/docs/book/plugins/enabling.md b/website/docs/book/plugins/enabling.md deleted file mode 100644 index 61bc257fe..000000000 --- a/website/docs/book/plugins/enabling.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -id: plugins-enabling -title: Подключение плагинов ---- - -## Автоматическое подключение - -В корневом `package.json` проекта pvm ищет пакеты с именами начинающимися с `pvm-plugin` или `@pvm/plugin` -либо с именами подходящими под маску `<любой неймспейс>/pvm-plugin`. - -```json -{ - "dependencies": { - "@pvm/plugin-http-proxy": "^0.51.3" - } -} -``` - -## На основе конфиг-файла pvm - -В секции `plugins.local_plugins` можно указать список относительных путей до плагинов -```yaml -[plugins] -local_plugins = ['src/changelog-plugin'] -``` - -## Через так называемый провайдер - -Пакет, имя которого удовлетворяет условиям, аналогичным для автоматически загружаемого плагина либо имеющего в названии `pvm` -проверяет на наличие в его `package.json` флага `pvm.provider`. Если флаг есть, то все плагины pvm -имеющиеся в зависимостях этого пакета, автоматически загружаются. \ No newline at end of file diff --git a/website/docs/config/config-defaults.md b/website/docs/config/config-defaults.md index af6d02a96..aa9c54290 100644 --- a/website/docs/config/config-defaults.md +++ b/website/docs/config/config-defaults.md @@ -4,5 +4,5 @@ title: Configuration default values --- ```typescript -@cli-inline cat packages/pvm-core/pvm-defaults.ts +@cli-inline cat packages/pvm/pvm-defaults.ts ``` \ No newline at end of file diff --git a/website/docs/config/config.md b/website/docs/config/config.md index 44b9efe18..1a9817ed5 100644 --- a/website/docs/config/config.md +++ b/website/docs/config/config.md @@ -3,7 +3,7 @@ id: configuration title: Configuration --- -## [Config schema](api/interfaces/pvm_types.Config.md) +## [Config schema](api/interfaces/pvm_pvm.Config.md) ## Configuration sources diff --git a/website/docs/config/env-defaults.md b/website/docs/config/env-defaults.md index a0640f741..c4b5a58c7 100644 --- a/website/docs/config/env-defaults.md +++ b/website/docs/config/env-defaults.md @@ -3,7 +3,7 @@ id: env-defaults title: Env variables default values --- -Default [env](api/interfaces/pvm_types.Env.md) values +Default [env](api/interfaces/pvm_pvm.Env.md) values ```typescript -@cli-inline cat packages/pvm-core/env-defaults.ts +@cli-inline cat packages/pvm/env-defaults.ts ``` diff --git a/website/docs/how-to/reviewers.md b/website/docs/how-to/reviewers.md index 1ae6375e2..4e5795c38 100644 --- a/website/docs/how-to/reviewers.md +++ b/website/docs/how-to/reviewers.md @@ -16,7 +16,7 @@ import { } from '@pvm/gitlab' import { readCodeOwners } from '@pvm/cowners' import { changedFiles } from '@pvm/pkgset/lib/changed-files' -import drainItems from '@pvm/core/lib/iter/drain-items' +import drainItems from '@pvm/pvm' async function main() { const codeOwners = await readCodeOwners() diff --git a/website/docs/how-to/update-hints.md b/website/docs/how-to/update-hints.md index e51eb013d..917441561 100644 --- a/website/docs/how-to/update-hints.md +++ b/website/docs/how-to/update-hints.md @@ -25,7 +25,7 @@ leave until one not delete it manually. In this case hints can be placed in merg `update-hints.toml` is a special file that is commited as usual and merged in merge request. Below is full example of hints content ```toml -@cli-inline cat packages/pvm-update/cli/hints_file.txt +@cli-inline cat packages/pvm/commands/update/hints_file.txt ``` ## Merge request description update hints diff --git a/website/docs/troubleshooting/eneedauth.md b/website/docs/troubleshooting/eneedauth.md new file mode 100644 index 000000000..f219e0800 --- /dev/null +++ b/website/docs/troubleshooting/eneedauth.md @@ -0,0 +1,24 @@ +--- +id: eneedauth +title: ENEEDAUTH +--- + +## Error + +Publication failure: + +``` +Error: Command "npm publish ./package --tag latest --registry https://registry.npmjs.org/ --unsafe-perm" +... +npm ERR! code ENEEDAUTH +npm ERR! need auth This command requires you to be logged in to https://registry.npmjs.org/ +npm ERR! need auth You need to authorize this machine using `npm adduser` +``` + +## Reason + +In Node.js after 18.14.0 version npm was upgraded to major 9.3.1 version - https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V18.md#auth, which broke authorization logic in pvm + +## Solution + +Stick to 18.13 node version - `node:18.13.0` until https://github.com/Tinkoff/pvm/issues/75 diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index bbd374046..f951e6daf 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -81,6 +81,10 @@ const siteConfig = { to: 'docs/how-to/move-to-dedicated-versions', label: 'How-To', }, + { + to: 'docs/troubleshooting/eneedauth', + label: 'Troubleshooting', + }, { label: 'References', to: `docs/api/modules/pvm_pvm`, diff --git a/website/download-pvm-packages.mjs b/website/download-pvm-packages.mjs index 17f0b8ece..be81156dd 100644 --- a/website/download-pvm-packages.mjs +++ b/website/download-pvm-packages.mjs @@ -1,15 +1,15 @@ -import fs from "fs"; +import fs from "fs-extra"; import path from "path"; import fetch from "node-fetch"; -import { pkgset } from "@pvm/pkgset"; -import drainItems from "@pvm/core/lib/iter/drain-items.js"; import {fileURLToPath} from 'url'; +import { Pvm } from '@pvm/pvm' const __filename = fileURLToPath(import.meta.url); -const pvmPackages = (await drainItems.default(pkgset('all', { +const pvm = new Pvm({ cwd: path.join(path.dirname(__filename), '..') -}))).filter(pkg => !pkg.meta.private).map(pkg => ({ +}) +const pvmPackages = (await pvm.getPackages('all')).filter(pkg => !pkg.meta.private).map(pkg => ({ name: pkg.name, version: pkg.version, tgz: `${pkg.shortName}-${pkg.version}.tgz`, @@ -18,10 +18,8 @@ const pvmPackages = (await drainItems.default(pkgset('all', { console.log('@pvm/* packages', JSON.stringify(pvmPackages, null, 2)) const artifactsPath = 'build/artifacts' -if (!fs.existsSync(artifactsPath)) { - fs.mkdirSync(artifactsPath) -} -fs.writeFileSync(path.join(artifactsPath, 'packages.json'), JSON.stringify(pvmPackages)) + +fs.outputFileSync(path.join(artifactsPath, 'packages.json'), JSON.stringify(pvmPackages)) pvmPackages.forEach(async ({ name, tgz }) => { const pkgTarPath = path.join(artifactsPath, tgz) const pkgTarUrl = `https://registry.npmjs.org/${name}/-/${tgz}` diff --git a/website/package-lock.json b/website/package-lock.json index 861e29fee..eb80dab3e 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -14,7 +14,6 @@ "command-exists": "^1.2.9", "docusaurus-lunr-search": "^2.1.10", "docusaurus-plugin-typedoc": "^0.16.3", - "fs-extra": "^10.1.0", "nlfurniss-typedoc-plugin-sourcefile-url": "^2.0.0", "react": "^16.13.1", "react-dom": "^16.13.1", diff --git a/website/sidebars.js b/website/sidebars.js index b8fdcc3e5..9851bd61d 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -31,7 +31,7 @@ module.exports = { }, 'Configuration': [ 'config/configuration', - 'api/interfaces/pvm_types.Env', + 'api/interfaces/pvm_pvm.Env', ], 'Справочник': { 'How To': [ @@ -41,6 +41,9 @@ module.exports = { 'how-to/local-releases', 'how-to/update-hints', ], + 'Troubleshooting': [ + 'troubleshooting/eneedauth', + ], }, 'API': [ {