From ad1dd80c5ad6cba1e59f9b562a1285294217a2de Mon Sep 17 00:00:00 2001 From: aldousalvarez Date: Fri, 30 Jun 2023 10:56:00 +0800 Subject: [PATCH] chore(tools): script to bump openapi spec dependency versions 1. Adds a new script that can be executed in order to bump all release versions of the open API specs. These are one of two main categories: 1.1. The top level .info.version property of the OpenAPI spec JSON object 1.2. Any schema component references embedded anywhere deep inside the JSON object that we define our specs as, for example when a connector plugin's endpoint returns a response object whose schema is defined in another package's OpenAPI spec file such as the core-api package's. 2. Fixed a bug in the "prettier" npm script which was pointing to a non- existent configuration file. This was necessary to be fixed in this commit because tests had to be carried out whether the auto-formatting applied by the version bumping script is consistent with the auto-formatting that is applied when we run prettier via the CLI (there was some struggle here to figure out that we have to pre-format the JSON string held in-memory via JSON.stringify() first otherwise the formatted version would diverge from what the CLI does to the .json files on-disk) 3. We had to exclude the tag called v2.0.0-alpha-prerelease because it was incorrectly named unfortunately: it is considered newer than v2.0.0-alpha.1 by the semver-parser package but it is actually older, e.g. we've issued v2.0.0-alpha-prerelease before we issued v2.0.0-alpha.1 (which is our mistake and this is the workaround to rectify that after the fact without having to force delete the tag that we've already pushed to the upstream main branch). This exclusion is applied by default which might turn out to be a mistake later but right now it does not look like there would be an edge case where we need to handle this in any different way. 4. The script is re-entrant and will save a thorough report of what it did to temporary .json files whose names are date and timestamped within the project root's ./build/ subfolder. 5. The target version to bump to can be specified explicitly via the --target-version CLI parameter but if it not provided then will default to whatever is the latest sem-ver compatibly named tag in the git log. Example to specify target version explicitly: `yarn tools:bump-openapi-spec-dep-versions --target-version=v3.2.1` Example to let the script figure out what the target version should be: `yarn tools:bump-openapi-spec-dep-versions` Fixes #2206 Co-authored-by: Peter Somogyvari Signed-off-by: aldousalvarez Signed-off-by: Peter Somogyvari --- package.json | 16 +- tools/bump-openapi-spec-dep-versions.ts | 314 ++++++++++++++++++++++++ tools/get-latest-sem-ver-git-tag.ts | 67 +++++ tools/has-key.ts | 3 + yarn.lock | 66 +++-- 5 files changed, 447 insertions(+), 19 deletions(-) create mode 100644 tools/bump-openapi-spec-dep-versions.ts create mode 100644 tools/get-latest-sem-ver-git-tag.ts create mode 100644 tools/has-key.ts diff --git a/package.json b/package.json index 79958b4c65..3c7be4918a 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,8 @@ "enable-corepack": "npm i -g corepack && corepack enable && corepack prepare yarn@1.22.17 --activate", "custom-checks": "TS_NODE_PROJECT=./tools/tsconfig.json node --trace-deprecation --experimental-modules --abort-on-uncaught-exception --loader ts-node/esm --experimental-specifier-resolution=node ./tools/custom-checks/run-custom-checks.ts", "tools:validate-bundle-names": "TS_NODE_PROJECT=./tools/tsconfig.json node --trace-deprecation --experimental-modules --abort-on-uncaught-exception --loader ts-node/esm --experimental-specifier-resolution=node ./tools/validate-bundle-names.js", + "tools:bump-openapi-spec-dep-versions": "TS_NODE_PROJECT=./tools/tsconfig.json node --trace-deprecation --experimental-modules --abort-on-uncaught-exception --loader ts-node/esm --experimental-specifier-resolution=node ./tools/bump-openapi-spec-dep-versions.ts", + "tools:get-latest-sem-ver-git-tag": "TS_NODE_PROJECT=./tools/tsconfig.json node --abort-on-uncaught-exception --loader ts-node/esm --experimental-specifier-resolution=node --no-warnings ./tools/get-latest-sem-ver-git-tag.ts", "generate-api-server-config": "node ./tools/generate-api-server-config.js", "sync-ts-config": "TS_NODE_PROJECT=tools/tsconfig.json node --experimental-json-modules --loader ts-node/esm ./tools/sync-npm-deps-to-tsc-projects.ts", "start:api-server": "node ./packages/cactus-cmd-api-server/dist/lib/main/typescript/cmd/cactus-api.js --config-file=.config.json", @@ -79,7 +81,7 @@ "test:integration": "tap --ts --node-arg=--max-old-space-size=4096 --jobs=1 --timeout=3600 --no-check-coverage \"packages/cactus-*/src/test/typescript/integration/\"", "changelog": "conventional-changelog --infile CHANGELOG.md --outfile CHANGELOG.md && git add CHANGELOG.md", "commit": "git-cz --signoff", - "prettier": "prettier --write --config .prettierrc.json \"./**/*.{ts,js}\"", + "prettier": "prettier --write --config .prettierrc.js \"./**/src/main/json/openapi.json\"", "version": "npm ci && npm run build:dev && npm run build:prod && npm run test:unit", "lerna-publish-canary": "npm run run-ci && lerna publish --canary --force-publish --dist-tag $(git branch --show-current) --preid $(git branch --show-current).$(git rev-parse --short HEAD)", "lerna-publish": "lerna publish --conventional-commits --sign-git-commit --sign-git-tag", @@ -89,11 +91,11 @@ "devDependencies": { "@commitlint/cli": "13.1.0", "@commitlint/config-conventional": "13.1.0", - "@openapitools/openapi-generator-cli": "2.4.14", "@lerna-lite/cli": "1.17.0", "@lerna-lite/exec": "1.17.0", "@lerna-lite/list": "1.17.0", "@lerna-lite/run": "1.17.0", + "@openapitools/openapi-generator-cli": "2.4.14", "@types/fs-extra": "9.0.12", "@types/jasminewd2": "2.0.10", "@types/jest": "27.5.0", @@ -102,6 +104,7 @@ "@types/tape": "4.13.2", "@types/tape-promise": "4.0.1", "@types/uuid": "8.3.1", + "@types/yargs": "17.0.24", "@typescript-eslint/eslint-plugin": "5.27.0", "@typescript-eslint/parser": "5.27.0", "buffer": "6.0.3", @@ -121,12 +124,13 @@ "eslint-plugin-prettier": "3.4.0", "eslint-plugin-promise": "5.1.0", "eslint-plugin-standard": "5.0.0", + "fast-safe-stringify": "2.1.1", "fs-extra": "10.0.0", "git-cz": "4.7.6", "globby": "12.0.0", "google-protobuf": "3.21.2", - "grpc_tools_node_protoc_ts": "5.3.1", "grpc-tools": "1.11.2", + "grpc_tools_node_protoc_ts": "5.3.1", "husky": "7.0.1", "inquirer": "8.1.2", "jest": "28.1.0", @@ -142,11 +146,14 @@ "node-polyfill-webpack-plugin": "1.1.4", "npm-run-all": "4.1.5", "npm-watch": "0.11.0", + "openapi-types": "12.1.3", "prettier": "2.1.2", "protoc-gen-ts": "0.6.0", "run-time-error": "1.4.0", "secp256k1": "4.0.2", + "semver-parser": "4.1.4", "shebang-loader": "0.0.1", + "simple-git": "3.19.1", "sort-package-json": "1.53.1", "source-map-loader": "3.0.0", "stream-browserify": "3.0.0", @@ -160,7 +167,8 @@ "webpack": "5.76.0", "webpack-bundle-analyzer": "4.4.2", "webpack-cli": "4.7.2", - "wget-improved": "3.4.0" + "wget-improved": "3.4.0", + "yargs": "17.7.2" }, "resolutions": { "ansi-html": ">0.0.8", diff --git a/tools/bump-openapi-spec-dep-versions.ts b/tools/bump-openapi-spec-dep-versions.ts new file mode 100644 index 0000000000..ce98eef617 --- /dev/null +++ b/tools/bump-openapi-spec-dep-versions.ts @@ -0,0 +1,314 @@ +import { URL } from "url"; +import { fileURLToPath } from "url"; +import path from "path"; +import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; +import fs from "fs-extra"; +import { globby, Options as GlobbyOptions } from "globby"; +import { RuntimeError } from "run-time-error"; +import prettier from "prettier"; +import { OpenAPIV3_1 } from "openapi-types"; +import { isValidSemVer } from "semver-parser"; +import fastSafeStringify from "fast-safe-stringify"; + +import { hasKey } from "./has-key"; +import { getLatestSemVerGitTagV1 } from "./get-latest-sem-ver-git-tag"; + +const TAG = "[tools/bump-openapi-spec-dep-versions.ts]"; +export interface IBumpOpenAPISpecDepVersionsV1Request { + readonly argv: string[]; + readonly env: NodeJS.ProcessEnv; + readonly targetVersion: string; +} + +export interface IBumpOpenAPISpecDepVersionsV1Response { + readonly specFilePaths: string[]; + readonly specFileReports: ISpecFileReportV1[]; +} + +export interface ISpecFileReportV1 { + readonly specFilePath: string; + readonly replacementCount: number; + readonly replacements: ISpecRefReplacementV1[]; +} + +export interface ISpecRefReplacementV1 { + readonly propertyPath: string; + readonly oldValue: string; + readonly newValue: string; +} + +const nodePath = path.resolve(process.argv[1]); +const modulePath = path.resolve(fileURLToPath(import.meta.url)); +const isRunningDirectlyViaCLI = nodePath === modulePath; + +const main = async (argv: string[], env: NodeJS.ProcessEnv) => { + const req = await createRequest(argv, env); + await bumpOpenApiSpecDepVersions(req); +}; + +if (isRunningDirectlyViaCLI) { + main(process.argv, process.env); +} + +async function createRequest( + argv: string[], + env: NodeJS.ProcessEnv, +): Promise { + if (!argv) { + throw new RuntimeError(`Process argv cannot be falsy.`); + } + if (!env) { + throw new RuntimeError(`Process env cannot be falsy.`); + } + + const { latestSemVerTag } = await getLatestSemVerGitTagV1({ + // We have to exclude "v2.0.0-alpha-prerelease" because it was not named + // according to the specs and is considered newer by the parser than + // alpha.1 but we actually issued alpha.1 later + excludedTags: ["v2.0.0-alpha-prerelease"], + omitFetch: false, + }); + + const optDescTargetVersion = + "The version to bump to, such as 1.0.0 or 2.0.0-alpha.1, etc. Defaults " + + "to the current latest version tag found in git where a version tag is " + + "defined as anything **starting with** the character v and then " + + "containing 3 numbers that are separated by dots"; + + const parsedCfg = await yargs(hideBin(argv)) + .env("CACTI_") + .option("target-version", { + alias: "v", + type: "string", + description: optDescTargetVersion, + defaultDescription: "Defaults to the latest release git tag (vX.Y.Z.*", + default: latestSemVerTag, + }).argv; + + // These explicit casts are safe because we provided the coercion functions + // for both parameters. + const targetVersion = (await parsedCfg.targetVersion) as string; + + const req: IBumpOpenAPISpecDepVersionsV1Request = { + argv, + env, + targetVersion, + }; + + return req; +} + +function traversePojoRefs( + file: string, + newVersion: string, + pojo: unknown, + replacements: ISpecRefReplacementV1[], + propPartPaths: string[], +): ISpecRefReplacementV1[] { + if (!pojo || typeof pojo !== "object") { + throw new RuntimeError(`Expected "pojo" as a Plain Old Javascript Object`); + } + Object.entries(pojo).forEach(([key, oldVal]: [string, unknown]) => { + if (!oldVal) { + return; + } else if (typeof oldVal === "object") { + propPartPaths.push(key); + traversePojoRefs(file, newVersion, oldVal, replacements, propPartPaths); + propPartPaths.pop(); + } else if (key === "$ref") { + if (typeof oldVal !== "string") { + throw new RuntimeError(`Expected string value for $ref in ${file}`); + } + if (oldVal.startsWith("#")) { + // skip references that are local, e.g. pointint go a schema component + // within the same openapi.json specification file because these are + // not going to have a git tag in their URLs (because they aren't URLs) + return; + } + if (!hasKey(pojo, "$ref")) { + throw new RuntimeError(`Expected pojo to have a "$pref" property.`); + } + + const aUrl = tryParseUrl(oldVal); + const urlPathParts = aUrl.pathname.split("/"); + + let dirty = false; + + urlPathParts.forEach((x, idx) => { + if (isValidSemVer(x) && x !== newVersion) { + dirty = true; + urlPathParts[idx] = newVersion; + console.log(`${TAG} ${file} Swapping "${x}" to "${newVersion}"`); + } + }); + + if (dirty) { + aUrl.pathname = urlPathParts.join("/"); + const newValue = aUrl.toString(); + console.log(`${TAG} ${file} Swapping "${oldVal}" to "${newValue}"`); + pojo[key] = newValue; + const propertyPath = ".".concat(propPartPaths.join(".")); + replacements.push({ + newValue, + oldValue: oldVal, + propertyPath, + }); + } + } + }); + return replacements; +} + +async function bumpOpenApiSpecDepVersionsOneFile( + filePathAbs: string, + filePathRel: string, + newVersion: string, +): Promise { + const openApiJson: OpenAPIV3_1.Document = await fs.readJSON(filePathAbs); + if (!openApiJson) { + throw new RuntimeError(`Expected ${filePathRel} to be truthy.`); + } + if (typeof openApiJson !== "object") { + throw new RuntimeError(`Expected ${filePathRel} to be an object`); + } + if (!openApiJson.info) { + openApiJson.info = { title: filePathRel, version: "0.0.0" }; + } + + const replacements = traversePojoRefs( + filePathRel, + newVersion, + openApiJson, + [], + [], + ); + + if (openApiJson.info.version !== newVersion) { + const oldVersion = openApiJson.info.version; + openApiJson.info.version = newVersion; + + console.log(`${TAG} Bumped to ${newVersion} in ${filePathRel}`); + + replacements.push({ + newValue: newVersion, + oldValue: oldVersion, + propertyPath: ".info.version", + }); + } + + // We have to format the JSON string first in order to make it consistent + // with the input that the CLI invocations of prettier receive, otherwise + // the end result of the library call here and the CLI call there can vary. + const specAsJsonString = JSON.stringify(openApiJson, null, 2); + + // Format the updated JSON object + const prettierCfg = await prettier.resolveConfig(".prettierrc.js"); + if (!prettierCfg) { + throw new RuntimeError(`Could not locate .prettierrc.js in project dir`); + } + const prettierOpts = { ...prettierCfg, parser: "json" }; + const prettyJson = prettier.format(specAsJsonString, prettierOpts); + + if (replacements.length > 0) { + console.log(`${TAG} writing changes to disk or ${filePathRel}`); + await fs.writeFile(filePathAbs, prettyJson); + } + return replacements; +} + +function tryParseUrl(x: unknown): URL { + if (typeof x !== "string") { + throw new RuntimeError(`${TAG} tryParseUrl() expected string input.`); + } + try { + return new URL(x); + } catch (ex) { + console.error(`${TAG} parsing failed for ${x}`, ex); + let innerEx; + if (ex instanceof Error || typeof ex === "string") { + innerEx = ex; + } else { + innerEx = fastSafeStringify(ex); + } + throw new RuntimeError(`${TAG} parsing failed for ${x}`, innerEx); + } +} + +export async function bumpOpenApiSpecDepVersions( + req: IBumpOpenAPISpecDepVersionsV1Request, +): Promise { + const __filename = fileURLToPath(import.meta.url); + const __dirname = path.dirname(__filename); + const SCRIPT_DIR = __dirname; + const PROJECT_DIR = path.join(SCRIPT_DIR, "../"); + console.log(`${TAG} SCRIPT_DIR: ${SCRIPT_DIR}`); + console.log(`${TAG} PROJECT_DIR: ${PROJECT_DIR}`); + + if (!req) { + throw new RuntimeError(`req parameter cannot be falsy.`); + } + if (!req.argv) { + throw new RuntimeError(`req.argv cannot be falsy.`); + } + if (!req.env) { + throw new RuntimeError(`req.env cannot be falsy.`); + } + + const globbyOpts: GlobbyOptions = { + cwd: PROJECT_DIR, + ignore: ["**/node_modules"], + }; + + const DEFAULT_GLOB = "**/src/main/json/openapi.json"; + + const oasPaths = await globby(DEFAULT_GLOB, globbyOpts); + + console.log(`${TAG} Looking up openapi.json spec files: ${DEFAULT_GLOB}`); + console.log(`${TAG} Detected ${oasPaths.length} openapi.json spec files`); + console.log(`${TAG} Expected Target Version: ${req.targetVersion}`); + console.log(`${TAG} File paths found:`, JSON.stringify(oasPaths, null, 4)); + + let replacementCountTotal = 0; + const specFileReportPromises = oasPaths.map(async (pathRel) => { + const filePathAbs = path.join(PROJECT_DIR, pathRel); + + const replacements = await bumpOpenApiSpecDepVersionsOneFile( + filePathAbs, + pathRel, + req.targetVersion, + ); + + const specFileReport: ISpecFileReportV1 = { + replacementCount: replacements.length, + replacements, + specFilePath: pathRel, + }; + + replacementCountTotal += specFileReport.replacementCount; + + return specFileReport; + }); + + const specFileReports = await Promise.all(specFileReportPromises); + const report = { + replacementCountTotal, + specFilePaths: oasPaths, + specFileReports, + }; + + const reportJson = JSON.stringify(report, null, 4); + + const rootDistDirPath = path.join(PROJECT_DIR, "./build/"); + await fs.mkdirp(rootDistDirPath); + + const dateAndTime = new Date().toJSON().slice(0, 24).replaceAll(":", "-"); + const filename = `cacti_bump-openapi-spec-dep-versions_${dateAndTime}.json`; + const specFileReportPathAbs = path.join(PROJECT_DIR, "./build/", filename); + + console.log(`${TAG} Total number of replacements: ${replacementCountTotal}`); + console.log(`${TAG} Saving final report to: ${specFileReportPathAbs}`); + await fs.writeFile(specFileReportPathAbs, reportJson); + + return report; +} diff --git a/tools/get-latest-sem-ver-git-tag.ts b/tools/get-latest-sem-ver-git-tag.ts new file mode 100644 index 0000000000..9d3676c841 --- /dev/null +++ b/tools/get-latest-sem-ver-git-tag.ts @@ -0,0 +1,67 @@ +import path from "path"; +import { fileURLToPath } from "url" +import { simpleGit, SimpleGit, SimpleGitOptions } from "simple-git"; +import { compareSemVer, isValidSemVer } from "semver-parser"; +import { RuntimeError } from "run-time-error"; + +const TAG = "[tools/get-latest-sem-ver-git-tag.ts]"; + +const nodePath = path.resolve(process.argv[1]); +const modulePath = path.resolve(fileURLToPath(import.meta.url)) +const isRunningDirectlyViaCLI = nodePath === modulePath + +if (isRunningDirectlyViaCLI) { + const excludedTags = process.argv.slice(2); + getLatestSemVerGitTagV1({ excludedTags, omitFetch: false }); +} + +export interface IGetLatestSemVerGitTagV1Request { + readonly excludedTags: string[]; + readonly omitFetch: boolean; +} + +export interface IGetLatestSemVerGitTagV1Response { + readonly latestSemVerTag: string; +} + +export async function getLatestSemVerGitTagV1(req: IGetLatestSemVerGitTagV1Request): Promise { + const options: Partial = { + baseDir: process.cwd(), + binary: "git", + maxConcurrentProcesses: 6, + trimmed: false, + }; + + // when setting all options in a single object + const git: SimpleGit = simpleGit(options); + + if (req.omitFetch) { + console.log(`${TAG} omitted git fetch`); + } else { + console.log(`${TAG} running git fetch...`); + await git.fetch(); + } + console.log(`${TAG} retrieving git tags...`); + const { all: allTags } = await git.tags(); + console.log(`${TAG} found ${allTags.length} git tags total.`); + + const excludedTags = new Set(req.excludedTags); + const filteredTags = allTags.filter((t) => !excludedTags.has(t)); + console.log(`${TAG} ${filteredTags.length} tags remain after exclusions.`); + + const semVerTags = filteredTags.filter((t) => isValidSemVer(t)); + console.log(`${TAG} found ${semVerTags.length} semver tags.`, semVerTags); + + + const sorted = semVerTags.sort(compareSemVer); + console.log(`${TAG} sorted ${semVerTags.length} git tags:`, semVerTags); + + const latestSemVerTag = sorted.pop(); + console.log(`${TAG} latestSemVerTag ${latestSemVerTag}`); + + if (!latestSemVerTag) { + throw new RuntimeError(`Could not find any semver git tags in the repo.`); + } else { + return { latestSemVerTag }; + } + } \ No newline at end of file diff --git a/tools/has-key.ts b/tools/has-key.ts new file mode 100644 index 0000000000..03131dba88 --- /dev/null +++ b/tools/has-key.ts @@ -0,0 +1,3 @@ +export function hasKey(obj: unknown, key: T): obj is { [key in T]: unknown } { + return Boolean(typeof obj === 'object' && obj && key in obj); +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index da90b0da37..d2285a8f9c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4819,6 +4819,18 @@ resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796" integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg== +"@kwsites/file-exists@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@kwsites/file-exists/-/file-exists-1.1.1.tgz#ad1efcac13e1987d8dbaf235ef3be5b0d96faa99" + integrity sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw== + dependencies: + debug "^4.1.1" + +"@kwsites/promise-deferred@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz#8ace5259254426ccef57f3175bc64ed7095ed919" + integrity sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw== + "@lazyledger/protobuf3-solidity-lib@^0.6.0": version "0.6.0" resolved "https://registry.yarnpkg.com/@lazyledger/protobuf3-solidity-lib/-/protobuf3-solidity-lib-0.6.0.tgz#226e82d23e8020e8016995a538f5f4aea3a4ce6a" @@ -7336,6 +7348,13 @@ resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129" integrity sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw== +"@types/yargs@17.0.24": + version "17.0.24" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" + integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== + dependencies: + "@types/yargs-parser" "*" + "@types/yargs@^13.0.0": version "13.0.12" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.12.tgz#d895a88c703b78af0465a9de88aa92c61430b092" @@ -12775,7 +12794,6 @@ driftless@^2.0.3: "ds-test@https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0": version "1.0.0" - uid e282159d5170298eb2455a6c05280ab5a73a4ef0 resolved "https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0" duplexer3@^0.1.4: @@ -15303,7 +15321,6 @@ forever-agent@~0.6.1: "forge-std@https://github.com/foundry-rs/forge-std.git#66bf4e2c92cf507531599845e8d5a08cc2e3b5bb": version "1.5.6" - uid "66bf4e2c92cf507531599845e8d5a08cc2e3b5bb" resolved "https://github.com/foundry-rs/forge-std.git#66bf4e2c92cf507531599845e8d5a08cc2e3b5bb" form-data-encoder@1.7.1: @@ -23513,6 +23530,11 @@ open@^7.0.0, open@^7.4.2: is-docker "^2.0.0" is-wsl "^2.1.1" +openapi-types@12.1.3: + version "12.1.3" + resolved "https://registry.yarnpkg.com/openapi-types/-/openapi-types-12.1.3.tgz#471995eb26c4b97b7bd356aacf7b91b73e777dd3" + integrity sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw== + openapi-types@7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/openapi-types/-/openapi-types-7.0.1.tgz#966bcacfd14119fa12000dbc9d588bfd8df2e4d1" @@ -27072,6 +27094,11 @@ semver-dsl@^1.0.1: dependencies: semver "^5.3.0" +semver-parser@4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/semver-parser/-/semver-parser-4.1.4.tgz#152c172b9df80a5b826c66fb47080656c691f5e3" + integrity sha512-U0IqwT7n99QS5/L8erhYGXBiiZH4M8t6YIlUuloY+mZpXkQOmH0V7Xf5oMytTpasjCjJCbrfysK01fIRbyDyrQ== + "semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" @@ -27473,6 +27500,15 @@ simple-get@^4.0.0: once "^1.3.1" simple-concat "^1.0.0" +simple-git@3.19.1: + version "3.19.1" + resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-3.19.1.tgz#ff9c021961a3d876a1b115b1893bed9a28855d30" + integrity sha512-Ck+rcjVaE1HotraRAS8u/+xgTvToTuoMkT9/l9lvuP5jftwnYUp6DwuJzsKErHgfyRk8IB8pqGHWEbM3tLgV1w== + dependencies: + "@kwsites/file-exists" "^1.1.1" + "@kwsites/promise-deferred" "^1.1.1" + debug "^4.3.4" + simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" @@ -32946,6 +32982,19 @@ yargs@17.5.1, yargs@^17.3.1: y18n "^5.0.5" yargs-parser "^21.0.0" +yargs@17.7.2, yargs@^17.7.2: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + 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" + yargs@^13.3.0: version "13.3.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" @@ -33018,19 +33067,6 @@ yargs@^17.7.1: y18n "^5.0.5" yargs-parser "^21.1.1" -yargs@^17.7.2: - version "17.7.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" - integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== - 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" - yargs@^3.10.0, yargs@^3.19.0: version "3.32.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995"