diff --git a/package.json b/package.json index c3cd9fc..b38f8c2 100644 --- a/package.json +++ b/package.json @@ -60,5 +60,10 @@ "yarn prettier --write", "git add" ] + }, + "dependencies": { + "@roadiehq/roadie-backstage-entity-validator": "^2.3.0", + "axios": "^1.4.0", + "js-yaml": "^4.1.0" } } diff --git a/rules/common/__tests__/backstage.test.ts b/rules/common/__tests__/backstage.test.ts new file mode 100644 index 0000000..31910db --- /dev/null +++ b/rules/common/__tests__/backstage.test.ts @@ -0,0 +1,112 @@ +jest.mock("danger", () => jest.fn()) +import * as danger from "danger" +const dm = danger as any + +import backstage from "../backstage" + +beforeEach(() => { + dm.danger = {} + dm.fail = jest.fn() +}) + +it("fails when metadata.name is absent", async () => { + const yamlContent = `--- +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + description: Foo project + annotations: + github.com/project-slug: loadsmart/foo + circleci.com/project-slug: github/loadsmart/foo + opslevel.com/tier: tier_1 + labels: + loadsmart.com/product: internal-product + tags: + - go +spec: + type: service + lifecycle: production + owner: developer-productivity +` + + dm.danger.github = { + utils: { + fileContents: () => Promise.resolve(yamlContent), + }, + pr: { + head: { user: { login: "danger" }, repo: { name: "peril-settings" } }, + state: "open", + }, + } + dm.danger.git = { + modified_files: ["catalog-info.yaml"], + created_files: [], + } + + await backstage() + + expect(dm.fail).toHaveBeenCalledWith( + `The 'catalog-info.yaml' file is not valid for Backstage. Error details:\n\n\`\`\`\nError: Error: metadata.name must have a value\n\`\`\`` + ) +}) + +it("fails when spec.owner is absent", async () => { + const yamlContent = `--- +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: foo + description: Foo project + annotations: + github.com/project-slug: loadsmart/foo + circleci.com/project-slug: github/loadsmart/foo + opslevel.com/tier: tier_1 + labels: + loadsmart.com/product: internal-product + tags: + - go +spec: + type: service + lifecycle: production +` + + dm.danger.github = { + utils: { + fileContents: () => Promise.resolve(yamlContent), + }, + pr: { + head: { user: { login: "danger" }, repo: { name: "peril-settings" } }, + state: "open", + }, + } + dm.danger.git = { + modified_files: ["catalog-info.yaml"], + created_files: [], + } + + await backstage() + + expect(dm.fail).toHaveBeenCalledWith( + `The 'catalog-info.yaml' file is not valid for Backstage. Error details:\n\n\`\`\`\nError: TypeError: /spec must have required property 'owner' - missingProperty: owner\n\`\`\`` + ) +}) + +it("fails when catalog-info.yaml does not exist", async () => { + dm.danger.github = { + utils: { + fileContents: () => Promise.resolve(), + }, + pr: { + head: { user: { login: "danger" }, repo: { name: "peril-settings" } }, + state: "open", + }, + } + dm.danger.git = { + modified_files: [], + created_files: [], + } + + await backstage() + + expect(dm.fail).toHaveBeenCalledWith(`'catalog-info.yaml' file doesn't exist.`) +}) diff --git a/rules/common/backstage.ts b/rules/common/backstage.ts new file mode 100644 index 0000000..34ea81c --- /dev/null +++ b/rules/common/backstage.ts @@ -0,0 +1,31 @@ +import { danger, fail } from "danger" +import axios from "axios" +import { validate } from "@roadiehq/roadie-backstage-entity-validator" + +const backstage = async () => { + const pr = danger.github.pr + const utils = danger.github.utils + const schemaPath = "./schemas/backstage.annotations.json" + const schemaURL = "" + + const isOpen = pr.state === "open" + + if (!isOpen) { + return + } + + const filePath = "catalog-info.yaml" + const fileContent = await utils.fileContents(filePath, `${pr.head.user.login}/${pr.head.repo.name}`, pr.head.sha) + + if (fileContent) { + try { + await validate(fileContent, true, schemaPath) + } catch (e) { + fail(`The 'catalog-info.yaml' file is not valid for Backstage. Error details:\n\n\`\`\`\n${e}\n\`\`\``) + } + } else { + fail(`'${filePath}' file doesn't exist.`) + } +} + +export default backstage diff --git a/rules/common/index.ts b/rules/common/index.ts index f575576..44a33ee 100644 --- a/rules/common/index.ts +++ b/rules/common/index.ts @@ -4,6 +4,7 @@ import mergeCommits from "./mergeCommits" import changelog from "./changelog" import testsUpdated from "./testsUpdated" import notificationHubTemplate from "./notificationHubTemplate" +import backstage from "./backstage" // Default run export default async () => { @@ -13,4 +14,5 @@ export default async () => { await changelog() testsUpdated() await notificationHubTemplate() + await backstage() } diff --git a/rules/common/schemas/backstage.annotations.json b/rules/common/schemas/backstage.annotations.json new file mode 100644 index 0000000..e8cefc5 --- /dev/null +++ b/rules/common/schemas/backstage.annotations.json @@ -0,0 +1,301 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "Entity metadata annotations", + "description": "Individual annotation format validations", + "type": "object", + "required": ["metadata"], + "additionalProperties": true, + "properties": { + "metadata": { + "type": "object", + "required": ["annotations", "tags"], + "properties": { + "annotations": { + "type": "object", + "description": "Key/value pairs of non-identifying auxiliary information attached to the entity.", + "additionalProperties": false, + "patternProperties": { + "^.+$": { + "type": "string" + } + }, + "required": ["github.com/project-slug", "circleci.com/project-slug", "opslevel.com/tier"], + "allOf": [ + { + "properties": { + "backstage.io/managed-by-location": { + "type": "string", + "pattern": "(url|gitlab|github|azure/api|dir):.*" + } + } + }, + { + "properties": { + "backstage.io/managed-by-origin-location": { + "type": "string", + "pattern": "(url|gitlab|github|azure/api|dir):.*" + } + } + }, + { + "properties": { + "backstage.io/techdocs-ref": { + "type": "string", + "pattern": "(url|gitlab|github|azure/api|dir):.*" + } + } + }, + { + "properties": { + "backstage.io/source-location": { + "type": "string", + "pattern": "((url|gitlab|github|azure/api):.*|(dir):.*/)$" + } + } + }, + { + "properties": { + "backstage.io/view-url": { + "type": "string", + "format": "uri" + } + } + }, + { + "properties": { + "backstage.io/edit-url": { + "type": "string", + "format": "uri" + } + } + }, + { + "properties": { + "graph.microsoft.com/group-id": { + "type": "string", + "format": "uuid" + } + } + }, + { + "properties": { + "graph.microsoft.com/user-id": { + "type": "string", + "format": "uuid" + } + } + }, + { + "properties": { + "datadog/dashboard-url": { + "type": "string", + "format": "uri" + } + } + }, + { + "properties": { + "backstage.io/ldap-uuid": { + "type": "string", + "format": "uuid" + } + } + }, + { + "properties": { + "backstage.io/ldap-dn": { + "type": "string" + } + } + }, + { + "properties": { + "backstage.io/ldap-rdn": { + "type": "string" + } + } + }, + { + "properties": { + "jenkins.io/github-folder": { + "type": "string" + } + } + }, + { + "properties": { + "github.com/project-slug": { + "type": "string" + } + } + }, + { + "properties": { + "github.com/team-slug": { + "type": "string" + } + } + }, + { + "properties": { + "github.com/user-login": { + "type": "string" + } + } + }, + { + "properties": { + "rollbar.com/project-slug": { + "type": "string" + } + } + }, + { + "properties": { + "circleci.com/project-slug": { + "type": "string" + } + } + }, + { + "properties": { + "sonarqube.org/project-key": { + "type": "string" + } + } + }, + { + "properties": { + "backstage.io/code-coverage": { + "type": "string" + } + } + }, + { + "properties": { + "github.com/project-slug": { + "type": "string" + } + } + }, + { + "properties": { + "sentry.io/project-slug": { + "type": "string" + } + } + }, + { + "properties": { + "aws.com/lambda-function-name": { + "type": "string" + } + } + }, + { + "properties": { + "aws.com/lambda-region": { + "type": "string" + } + } + }, + { + "properties": { + "jira/project-key": { + "type": "string" + } + } + }, + { + "properties": { + "snyk.io/org-name": { + "type": "string" + } + } + }, + { + "properties": { + "graph.microsoft.com/tenant-id": { + "type": "string" + } + } + }, + { + "properties": { + "github.com/project-slug": { + "type": "string", + "pattern": "(loadsmart/).*" + } + } + }, + { + "properties": { + "circleci.com/project-slug": { + "type": "string", + "pattern": "(github/loadsmart/).*" + } + } + }, + { + "properties": { + "sentry.io/project-slug": { + "type": "string" + } + } + }, + { + "properties": { + "snyk.io/org-name": { + "type": "string", + "pattern": "loadsmart" + } + } + }, + { + "properties": { + "snyk.io/project-ids": { + "type": "string", + "pattern": "^(\\b[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\\b)(,\\b[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\\b)*$" + } + } + }, + { + "properties": { + "opslevel.com/tier": { + "type": "string", + "pattern": "^tier_[0-4]$" + } + } + } + ] + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "labels": { + "type": "object", + "description": "Optional key/value pairs of that are attached to the entity, and their use is identical to Kubernetes object labels.", + "additionalProperties": false, + "patternProperties": { + "^.+$": { + "type": "string" + } + }, + "allOf": [ + { + "properties": { + "loadsmart.com/product": { + "type": "string", + "pattern": "^(website|tms-integrations|shipper-guide|opendock|loadboard|kamion|internal-product|incident-management|alice|abgail|platform)$" + } + } + } + ] + } + } + } + } +} diff --git a/settings-peril.json b/settings-peril.json index b0f7d47..235eed6 100644 --- a/settings-peril.json +++ b/settings-peril.json @@ -5,7 +5,7 @@ }, "rules": { "pull_request.opened": ["rules/common/approveReleasePR.ts", "rules/common/changelog.ts"], - "pull_request.synchronize": "rules/common/changelog.ts", + "pull_request.synchronize": ["rules/common/changelog.ts", "rules/common/backstage.ts"], "pull_request.closed": "rules/common/deleteMergedPRBranch.ts", "issue_comment.created": [ "rules/common/markAsMergeOnGreen.ts", diff --git a/yarn.lock b/yarn.lock index 2d56560..93b4cd9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,21 @@ # yarn lockfile v1 +"@actions/core@^1.10.0": + version "1.10.0" + resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.10.0.tgz#44551c3c71163949a2f06e94d9ca2157a0cfac4f" + integrity sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug== + dependencies: + "@actions/http-client" "^2.0.1" + uuid "^8.3.2" + +"@actions/http-client@^2.0.1": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-2.1.0.tgz#b6d8c3934727d6a50d10d19f00a711a964599a9f" + integrity sha512-BonhODnXr3amchh4qkmjPMUO8mFi/zLaaCeCAJZqch8iQqyDnVIkySjB38VHAC8IJ+bnlgfOqlhpyCUZHlQsqw== + dependencies: + tunnel "^0.0.6" + "@babel/polyfill@^7.2.5": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.10.4.tgz#915e5bfe61490ac0199008e35ca9d7d151a8e45a" @@ -10,6 +25,62 @@ core-js "^2.6.5" regenerator-runtime "^0.13.4" +"@backstage/catalog-model@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@backstage/catalog-model/-/catalog-model-1.3.0.tgz#3d926b4e9d3d871f37e88295788cdce3b4ec17d3" + integrity sha512-QFoLho/SvzNepFHDUBL58fdcktAtshQQQ1FABpDbnBR954iQ7MGQlSPP+2uSrQ5wGpZylIjpFnsH3NB/k06i6g== + dependencies: + "@backstage/config" "^1.0.7" + "@backstage/errors" "^1.1.5" + "@backstage/types" "^1.0.2" + ajv "^8.10.0" + json-schema "^0.4.0" + lodash "^4.17.21" + uuid "^8.0.0" + +"@backstage/config@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@backstage/config/-/config-1.0.7.tgz#f6929fb5af80ca36fae8b385f957f9c0a64a72a6" + integrity sha512-8Fh3QJl0PltQZ9nCNr9UsYoRNCbfhJQR+1z1JUur7hTgJ/yCVnVPmESrpBWR27NCT7IBNtRv0jZhzj/BYZfFgA== + dependencies: + "@backstage/types" "^1.0.2" + lodash "^4.17.21" + +"@backstage/errors@^1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@backstage/errors/-/errors-1.1.5.tgz#27c0deb040a136f196865d2d6d24e31f1d17f472" + integrity sha512-aKkYniwo3dkd8a5dIZhnfoSLqsFzBqzQC2yhw/XfOUbfEkej6XZVsPKws/zZODUAPF1ZKNMUBbt1NTVG14Bahw== + dependencies: + "@backstage/types" "^1.0.2" + cross-fetch "^3.1.5" + serialize-error "^8.0.1" + +"@backstage/plugin-permission-common@^0.7.5": + version "0.7.5" + resolved "https://registry.yarnpkg.com/@backstage/plugin-permission-common/-/plugin-permission-common-0.7.5.tgz#6403446a98a665f813e2b550d9e47c9059566dcc" + integrity sha512-7kltlP+p79tiyOgxao90+yme6HtWtxY6lIl3lksYD2XMb19FFcJaxtYmx3DPlDzecaVAoUK8gQG9NrGtbQJeTQ== + dependencies: + "@backstage/config" "^1.0.7" + "@backstage/errors" "^1.1.5" + "@backstage/types" "^1.0.2" + cross-fetch "^3.1.5" + uuid "^8.0.0" + zod "^3.21.4" + +"@backstage/plugin-scaffolder-common@^1.2.7": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@backstage/plugin-scaffolder-common/-/plugin-scaffolder-common-1.2.7.tgz#a61ab8f1360e6882164430ae19edc657e342d286" + integrity sha512-5Hk7/cNozs7ZQtpcytgwCxoPWXLLJTr2hhmALw0/AU1P/aOtXvI/4BeYpazeeoRcUVFT9oszjUGBgYfNIEXeoQ== + dependencies: + "@backstage/catalog-model" "^1.3.0" + "@backstage/plugin-permission-common" "^0.7.5" + "@backstage/types" "^1.0.2" + +"@backstage/types@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@backstage/types/-/types-1.0.2.tgz#a12cdc7c1ec7e0d99cb2e30903b9dfd97c1050c9" + integrity sha512-wE4AAP3je00UlVNV5faIto414aOUNv30CmvNmxgImNKelPRYJsMEicM9slwkrNMyFLqTMITeXJvQvMofUk3Wxg== + "@octokit/auth-token@^2.4.0": version "2.4.2" resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.4.2.tgz#10d0ae979b100fa6b72fa0e8e63e27e6d0dbff8a" @@ -114,6 +185,21 @@ dependencies: "@types/node" ">= 8" +"@roadiehq/roadie-backstage-entity-validator@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@roadiehq/roadie-backstage-entity-validator/-/roadie-backstage-entity-validator-2.3.0.tgz#acae4fb25fcdb7f61672e1855058e66c8b2d15d9" + integrity sha512-pQ5s2Q6zPYW2MS/YU7srUsUVA17QOoX/jAAVtwTI7YKxpKbTsrL5LUfmtjoQhdgzhkziJzC4a3HXCLIpjm3HgA== + dependencies: + "@actions/core" "^1.10.0" + "@backstage/catalog-model" "^1.3.0" + "@backstage/plugin-scaffolder-common" "^1.2.7" + ajv "^8.4.0" + ajv-formats "^2.1.0" + glob "^7.1.7" + js-yaml "^4.1.0" + memfs "^3.4.1" + minimist "^1.2.5" + "@slack/client@^4.2.2": version "4.12.0" resolved "https://registry.yarnpkg.com/@slack/client/-/client-4.12.0.tgz#ec14c84a572cd9afed398bbcf7241c5a83e94c57" @@ -246,6 +332,13 @@ agent-base@4, agent-base@^4.1.0: dependencies: es6-promisify "^5.0.0" +ajv-formats@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + ajv@^4.9.1: version "4.11.8" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" @@ -273,6 +366,16 @@ ajv@^6.5.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^8.0.0, ajv@^8.10.0, ajv@^8.4.0: + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + ansi-escapes@^1.0.0, ansi-escapes@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" @@ -345,6 +448,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + arr-diff@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" @@ -492,6 +600,15 @@ axios@^0.18.0: follow-redirects "1.5.10" is-buffer "^2.0.2" +axios@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" + integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" @@ -1106,6 +1223,13 @@ create-thenable@~1.0.0: object.omit "~2.0.0" unique-concat "~0.2.2" +cross-fetch@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" + integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== + dependencies: + node-fetch "2.6.7" + cross-spawn@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -2135,6 +2259,11 @@ follow-redirects@1.5.10: dependencies: debug "=3.1.0" +follow-redirects@^1.15.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -2174,6 +2303,15 @@ form-data@^2.3.3: combined-stream "^1.0.6" mime-types "^2.1.12" +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@~2.1.1: version "2.1.4" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" @@ -2231,6 +2369,11 @@ fs-extra@^9.0.1: jsonfile "^6.0.1" universalify "^1.0.0" +fs-monkey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" + integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -2395,6 +2538,18 @@ glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.1.7: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -3408,6 +3563,13 @@ js-yaml@^3.10.0, js-yaml@^3.7.0, js-yaml@^3.9.0: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -3482,11 +3644,21 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= +json-schema@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" @@ -3815,6 +3987,11 @@ lodash@^4.15.0: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + log-symbols@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" @@ -3916,6 +4093,13 @@ memfs-or-file-map-to-github-branch@^1.1.0: dependencies: "@octokit/rest" "^16.43.1" +memfs@^3.4.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.5.1.tgz#f0cd1e2bfaef58f6fe09bfb9c2288f07fea099ec" + integrity sha512-UWbFJKvj5k+nETdteFndTpYxdeTMox/ULeqX5k/dpaQJCCFmj5EeKv3dBcyO2xmkRAx2vppRu5dVG7SOtsGOzA== + dependencies: + fs-monkey "^1.0.3" + merge@^1.1.3: version "1.2.1" resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" @@ -4000,6 +4184,13 @@ minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" @@ -4093,6 +4284,13 @@ node-cleanup@^2.1.2: resolved "https://registry.yarnpkg.com/node-cleanup/-/node-cleanup-2.1.2.tgz#7ac19abd297e09a7f72a71545d951b517e4dde2c" integrity sha1-esGavSl+Caf3KnFUXZUbUX5N3iw= +node-fetch@2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + node-fetch@^1.7.1: version "1.7.3" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" @@ -4675,6 +4873,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" @@ -5078,6 +5281,13 @@ semver@^6.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +serialize-error@^8.0.1: + version "8.1.0" + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-8.1.0.tgz#3a069970c712f78634942ddd50fbbc0eaebe2f67" + integrity sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ== + dependencies: + type-fest "^0.20.2" + set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -5605,6 +5815,11 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" +tunnel@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" + integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== + tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" @@ -5617,6 +5832,11 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -5728,6 +5948,11 @@ uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== +uuid@^8.0.0, uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + validate-npm-package-license@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" @@ -5798,6 +6023,14 @@ whatwg-url@^4.3.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" @@ -5982,3 +6215,8 @@ yargs@^9.0.0: which-module "^2.0.0" y18n "^3.2.1" yargs-parser "^7.0.0" + +zod@^3.21.4: + version "3.21.4" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.21.4.tgz#10882231d992519f0a10b5dd58a38c9dabbb64db" + integrity sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==