From 1416c9a99f45aca42b38ad4cf5dcbe741985adb5 Mon Sep 17 00:00:00 2001 From: Rogerio Angeliski Date: Fri, 26 Mar 2021 22:58:08 -0300 Subject: [PATCH 1/2] feat(gem): add canary hook --- plugins/gem/__tests__/gem.test.ts | 72 +++++++++++++++++++ plugins/gem/package.json | 3 + plugins/gem/src/index.ts | 111 ++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+) diff --git a/plugins/gem/__tests__/gem.test.ts b/plugins/gem/__tests__/gem.test.ts index aaa4247ac..91e739081 100644 --- a/plugins/gem/__tests__/gem.test.ts +++ b/plugins/gem/__tests__/gem.test.ts @@ -2,6 +2,7 @@ import glob from "fast-glob"; import { makeHooks } from "@auto-it/core/dist/utils/make-hooks"; import { dummyLog } from "@auto-it/core/dist/utils/logger"; import { execSync } from "child_process"; +import { when } from 'jest-when'; import * as utils from "../src/utils"; import Gem from "../src"; @@ -265,6 +266,10 @@ describe("Gem Plugin", () => { }); describe("publish", () => { + beforeEach(() => { + execSpy.mockClear(); + }); + test("uses bundler + rake as default publishing method", async () => { globSpy.mockReturnValueOnce(["test.gemspec"]); readFile.mockReturnValue(endent` @@ -303,4 +308,71 @@ describe("Gem Plugin", () => { }); }); }); + + describe("canary", () => { + beforeEach(() => { + execSpy.mockClear(); + }); + test("uses (bundler + rake + gem push) as default publishing method", async () => { + globSpy.mockReturnValue(["test.gemspec"]); + readFile.mockReturnValue(endent` + Gem::Specification.new do |spec| + spec.name = "test" + spec.version = "0.1.0" + end + `); + + const canaryIdentifier = '-canary-x' + when(execSpy).calledWith("bundle", ["exec", "rake", "build"]) + .mockReturnValue(`test 0.2.0.pre${canaryIdentifier} built to pkg/test-0.2.0.pre${canaryIdentifier.replace('-','.')}.gem.`); + + const plugin = new Gem(); + const hooks = makeHooks(); + + plugin.apply({ hooks, logger } as any); + + const result = await hooks.canary + .promise({ bump: SEMVER.minor, canaryIdentifier: "-canary-x", dryRun: false, quiet: false }); + + expect(result.newVersion).toBe(`0.2.0.pre${canaryIdentifier.replace('-','.')}`) + expect(result.details).toBe(endent` + :sparkles: Test out this PR via: + + \`\`\`bash + gem test, 0.2.0.pre${canaryIdentifier.replace('-','.')} + or + gem install test -v 0.2.0.pre${canaryIdentifier.replace('-','.')} + \`\`\` + `) + + expect(execSpy).toHaveBeenCalledWith("bundle", ["exec", "rake", "build"]); + expect(execSpy).toHaveBeenCalledWith("gem", ["push", "pkg/test-0.2.0.pre.canary-x.gem"]); + }); + + test("dry-run not release", async () => { + globSpy.mockReturnValue(["test.gemspec"]); + readFile.mockReturnValue(endent` + Gem::Specification.new do |spec| + spec.name = "test" + spec.version = "0.1.0" + end + `); + + const canaryIdentifier = '-canary-x' + when(execSpy).calledWith("bundle", ["exec", "rake", "build"]) + .mockReturnValue(`test 0.2.0.pre${canaryIdentifier} built to pkg/test-0.2.0.pre${canaryIdentifier.replace('-','.')}.gem.`); + + const plugin = new Gem(); + const hooks = makeHooks(); + + plugin.apply({ hooks, logger } as any); + + await hooks.canary + .promise({ bump: SEMVER.minor, canaryIdentifier: "-canary-x", dryRun: true, quiet: false }); + + expect(execSpy).not.toHaveBeenCalledWith("bundle", ["exec", "rake", "build"]); + expect(execSpy).not.toHaveBeenCalledWith("gem", ["push", "pkg/test-0.2.0.pre.canary-x.gem"]); + }); + + }); }); diff --git a/plugins/gem/package.json b/plugins/gem/package.json index 96ec569f5..7a7c5ed3b 100644 --- a/plugins/gem/package.json +++ b/plugins/gem/package.json @@ -45,5 +45,8 @@ "parse-github-url": "1.0.2", "semver": "^7.0.0", "tslib": "2.1.0" + }, + "devDependencies": { + "jest-when": "^3.2.1" } } diff --git a/plugins/gem/src/index.ts b/plugins/gem/src/index.ts index bb97f3b97..37d79b30e 100644 --- a/plugins/gem/src/index.ts +++ b/plugins/gem/src/index.ts @@ -16,6 +16,9 @@ import envCi from "env-ci"; import { readFile, writeFile, mkdir } from "./utils"; const VERSION_REGEX = /\d+\.\d+\.\d+/; +const GEM_PKG_BUILD_REGEX = /(pkg.*)[^.]/; +const GEM_SPEC_NAME_REGEX = /name\s*=\s*["']([\S ]+)["']/; + const { isCi } = envCi(); const pluginOptions = t.partial({ @@ -120,6 +123,93 @@ export default class GemPlugin implements IPlugin { } ); + auto.hooks.canary.tapPromise( + this.name, + async ({ bump, canaryIdentifier, dryRun, quiet }) => { + if ( + isCi && + !fs.existsSync("~/.gem/credentials") && + process.env.RUBYGEMS_API_KEY + ) { + const home = process.env.HOME || "~"; + const gemDir = path.join(home, ".gem"); + + if (!fs.existsSync(gemDir)) { + auto.logger.verbose.info(`Creating ${gemDir} directory`); + await mkdir(gemDir); + } + + const credentials = path.join(gemDir, "credentials"); + + await writeFile( + credentials, + endent` + --- + :rubygems_api_key: ${process.env.RUBYGEMS_API_KEY} + + ` + ); + auto.logger.verbose.success(`Wrote ${credentials}`); + + execSync(`chmod 0600 ${credentials}`, { + stdio: "inherit", + }); + } + + const [version, versionFile] = await this.getVersion(auto); + const newTag = inc(version, bump as ReleaseType); + + if (!newTag) { + throw new Error( + `The version "${version}" parsed from your version file "${versionFile}" was invalid and could not be incremented. Please fix this!` + ); + } + + const canaryVersion = `${newTag}.pre${canaryIdentifier.replace('-','.')}` + + if (dryRun) { + if (quiet) { + console.log(canaryVersion); + } else { + auto.logger.log.info(`Would have published: ${canaryVersion}`); + } + + return; + } + + + const content = await readFile(versionFile, { encoding: "utf8" }); + await writeFile(versionFile, content.replace(version, canaryVersion)); + + /** Commit the new version. we wait because "rake build" changes the lock file */ + /** we don't push that version, is just to clean the stage */ + const commitVersion = async () => + execPromise("git", [ + "commit", + "-am", + `"update version: ${canaryVersion} [skip ci]"`, + "--no-verify", + ]); + + + auto.logger.verbose.info("Running default release command"); + const buildResult = await execPromise("bundle", ["exec", "rake", "build"]); + const gemPath = GEM_PKG_BUILD_REGEX.exec(buildResult)?.[0] + await commitVersion(); + // will push the canary gem + await execPromise("gem", ["push", `${gemPath}`]); + + auto.logger.verbose.info("Successfully published canary version"); + + const name = await this.loadGemName(); + + return { + newVersion: canaryVersion, + details: this.makeInstallDetails(name, canaryVersion), + }; + + }); + auto.hooks.publish.tapPromise(this.name, async () => { if ( isCi && @@ -176,6 +266,27 @@ export default class GemPlugin implements IPlugin { }); } + /** create the installation details */ + private makeInstallDetails(name: string | undefined, canaryVersion: string) { + return [ + ":sparkles: Test out this PR via:\n", + "```bash", + `gem ${name}, ${canaryVersion}`, + "or", + `gem install ${name} -v ${canaryVersion}`, + "```", + ].join("\n"); + } + + /** loads the gem name from .gemspec */ + private async loadGemName() { + const gemspec = glob.sync("*.gemspec")[0]; + const content = await readFile(gemspec, { encoding: "utf8" }); + + return content.match(GEM_SPEC_NAME_REGEX)?.[1]; + } + + /** Get the current version of the gem and where it was found */ private async getVersion(auto: Auto) { let content = await readFile(this.gemspec, { encoding: "utf8" }); From d8ea7bb58a708e884d88f3c1e18efb41f59449b0 Mon Sep 17 00:00:00 2001 From: Rogerio Angeliski Date: Tue, 30 Mar 2021 08:56:31 -0300 Subject: [PATCH 2/2] chore: refactored gem package to join useful methods --- plugins/gem/src/index.ts | 138 +++++++++++-------------- yarn.lock | 216 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 270 insertions(+), 84 deletions(-) diff --git a/plugins/gem/src/index.ts b/plugins/gem/src/index.ts index 37d79b30e..773c2f0f4 100644 --- a/plugins/gem/src/index.ts +++ b/plugins/gem/src/index.ts @@ -99,8 +99,7 @@ export default class GemPlugin implements IPlugin { auto.hooks.version.tapPromise( this.name, async ({ bump, dryRun, quiet }) => { - const [version, versionFile] = await this.getVersion(auto); - const newTag = inc(version, bump as ReleaseType); + const [version, newTag, versionFile] = await this.getNewVersion(auto, bump as ReleaseType) if (dryRun && newTag) { if (quiet) { @@ -112,58 +111,16 @@ export default class GemPlugin implements IPlugin { return; } - if (!newTag) { - throw new Error( - `The version "${version}" parsed from your version file "${versionFile}" was invalid and could not be incremented. Please fix this!` - ); - } - - const content = await readFile(versionFile, { encoding: "utf8" }); - await writeFile(versionFile, content.replace(version, newTag)); + await this.writeNewVersion(version, newTag, versionFile) } ); auto.hooks.canary.tapPromise( this.name, async ({ bump, canaryIdentifier, dryRun, quiet }) => { - if ( - isCi && - !fs.existsSync("~/.gem/credentials") && - process.env.RUBYGEMS_API_KEY - ) { - const home = process.env.HOME || "~"; - const gemDir = path.join(home, ".gem"); - - if (!fs.existsSync(gemDir)) { - auto.logger.verbose.info(`Creating ${gemDir} directory`); - await mkdir(gemDir); - } + await this.writeCredentials(auto) - const credentials = path.join(gemDir, "credentials"); - - await writeFile( - credentials, - endent` - --- - :rubygems_api_key: ${process.env.RUBYGEMS_API_KEY} - - ` - ); - auto.logger.verbose.success(`Wrote ${credentials}`); - - execSync(`chmod 0600 ${credentials}`, { - stdio: "inherit", - }); - } - - const [version, versionFile] = await this.getVersion(auto); - const newTag = inc(version, bump as ReleaseType); - - if (!newTag) { - throw new Error( - `The version "${version}" parsed from your version file "${versionFile}" was invalid and could not be incremented. Please fix this!` - ); - } + const [version, newTag, versionFile] = await this.getNewVersion(auto, bump as ReleaseType) const canaryVersion = `${newTag}.pre${canaryIdentifier.replace('-','.')}` @@ -177,9 +134,7 @@ export default class GemPlugin implements IPlugin { return; } - - const content = await readFile(versionFile, { encoding: "utf8" }); - await writeFile(versionFile, content.replace(version, canaryVersion)); + await this.writeNewVersion(version, canaryVersion, versionFile) /** Commit the new version. we wait because "rake build" changes the lock file */ /** we don't push that version, is just to clean the stage */ @@ -211,35 +166,7 @@ export default class GemPlugin implements IPlugin { }); auto.hooks.publish.tapPromise(this.name, async () => { - if ( - isCi && - !fs.existsSync("~/.gem/credentials") && - process.env.RUBYGEMS_API_KEY - ) { - const home = process.env.HOME || "~"; - const gemDir = path.join(home, ".gem"); - - if (!fs.existsSync(gemDir)) { - auto.logger.verbose.info(`Creating ${gemDir} directory`); - await mkdir(gemDir); - } - - const credentials = path.join(gemDir, "credentials"); - - await writeFile( - credentials, - endent` - --- - :rubygems_api_key: ${process.env.RUBYGEMS_API_KEY} - - ` - ); - auto.logger.verbose.success(`Wrote ${credentials}`); - - execSync(`chmod 0600 ${credentials}`, { - stdio: "inherit", - }); - } + await this.writeCredentials(auto) const [version] = await this.getVersion(auto); @@ -286,6 +213,59 @@ export default class GemPlugin implements IPlugin { return content.match(GEM_SPEC_NAME_REGEX)?.[1]; } + /** write the credentials file when necessary */ + private async writeCredentials(auto: Auto) { + if ( + isCi && + !fs.existsSync("~/.gem/credentials") && + process.env.RUBYGEMS_API_KEY + ) { + const home = process.env.HOME || "~"; + const gemDir = path.join(home, ".gem"); + + if (!fs.existsSync(gemDir)) { + auto.logger.verbose.info(`Creating ${gemDir} directory`); + await mkdir(gemDir); + } + + const credentials = path.join(gemDir, "credentials"); + + await writeFile( + credentials, + endent` + --- + :rubygems_api_key: ${process.env.RUBYGEMS_API_KEY} + + ` + ); + auto.logger.verbose.success(`Wrote ${credentials}`); + + execSync(`chmod 0600 ${credentials}`, { + stdio: "inherit", + }); + } + } + + /** resolves the version to a new one */ + private async getNewVersion(auto: Auto, bump: ReleaseType) { + const [version, versionFile] = await this.getVersion(auto); + const newTag = inc(version, bump); + + if (!newTag) { + throw new Error( + `The version "${version}" parsed from your version file "${versionFile}" was invalid and could not be incremented. Please fix this!` + ); + } + + return [version, newTag, versionFile]; + } + + /** write the version in the file */ + private async writeNewVersion(version: string, newVersion: string, versionFile: string){ + const content = await readFile(versionFile, { encoding: "utf8" }); + await writeFile(versionFile, content.replace(version, newVersion)); + + } /** Get the current version of the gem and where it was found */ private async getVersion(auto: Auto) { diff --git a/yarn.lock b/yarn.lock index 92513eb87..5cf7f1064 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1589,6 +1589,15 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== +"@jest/console@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" + integrity sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ== + dependencies: + "@jest/source-map" "^24.9.0" + chalk "^2.0.1" + slash "^2.0.0" + "@jest/console@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.6.2.tgz#4e04bc464014358b03ab4937805ee36a0aeb98f2" @@ -1698,6 +1707,15 @@ optionalDependencies: node-notifier "^8.0.0" +"@jest/source-map@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" + integrity sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.1.15" + source-map "^0.6.0" + "@jest/source-map@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-26.6.2.tgz#29af5e1e2e324cafccc936f218309f54ab69d535" @@ -1707,6 +1725,15 @@ graceful-fs "^4.2.4" source-map "^0.6.0" +"@jest/test-result@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" + integrity sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA== + dependencies: + "@jest/console" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/istanbul-lib-coverage" "^2.0.0" + "@jest/test-result@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.2.tgz#55da58b62df134576cc95476efa5f7949e3f5f18" @@ -1749,6 +1776,15 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" +"@jest/types@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" + integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^13.0.0" + "@jest/types@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" @@ -3094,6 +3130,14 @@ dependencies: "@types/istanbul-lib-coverage" "*" +"@types/istanbul-reports@^1.1.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz#e875cc689e47bce549ec81f3df5e6f6f11cfaeb2" + integrity sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw== + dependencies: + "@types/istanbul-lib-coverage" "*" + "@types/istanbul-lib-report" "*" + "@types/istanbul-reports@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz#508b13aa344fa4976234e75dddcc34925737d821" @@ -3265,6 +3309,11 @@ resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== +"@types/stack-utils@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" + integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== + "@types/stack-utils@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" @@ -3343,6 +3392,13 @@ resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.0.0.tgz#453743c5bbf9f1bed61d959baab5b06be029b2d0" integrity sha512-wBlsw+8n21e6eTd4yVv8YD/E3xq0O6nNnJIquutAsFGE7EyMKz7W6RNT6BRu1SmdgmlCZ9tb0X+j+D6HGr8pZw== +"@types/yargs@^13.0.0": + version "13.0.11" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.11.tgz#def2f0c93e4bdf2c61d7e34899b17e34be28d3b1" + integrity sha512-NRqD6T4gktUrDi1o1wLH3EKC1o2caCr7/wR87ODcbVITQF106OM3sFN92ysZ++wqelOd1CTzatnOBRDYYG6wGQ== + dependencies: + "@types/yargs-parser" "*" + "@types/yargs@^15.0.0": version "15.0.1" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.1.tgz#9266a9d7be68cfcc982568211085a49a277f7c96" @@ -3820,7 +3876,7 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= -ansi-regex@^4.1.0: +ansi-regex@^4.0.0, ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== @@ -4597,6 +4653,16 @@ builtins@^1.0.3: resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= +bunyan@^1.8.12: + version "1.8.15" + resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.15.tgz#8ce34ca908a17d0776576ca1b2f6cbd916e93b46" + integrity sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig== + optionalDependencies: + dtrace-provider "~0.8" + moment "^2.19.3" + mv "~2" + safe-json-stringify "~1" + byline@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" @@ -4829,7 +4895,7 @@ ccount@^1.0.0, ccount@^1.0.3: resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.5.tgz#ac82a944905a65ce204eb03023157edf29425c17" integrity sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw== -chalk@2.4.2, chalk@^2.0.0, chalk@^2.3.1, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2: +chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.1, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -6238,6 +6304,11 @@ didyoumean@^1.2.1: resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.1.tgz#e92edfdada6537d484d73c0172fd1eba0c4976ff" integrity sha1-6S7f2tplN9SE1zwBcv0eugxJdv8= +diff-sequences@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" + integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== + diff-sequences@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" @@ -6399,6 +6470,13 @@ dotenv@*, dotenv@^8.0.0, dotenv@^8.2.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== +dtrace-provider@~0.8: + version "0.8.8" + resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.8.tgz#2996d5490c37e1347be263b423ed7b297fb0d97e" + integrity sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg== + dependencies: + nan "^2.14.0" + duplexer@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" @@ -7024,6 +7102,18 @@ expand-template@^2.0.3: resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== +expect@^24.8.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" + integrity sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q== + dependencies: + "@jest/types" "^24.9.0" + ansi-styles "^3.2.0" + jest-get-type "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-regex-util "^24.9.0" + expect@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/expect/-/expect-26.6.2.tgz#c6b996bf26bf3fe18b67b2d0f51fc981ba934417" @@ -7802,6 +7892,17 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== +glob@^6.0.1: + version "6.0.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" + integrity sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^7.0.0, glob@^7.0.3, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.5, glob@^7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" @@ -9216,6 +9317,16 @@ jest-config@^26.6.3: micromatch "^4.0.2" pretty-format "^26.6.2" +jest-diff@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" + integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== + dependencies: + chalk "^2.0.1" + diff-sequences "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + jest-diff@^26.0.0, jest-diff@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" @@ -9269,6 +9380,11 @@ jest-environment-node@^26.6.2: jest-mock "^26.6.2" jest-util "^26.6.2" +jest-get-type@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" + integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== + jest-get-type@^26.3.0: version "26.3.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" @@ -9327,6 +9443,16 @@ jest-leak-detector@^26.6.2: jest-get-type "^26.3.0" pretty-format "^26.6.2" +jest-matcher-utils@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" + integrity sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA== + dependencies: + chalk "^2.0.1" + jest-diff "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + jest-matcher-utils@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz#8e6fd6e863c8b2d31ac6472eeb237bc595e53e7a" @@ -9337,6 +9463,20 @@ jest-matcher-utils@^26.6.2: jest-get-type "^26.3.0" pretty-format "^26.6.2" +jest-message-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" + integrity sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/stack-utils" "^1.0.1" + chalk "^2.0.1" + micromatch "^3.1.10" + slash "^2.0.0" + stack-utils "^1.0.1" + jest-message-util@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07" @@ -9365,6 +9505,11 @@ jest-pnp-resolver@^1.2.2: resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== +jest-regex-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" + integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== + jest-regex-util@^26.0.0: version "26.0.0" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" @@ -9536,6 +9681,14 @@ jest-watcher@^26.6.2: jest-util "^26.6.2" string-length "^4.0.1" +jest-when@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/jest-when/-/jest-when-3.2.1.tgz#69b58ff641a399a0f2db5bfee6d8dd40cd065eb8" + integrity sha512-7OuFR5f2AdDPoRs/uk99dEWI+Isc2SFThugPjVUZgLLhWqeGr64rCFuuYcxVXQKwBmF3GG/MCS6zcKR9H86qiw== + dependencies: + bunyan "^1.8.12" + expect "^24.8.0" + jest-worker@24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" @@ -10565,7 +10718,7 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -minimatch@3.0.4, minimatch@^3.0.3, minimatch@^3.0.4: +"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -10650,7 +10803,7 @@ mkdirp@*, mkdirp@1.x: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3: +mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -10677,6 +10830,11 @@ module-alias@^2.2.2: resolved "https://registry.yarnpkg.com/module-alias/-/module-alias-2.2.2.tgz#151cdcecc24e25739ff0aa6e51e1c5716974c0e0" integrity sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q== +moment@^2.19.3: + version "2.29.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" + integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -10732,6 +10890,15 @@ mute-stream@0.0.8, mute-stream@~0.0.4: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== +mv@~2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2" + integrity sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI= + dependencies: + mkdirp "~0.5.1" + ncp "~2.0.0" + rimraf "~2.4.0" + mz@^2.5.0: version "2.7.0" resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" @@ -10746,6 +10913,11 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== +nan@^2.14.0: + version "2.14.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" + integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== + nano-css@^5.2.1: version "5.3.0" resolved "https://registry.yarnpkg.com/nano-css/-/nano-css-5.3.0.tgz#9d3cd29788d48b6a07f52aa4aec7cf4da427b6b5" @@ -10799,6 +10971,11 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +ncp@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" + integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= + needle@^2.2.1: version "2.4.0" resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" @@ -12338,6 +12515,16 @@ pretty-bytes@^5.3.0, pretty-bytes@^5.4.1, pretty-bytes@^5.5.0: resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.5.0.tgz#0cecda50a74a941589498011cf23275aa82b339e" integrity sha512-p+T744ZyjjiaFlMUZZv6YPC5JrkNj8maRmPaQCWFJFplUAzpIUTRaTcS+7wmZtUoFXHtESJb23ISliaWyz3SHA== +pretty-format@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" + integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== + dependencies: + "@jest/types" "^24.9.0" + ansi-regex "^4.0.0" + ansi-styles "^3.2.0" + react-is "^16.8.4" + pretty-format@^26.0.0, pretty-format@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" @@ -12676,7 +12863,7 @@ react-dom@16.13.0: prop-types "^15.6.2" scheduler "^0.19.0" -react-is@16.13.1: +react-is@16.13.1, react-is@^16.8.4: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -13436,6 +13623,13 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" +rimraf@~2.4.0: + version "2.4.5" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da" + integrity sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto= + dependencies: + glob "^6.0.1" + ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -13553,6 +13747,11 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-json-stringify@~1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd" + integrity sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg== + safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -14227,6 +14426,13 @@ stack-generator@^2.0.5: dependencies: stackframe "^1.1.1" +stack-utils@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.4.tgz#4b600971dcfc6aed0cbdf2a8268177cc916c87c8" + integrity sha512-IPDJfugEGbfizBwBZRZ3xpccMdRyP5lqsBWXGQWimVjua/ccLCeMOAVjlc1R7LxFjo5sEDhyNIXd8mo/AiDS9w== + dependencies: + escape-string-regexp "^2.0.0" + stack-utils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.2.tgz#5cf48b4557becb4638d0bc4f21d23f5d19586593"