diff --git a/README.md b/README.md index dae8abe0..c81d92f7 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,10 @@ This will trigger on all pushes and automatically update any pull requests, if c For more information on customising event triggers, see [Github's documentation](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/events-that-trigger-workflows#push-event-push). +The following events are supported: +* push +* pull_request +* workflow_run ## Configuration The following configuration options are supported. To change any of these, simply specify it as an `env` value in your workflow file. @@ -101,10 +105,10 @@ Here's a screenshot: * There is [an open issue in the Github community forum](https://github.community/t5/GitHub-Actions/Triggering-a-new-workflow-from-another-workflow/td-p/31676) tracking this ## Coming soon -* Conflict handling * Rebase support * Label negation support * Token support in custom merge messages +* `schedule` event support ## Also see * [automerge](https://github.com/pascalgn/automerge-action/) for automatic merging of PRs diff --git a/package.json b/package.json index dd095551..d6af3ad5 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,10 @@ "@actions/core": "^1.2.6", "@actions/github": "^4.0.0", "@octokit/types": "^6.13.0", + "@octokit/webhooks": "^9.0.0", "@types/node": "^14.14.37", "@vercel/ncc": "^0.27.0", + "ttypescript": "^1.5.12", "typescript": "^4.2.4" }, "devDependencies": { @@ -33,16 +35,29 @@ "eslint-plugin-jest": "^24.3.5", "eslint-plugin-prettier": "^3.3.1", "jest": "^26.6.3", + "jest-ts-auto-mock": "^2.0.0", "nock": "^13.0.11", "prettier": "^2.2.1", + "ts-auto-mock": "^3.1.2", "ts-jest": "^26.5.4" }, "jest": { - "preset": "ts-jest", "clearMocks": true, "collectCoverage": true, "coverageDirectory": "coverage", "coverageProvider": "v8", - "testEnvironment": "node" + "globals": { + "ts-jest": { + "compiler": "ttypescript" + } + }, + "preset": "ts-jest", + "setupFiles": [ + "/test/config.ts" + ], + "testEnvironment": "node", + "transform": { + ".(ts|tsx)": "ts-jest" + } } } diff --git a/src/autoupdater.ts b/src/autoupdater.ts index 84caec72..8e82f586 100644 --- a/src/autoupdater.ts +++ b/src/autoupdater.ts @@ -2,32 +2,87 @@ import * as github from '@actions/github'; import { GitHub } from '@actions/github/lib/utils'; import * as ghCore from '@actions/core'; import * as octokit from '@octokit/types'; +import { + PullRequestEvent, + PushEvent, + Repository, + WebhookEvent, + WorkflowRunEvent, +} from '@octokit/webhooks-definitions/schema'; import { ConfigLoader } from './config-loader'; import { Endpoints } from '@octokit/types'; +type PullRequest = + | PullRequestResponse['data'] + | PullRequestEvent['pull_request']; type PullRequestResponse = Endpoints['GET /repos/{owner}/{repo}/pulls/{pull_number}']['response']; type MergeParameters = Endpoints['POST /repos/{owner}/{repo}/merges']['parameters']; export class AutoUpdater { - eventData: any; + // See https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads + eventData: WebhookEvent; config: ConfigLoader; octokit: InstanceType; - constructor( - config: ConfigLoader, - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - eventData: any, - ) { + constructor(config: ConfigLoader, eventData: WebhookEvent) { this.eventData = eventData; this.config = config; this.octokit = github.getOctokit(this.config.githubToken()); } async handlePush(): Promise { - const { ref, repository } = this.eventData; + const { ref, repository } = this.eventData as PushEvent; ghCore.info(`Handling push event on ref '${ref}'`); + return await this.pulls(ref, repository); + } + + async handlePullRequest(): Promise { + const { action, pull_request } = this.eventData as PullRequestEvent; + + ghCore.info(`Handling pull_request event triggered by action '${action}'`); + + const isUpdated = await this.update(pull_request); + if (isUpdated) { + ghCore.info( + 'Auto update complete, pull request branch was updated with changes from the base branch.', + ); + } else { + ghCore.info('Auto update complete, no changes were made.'); + } + + return isUpdated; + } + + async handleWorkflowRun(): Promise { + const { workflow_run: workflowRun, repository } = this + .eventData as WorkflowRunEvent; + const { head_branch: branch, event } = workflowRun; + + if (!['push', 'pull_request'].includes(event)) { + ghCore.error( + `workflow_run events triggered via ${event} workflows are not supported.`, + ); + return 0; + } + + // This may not be possible given the check above, but here for safety. + if (!branch) { + ghCore.warning('Event was not on a branch, skipping.'); + return 0; + } + + ghCore.info( + `Handling workflow_run event triggered by '${event}' on '${branch}'`, + ); + + // The `pull_request` event is handled the same way as `push` as we may + // get multiple PRs. + return await this.pulls(`refs/heads/${branch}`, repository); + } + + async pulls(ref: string, repository: Repository): Promise { if (!ref.startsWith('refs/heads/')) { ghCore.warning('Push event was not on a branch, skipping.'); return 0; @@ -37,7 +92,7 @@ export class AutoUpdater { let updated = 0; const paginatorOpts = this.octokit.pulls.list.endpoint.merge({ - owner: repository.owner.name, + owner: repository.owner.name || repository.owner.login, repo: repository.name, base: baseBranch, state: 'open', @@ -66,24 +121,7 @@ export class AutoUpdater { return updated; } - async handlePullRequest(): Promise { - const { action } = this.eventData; - - ghCore.info(`Handling pull_request event triggered by action '${action}'`); - - const isUpdated = await this.update(this.eventData.pull_request); - if (isUpdated) { - ghCore.info( - 'Auto update complete, pull request branch was updated with changes from the base branch.', - ); - } else { - ghCore.info('Auto update complete, no changes were made.'); - } - - return isUpdated; - } - - async update(pull: PullRequestResponse['data']): Promise { + async update(pull: PullRequest): Promise { const { ref } = pull.head; ghCore.info(`Evaluating pull request #${pull.number}...`); @@ -131,7 +169,7 @@ export class AutoUpdater { return true; } - async prNeedsUpdate(pull: PullRequestResponse['data']): Promise { + async prNeedsUpdate(pull: PullRequest): Promise { if (pull.merged === true) { ghCore.warning('Skipping pull request, already merged.'); return false; @@ -170,7 +208,7 @@ export class AutoUpdater { if (excludedLabels.length > 0) { for (const label of pull.labels) { if (label.name === undefined) { - ghCore.warning(`Label name is undefined, continuing.`); + ghCore.debug(`Label name is undefined, continuing.`); continue; } if (excludedLabels.includes(label.name)) { @@ -209,7 +247,7 @@ export class AutoUpdater { for (const label of pull.labels) { if (label.name === undefined) { - ghCore.warning(`Label name is undefined, continuing.`); + ghCore.debug(`Label name is undefined, continuing.`); continue; } diff --git a/src/router.ts b/src/router.ts index f22fd9c1..72a4fbaa 100644 --- a/src/router.ts +++ b/src/router.ts @@ -1,15 +1,11 @@ +import { WebhookEvent } from '@octokit/webhooks-definitions/schema'; import { AutoUpdater } from '../src/autoupdater'; import { ConfigLoader } from '../src/config-loader'; export class Router { - eventData: any; updater: AutoUpdater; - constructor( - config: ConfigLoader, - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - eventData: any, - ) { + constructor(config: ConfigLoader, eventData: WebhookEvent) { this.updater = new AutoUpdater(config, eventData); } @@ -24,9 +20,11 @@ export class Router { await this.updater.handlePullRequest(); } else if (eventName === 'push') { await this.updater.handlePush(); + } else if (eventName === 'workflow_run') { + await this.updater.handleWorkflowRun(); } else { throw new Error( - `Unknown event type '${eventName}', only 'push' and 'pull_request' are supported.`, + `Unknown event type '${eventName}', only 'push', 'pull_request' and 'workflow_run' are supported.`, ); } } diff --git a/test/autoupdate.test.ts b/test/autoupdate.test.ts index d4e8566b..eb1ae743 100644 --- a/test/autoupdate.test.ts +++ b/test/autoupdate.test.ts @@ -4,10 +4,17 @@ if ('GITHUB_TOKEN' in process.env) { delete process.env.GITHUB_TOKEN; } +import { createMock } from 'ts-auto-mock'; import nock from 'nock'; import config from '../src/config-loader'; import { AutoUpdater } from '../src/autoupdater'; import { Endpoints } from '@octokit/types'; +import { + PullRequestEvent, + PushEvent, + WebhookEvent, + WorkflowRunEvent, +} from '@octokit/webhooks-definitions/schema'; type PullRequestResponse = Endpoints['GET /repos/{owner}/{repo}/pulls/{pull_number}']['response']; @@ -18,20 +25,45 @@ beforeEach(() => { jest.spyOn(config, 'githubToken').mockImplementation(() => 'test-token'); }); +const emptyEvent = {} as WebhookEvent; const owner = 'chinthakagodawita'; const repo = 'not-a-real-repo'; const base = 'master'; const head = 'develop'; const branch = 'not-a-real-branch'; -const dummyEvent = { +const dummyPushEvent = createMock({ ref: `refs/heads/${branch}`, + repository: { + owner: { + login: owner, + }, + name: repo, + }, +}); +const dummyWorkflowRunPushEvent = createMock({ + workflow_run: { + event: 'push', + head_branch: branch, + }, repository: { owner: { name: owner, }, name: repo, }, -}; +}); +const dummyWorkflowRunPullRequestEvent = createMock({ + workflow_run: { + event: 'pull_request', + head_branch: branch, + }, + repository: { + owner: { + name: owner, + }, + name: repo, + }, +}); const invalidLabelPull = { number: 1, merged: false, @@ -93,7 +125,7 @@ describe('test `prNeedsUpdate`', () => { merged: true, }; - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const needsUpdate = await updater.prNeedsUpdate( (pull as unknown) as PullRequestResponse['data'], ); @@ -106,7 +138,7 @@ describe('test `prNeedsUpdate`', () => { state: 'closed', }; - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const needsUpdate = await updater.prNeedsUpdate( (pull as unknown) as PullRequestResponse['data'], ); @@ -121,7 +153,7 @@ describe('test `prNeedsUpdate`', () => { repo: null, }, }); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, {} as WebhookEvent); const needsUpdate = await updater.prNeedsUpdate( (pull as unknown) as PullRequestResponse['data'], ); @@ -135,7 +167,7 @@ describe('test `prNeedsUpdate`', () => { behind_by: 0, }); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const needsUpdate = await updater.prNeedsUpdate( (validPull as unknown) as PullRequestResponse['data'], ); @@ -154,7 +186,7 @@ describe('test `prNeedsUpdate`', () => { behind_by: 1, }); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const needsUpdate = await updater.prNeedsUpdate( (validPull as unknown) as PullRequestResponse['data'], ); @@ -176,7 +208,7 @@ describe('test `prNeedsUpdate`', () => { behind_by: 1, }); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const pull = clonePull(); pull.labels = [ { @@ -211,7 +243,7 @@ describe('test `prNeedsUpdate`', () => { behind_by: 1, }); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const needsUpdate = await updater.prNeedsUpdate( (validPull as unknown) as PullRequestResponse['data'], ); @@ -234,7 +266,7 @@ describe('test `prNeedsUpdate`', () => { behind_by: 1, }); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const pull = clonePull(); pull.labels = []; const needsUpdate = await updater.prNeedsUpdate(pull); @@ -257,7 +289,7 @@ describe('test `prNeedsUpdate`', () => { behind_by: 1, }); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const needsUpdate = await updater.prNeedsUpdate( (invalidLabelPull as unknown) as PullRequestResponse['data'], ); @@ -280,7 +312,7 @@ describe('test `prNeedsUpdate`', () => { behind_by: 1, }); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const needsUpdate = await updater.prNeedsUpdate( (invalidLabelPull as unknown) as PullRequestResponse['data'], ); @@ -303,7 +335,7 @@ describe('test `prNeedsUpdate`', () => { behind_by: 1, }); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const needsUpdate = await updater.prNeedsUpdate( (validPull as unknown) as PullRequestResponse['data'], ); @@ -326,7 +358,7 @@ describe('test `prNeedsUpdate`', () => { behind_by: 1, }); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const pull = clonePull(); pull.labels = [ { @@ -356,7 +388,7 @@ describe('test `prNeedsUpdate`', () => { protected: true, }); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const needsUpdate = await updater.prNeedsUpdate( (validPull as unknown) as PullRequestResponse['data'], ); @@ -384,7 +416,7 @@ describe('test `prNeedsUpdate`', () => { protected: false, }); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const needsUpdate = await updater.prNeedsUpdate( (validPull as unknown) as PullRequestResponse['data'], ); @@ -406,7 +438,7 @@ describe('test `prNeedsUpdate`', () => { behind_by: 1, }); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const needsUpdate = await updater.prNeedsUpdate( (validPull as unknown) as PullRequestResponse['data'], ); @@ -419,7 +451,7 @@ describe('test `prNeedsUpdate`', () => { }); describe('test `handlePush`', () => { - const cloneEvent = () => JSON.parse(JSON.stringify(dummyEvent)); + const cloneEvent = () => JSON.parse(JSON.stringify(dummyPushEvent)); test('push event on a non-branch', async () => { const event = cloneEvent(); @@ -436,7 +468,7 @@ describe('test `handlePush`', () => { }); test('push event on a branch without any PRs', async () => { - const updater = new AutoUpdater(config, dummyEvent); + const updater = new AutoUpdater(config, dummyPushEvent); const updateSpy = jest.spyOn(updater, 'update').mockResolvedValue(true); @@ -454,7 +486,7 @@ describe('test `handlePush`', () => { }); test('push event on a branch with PRs', async () => { - const updater = new AutoUpdater(config, dummyEvent); + const updater = new AutoUpdater(config, dummyPushEvent); const pullsMock = []; const expectedPulls = 5; @@ -481,11 +513,138 @@ describe('test `handlePush`', () => { }); }); +describe('test `handleWorkflowRun`', () => { + const cloneEvent = () => + JSON.parse(JSON.stringify(dummyWorkflowRunPushEvent)); + + test('workflow_run event by push event on a non-branch', async () => { + const event = cloneEvent(); + event.workflow_run.head_branch = ''; + + const updater = new AutoUpdater(config, event); + + const updateSpy = jest.spyOn(updater, 'update').mockResolvedValue(true); + + const updated = await updater.handleWorkflowRun(); + + expect(updated).toEqual(0); + expect(updateSpy).toHaveBeenCalledTimes(0); + }); + + test('workflow_run event by push event on a branch without any PRs', async () => { + const updater = new AutoUpdater(config, dummyWorkflowRunPushEvent); + + const updateSpy = jest.spyOn(updater, 'update').mockResolvedValue(true); + + const scope = nock('https://api.github.com:443') + .get( + `/repos/${owner}/${repo}/pulls?base=${branch}&state=open&sort=updated&direction=desc`, + ) + .reply(200, []); + + const updated = await updater.handleWorkflowRun(); + + expect(updated).toEqual(0); + expect(updateSpy).toHaveBeenCalledTimes(0); + expect(scope.isDone()).toEqual(true); + }); + + test('workflow_run event by push event on a branch with PRs', async () => { + const updater = new AutoUpdater(config, dummyWorkflowRunPushEvent); + + const pullsMock = []; + const expectedPulls = 5; + for (let i = 0; i < expectedPulls; i++) { + pullsMock.push({ + id: i, + number: i, + }); + } + + const updateSpy = jest.spyOn(updater, 'update').mockResolvedValue(true); + + const scope = nock('https://api.github.com:443') + .get( + `/repos/${owner}/${repo}/pulls?base=${branch}&state=open&sort=updated&direction=desc`, + ) + .reply(200, pullsMock); + + const updated = await updater.handleWorkflowRun(); + + expect(updated).toEqual(expectedPulls); + expect(updateSpy).toHaveBeenCalledTimes(expectedPulls); + expect(scope.isDone()).toEqual(true); + }); + + test('workflow_run event by pull_request event with an update triggered', async () => { + const updater = new AutoUpdater( + config, + createMock(dummyWorkflowRunPullRequestEvent), + ); + + const pullsMock = []; + const expectedPulls = 2; + for (let i = 0; i < expectedPulls; i++) { + pullsMock.push({ + id: i, + number: i, + }); + } + + const updateSpy = jest.spyOn(updater, 'update').mockResolvedValue(true); + + const scope = nock('https://api.github.com:443') + .get( + `/repos/${owner}/${repo}/pulls?base=${branch}&state=open&sort=updated&direction=desc`, + ) + .reply(200, pullsMock); + + const updated = await updater.handleWorkflowRun(); + + expect(updated).toEqual(expectedPulls); + expect(updateSpy).toHaveBeenCalledTimes(expectedPulls); + expect(scope.isDone()).toEqual(true); + }); + + test('workflow_run event by pull_request event without an update', async () => { + const updater = new AutoUpdater( + config, + createMock(dummyWorkflowRunPullRequestEvent), + ); + + const updateSpy = jest.spyOn(updater, 'update').mockResolvedValue(false); + + const scope = nock('https://api.github.com:443') + .get( + `/repos/${owner}/${repo}/pulls?base=${branch}&state=open&sort=updated&direction=desc`, + ) + .reply(200, []); + + const updated = await updater.handleWorkflowRun(); + + expect(updated).toEqual(0); + expect(updateSpy).toHaveBeenCalledTimes(0); + expect(scope.isDone()).toEqual(true); + }); + + test('workflow_run event with an unsupported event type', async () => { + const event = cloneEvent(); + event.workflow_run.event = 'pull_request_review'; + + const updater = new AutoUpdater(config, event); + + const updateSpy = jest.spyOn(updater, 'update').mockResolvedValue(true); + + const updated = await updater.handleWorkflowRun(); + + expect(updated).toEqual(0); + expect(updateSpy).toHaveBeenCalledTimes(0); + }); +}); + describe('test `handlePullRequest`', () => { test('pull request event with an update triggered', async () => { - const updater = new AutoUpdater(config, { - action: 'dummy-action', - }); + const updater = new AutoUpdater(config, createMock()); const updateSpy = jest.spyOn(updater, 'update').mockResolvedValue(true); const updated = await updater.handlePullRequest(); @@ -495,9 +654,7 @@ describe('test `handlePullRequest`', () => { }); test('pull request event without an update', async () => { - const updater = new AutoUpdater(config, { - action: 'dummy-action', - }); + const updater = new AutoUpdater(config, createMock()); const updateSpy = jest.spyOn(updater, 'update').mockResolvedValue(false); const updated = await updater.handlePullRequest(); @@ -509,7 +666,7 @@ describe('test `handlePullRequest`', () => { describe('test `update`', () => { test('when a pull request does not need an update', async () => { - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const updateSpy = jest .spyOn(updater, 'prNeedsUpdate') .mockResolvedValue(false); @@ -520,7 +677,7 @@ describe('test `update`', () => { test('dry run mode', async () => { (config.dryRun as jest.Mock).mockReturnValue(true); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const updateSpy = jest .spyOn(updater, 'prNeedsUpdate') .mockResolvedValue(true); @@ -535,7 +692,7 @@ describe('test `update`', () => { test('custom merge message', async () => { const mergeMsg = 'dummy-merge-msg'; (config.mergeMsg as jest.Mock).mockReturnValue(mergeMsg); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const updateSpy = jest .spyOn(updater, 'prNeedsUpdate') @@ -558,7 +715,7 @@ describe('test `update`', () => { test('merge with no message', async () => { (config.mergeMsg as jest.Mock).mockReturnValue(''); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const updateSpy = jest .spyOn(updater, 'prNeedsUpdate') @@ -611,7 +768,7 @@ describe('test `merge`', () => { (config.retryCount as jest.Mock).mockReturnValue(0); (config.retrySleep as jest.Mock).mockReturnValue(0); (config.mergeConflictAction as jest.Mock).mockReturnValue(null); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const scope = nock('https://api.github.com:443') .post(`/repos/${owner}/${repo}/merges`, { @@ -635,7 +792,7 @@ describe('test `merge`', () => { const retryCount = 3; (config.retryCount as jest.Mock).mockReturnValue(retryCount); (config.mergeConflictAction as jest.Mock).mockReturnValue(null); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const scopes = []; for (let i = 0; i <= retryCount; i++) { @@ -659,7 +816,7 @@ describe('test `merge`', () => { test('ignore merge conflicts', async () => { (config.retryCount as jest.Mock).mockReturnValue(0); (config.mergeConflictAction as jest.Mock).mockReturnValue('ignore'); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const scope = nock('https://api.github.com:443') .post(`/repos/${owner}/${repo}/merges`, { @@ -679,7 +836,7 @@ describe('test `merge`', () => { test('not ignoring merge conflicts', async () => { (config.retryCount as jest.Mock).mockReturnValue(0); (config.mergeConflictAction as jest.Mock).mockReturnValue(null); - const updater = new AutoUpdater(config, {}); + const updater = new AutoUpdater(config, emptyEvent); const scope = nock('https://api.github.com:443') .post(`/repos/${owner}/${repo}/merges`, { @@ -700,7 +857,7 @@ describe('test `merge`', () => { test('continue if merging throws an error', async () => { (config.mergeMsg as jest.Mock).mockReturnValue(null); - const updater = new AutoUpdater(config, dummyEvent); + const updater = new AutoUpdater(config, dummyPushEvent); const pullsMock = []; const expectedPulls = 5; diff --git a/test/config.ts b/test/config.ts new file mode 100644 index 00000000..388dd689 --- /dev/null +++ b/test/config.ts @@ -0,0 +1 @@ +import 'jest-ts-auto-mock'; diff --git a/test/router.test.ts b/test/router.test.ts index 942745fb..9d3ebd2a 100644 --- a/test/router.test.ts +++ b/test/router.test.ts @@ -1,6 +1,7 @@ import config from '../src/config-loader'; import { AutoUpdater } from '../src/autoupdater'; import { Router } from '../src/router'; +import { WebhookEvent } from '@octokit/webhooks-definitions/schema'; jest.mock('../src/config-loader'); jest.mock('../src/autoupdater'); @@ -10,12 +11,12 @@ beforeEach(() => { }); test('invalid event name', async () => { - const router = new Router(config, {}); + const router = new Router(config, {} as WebhookEvent); expect(AutoUpdater).toHaveBeenCalledTimes(1); const eventName = 'not-a-real-event'; await expect(router.route(eventName)).rejects.toThrowError( - `Unknown event type '${eventName}', only 'push' and 'pull_request' are supported.`, + `Unknown event type '${eventName}', only 'push', 'pull_request' and 'workflow_run' are supported.`, ); const autoUpdateInstance = (AutoUpdater as jest.Mock).mock.instances[0]; @@ -24,7 +25,7 @@ test('invalid event name', async () => { }); test('"push" events', async () => { - const router = new Router(config, {}); + const router = new Router(config, {} as WebhookEvent); expect(AutoUpdater).toHaveBeenCalledTimes(1); await router.route('push'); @@ -34,7 +35,7 @@ test('"push" events', async () => { }); test('"pull_request" events', async () => { - const router = new Router(config, {}); + const router = new Router(config, {} as WebhookEvent); expect(AutoUpdater).toHaveBeenCalledTimes(1); await router.route('pull_request'); @@ -42,3 +43,13 @@ test('"pull_request" events', async () => { const autoUpdateInstance = (AutoUpdater as jest.Mock).mock.instances[0]; expect(autoUpdateInstance.handlePullRequest).toHaveBeenCalledTimes(1); }); + +test('"workflow_run" events', async () => { + const router = new Router(config, {} as WebhookEvent); + expect(AutoUpdater).toHaveBeenCalledTimes(1); + + await router.route('workflow_run'); + + const autoUpdateInstance = (AutoUpdater as jest.Mock).mock.instances[0]; + expect(autoUpdateInstance.handleWorkflowRun).toHaveBeenCalledTimes(1); +}); diff --git a/tsconfig.json b/tsconfig.json index 9b9d4ecb..1dda733c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,13 @@ "baseUrl": ".", "paths": { "*": ["src/*", "bin/*"] - } + }, + "plugins": [ + { + "transform": "ts-auto-mock/transformer", + "cacheBetweenTests": false + }, + ] }, "include": ["src/**/*"], "exclude": ["**/*.test.ts"] diff --git a/yarn.lock b/yarn.lock index 9cd8dbe0..946a8f44 100644 --- a/yarn.lock +++ b/yarn.lock @@ -300,6 +300,15 @@ exec-sh "^0.3.2" minimist "^1.2.0" +"@dabh/diagnostics@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.2.tgz#290d08f7b381b8f94607dc8f471a12c675f9db31" + integrity sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q== + dependencies: + colorspace "1.1.x" + enabled "2.0.x" + kuler "^2.0.0" + "@eslint/eslintrc@^0.4.0": version "0.4.0" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.0.tgz#99cc0a0584d72f1df38b900fb062ba995f395547" @@ -589,6 +598,15 @@ deprecation "^2.0.0" once "^1.4.0" +"@octokit/request-error@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-2.0.5.tgz#72cc91edc870281ad583a42619256b380c600143" + integrity sha512-T/2wcCFyM7SkXzNoyVNWjyVlUwBvW3igM3Btr/eKYiPmucXTtkxt2RBsf6gn3LTzaLSLTQtNmvg+dGsOxQrjZg== + dependencies: + "@octokit/types" "^6.0.3" + deprecation "^2.0.0" + once "^1.4.0" + "@octokit/request@^5.3.0", "@octokit/request@^5.4.0": version "5.4.9" resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.4.9.tgz#0a46f11b82351b3416d3157261ad9b1558c43365" @@ -610,13 +628,33 @@ dependencies: "@types/node" ">= 8" -"@octokit/types@^6.13.0": +"@octokit/types@^6.0.3", "@octokit/types@^6.13.0": version "6.13.0" resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.13.0.tgz#779e5b7566c8dde68f2f6273861dd2f0409480d0" integrity sha512-W2J9qlVIU11jMwKHUp5/rbVUeErqelCsO5vW5PKNb7wAXQVUz87Rc+imjlEvpvbH8yUb+KHmv8NEjVZdsdpyxA== dependencies: "@octokit/openapi-types" "^6.0.0" +"@octokit/webhooks-definitions@3.67.3": + version "3.67.3" + resolved "https://registry.yarnpkg.com/@octokit/webhooks-definitions/-/webhooks-definitions-3.67.3.tgz#d2a905a90b04af8111982d0c13658a49fc4eecb9" + integrity sha512-do4Z1r2OVhuI0ihJhQ8Hg+yPWnBYEBNuFNCrvtPKoYT1w81jD7pBXgGe86lYuuNirkDHb0Nxt+zt4O5GiFJfgA== + +"@octokit/webhooks-methods@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@octokit/webhooks-methods/-/webhooks-methods-1.0.0.tgz#274799138725c89a3466e3af2026afe755f28c4b" + integrity sha512-pVceMQcj9SZ5p2RkemL0TuuPdGULNQj9F3Pq1cNM1xH+Kst1VNt0dj3PEGZRZV473njrDnYdi/OG4wWY9TLbbA== + +"@octokit/webhooks@^9.0.0": + version "9.0.0" + resolved "https://registry.yarnpkg.com/@octokit/webhooks/-/webhooks-9.0.0.tgz#ea38870e4fe761d2a5564ddf5bf9f888bf91e748" + integrity sha512-r8ZTnYAOZydrhRMnDonAVdeOl4IhK144UD+Vw8GUZCHurZxwO88VhoxV02omz2dm41h07EDo77i4H/A1DZ+0LQ== + dependencies: + "@octokit/request-error" "^2.0.2" + "@octokit/webhooks-definitions" "3.67.3" + "@octokit/webhooks-methods" "^1.0.0" + aggregate-error "^3.1.0" + "@sinonjs/commons@^1.7.0": version "1.8.1" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.1.tgz#e7df00f98a203324f6dc7cc606cad9d4a8ab2217" @@ -843,6 +881,14 @@ acorn@^7.1.1, acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +aggregate-error@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -981,6 +1027,11 @@ astral-regex@^2.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== +async@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" + integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -1231,6 +1282,11 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + cliui@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" @@ -1258,7 +1314,7 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" -color-convert@^1.9.0: +color-convert@^1.9.0, color-convert@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -1277,11 +1333,40 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@~1.1.4: +color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-string@^1.5.2: + version "1.5.5" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.5.tgz#65474a8f0e7439625f3d27a6a19d89fc45223014" + integrity sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@3.0.x: + version "3.0.0" + resolved "https://registry.yarnpkg.com/color/-/color-3.0.0.tgz#d920b4328d534a3ac8295d68f7bd4ba6c427be9a" + integrity sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w== + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" + +colors@^1.2.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +colorspace@1.1.x: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.2.tgz#e0128950d082b86a2168580796a0aa5d6c68d8c5" + integrity sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ== + dependencies: + color "3.0.x" + text-hex "1.0.x" + combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -1316,7 +1401,7 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-util-is@1.0.2: +core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= @@ -1509,6 +1594,11 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +enabled@2.0.x: + version "2.0.0" + resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" + integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== + end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -1900,6 +1990,11 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fast-safe-stringify@^2.0.4: + version "2.0.7" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" + integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== + fastq@^1.6.0: version "1.8.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481" @@ -1914,6 +2009,11 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +fecha@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce" + integrity sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q== + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -1966,6 +2066,11 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.0.tgz#a5d06b4a8b01e3a63771daa5cb7a1903e2e57067" integrity sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA== +fn.name@1.x.x: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" + integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -2248,6 +2353,11 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -2256,7 +2366,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2: +inherits@2, inherits@^2.0.3, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -2285,6 +2395,11 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -2302,7 +2417,7 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-core-module@^2.1.0: +is-core-module@^2.1.0, is-core-module@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== @@ -2465,7 +2580,7 @@ is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" -isarray@1.0.0, isarray@^1.0.0: +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= @@ -2851,6 +2966,11 @@ jest-snapshot@^26.6.2: pretty-format "^26.6.2" semver "^7.3.2" +jest-ts-auto-mock@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/jest-ts-auto-mock/-/jest-ts-auto-mock-2.0.0.tgz#0a2a5698ac55e0c3af3923f989b423c07ca0b370" + integrity sha512-ybY/VtTWJUGDPhOLdjAXsM10ShO8ri1EorXpfHYg4CH00b/k30c4RJJ0iM7GQ4FakHsIr7/zTRwETd3N9smxoA== + jest-util@^26.1.0, jest-util@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" @@ -3044,6 +3164,11 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +kuler@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" + integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== + leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -3095,6 +3220,11 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +lodash-es@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" + integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== + lodash.set@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" @@ -3110,6 +3240,17 @@ lodash@4.x, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +logform@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/logform/-/logform-2.2.0.tgz#40f036d19161fc76b68ab50fdc7fe495544492f2" + integrity sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg== + dependencies: + colors "^1.2.1" + fast-safe-stringify "^2.0.4" + fecha "^4.2.0" + ms "^2.1.1" + triple-beam "^1.3.0" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -3237,6 +3378,11 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -3407,6 +3553,13 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" +one-time@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45" + integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g== + dependencies: + fn.name "1.x.x" + onetime@^5.1.0: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" @@ -3635,6 +3788,11 @@ pretty-format@^26.0.0, pretty-format@^26.6.2: ansi-styles "^4.0.0" react-is "^17.0.1" +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + progress@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" @@ -3717,6 +3875,28 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" +readable-stream@^2.3.7: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.4.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -3824,6 +4004,14 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= +resolve@>=1.9.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + resolve@^1.10.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2: version "1.17.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" @@ -3866,12 +4054,12 @@ run-parallel@^1.1.9: resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q== -safe-buffer@^5.0.1, safe-buffer@^5.1.2: +safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -safe-buffer@~5.1.1: +safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== @@ -3976,6 +4164,13 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + sisteransi@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -4117,6 +4312,11 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" +stack-trace@0.0.x: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= + stack-utils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.2.tgz#5cf48b4557becb4638d0bc4f21d23f5d19586593" @@ -4170,6 +4370,20 @@ string.prototype.trimstart@^1.0.1: define-properties "^1.1.3" es-abstract "^1.17.5" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + strip-ansi@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" @@ -4256,6 +4470,11 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +text-hex@1.0.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" + integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -4332,6 +4551,20 @@ tr46@^2.0.2: dependencies: punycode "^2.1.1" +triple-beam@^1.2.0, triple-beam@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" + integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== + +ts-auto-mock@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/ts-auto-mock/-/ts-auto-mock-3.1.2.tgz#f1b4e73dd11a6296aa77d7779c341c29ab3b1fef" + integrity sha512-JoUQu7gtGXU0M8oDexUmBWcolzrGa2e69qm6DraRkkS09DsWfO7XE3lpCGjZ0kPQL+94Dv0unxSWpIY0qs5KnQ== + dependencies: + lodash-es "^4.17.21" + micromatch "^4.0.2" + winston "^3.3.3" + ts-jest@^26.5.4: version "26.5.4" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.5.4.tgz#207f4c114812a9c6d5746dd4d1cdf899eafc9686" @@ -4370,6 +4603,13 @@ tsutils@^3.17.1: dependencies: tslib "^1.8.1" +ttypescript@^1.5.12: + version "1.5.12" + resolved "https://registry.yarnpkg.com/ttypescript/-/ttypescript-1.5.12.tgz#27a8356d7d4e719d0075a8feb4df14b52384f044" + integrity sha512-1ojRyJvpnmgN9kIHmUnQPlEV1gq+VVsxVYjk/NfvMlHSmYxjK5hEvOOU2MQASrbekTUiUM7pR/nXeCc8bzvMOQ== + dependencies: + resolve ">=1.9.0" + tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -4478,6 +4718,11 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" @@ -4590,6 +4835,29 @@ which@^2.0.1, which@^2.0.2: dependencies: isexe "^2.0.0" +winston-transport@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59" + integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw== + dependencies: + readable-stream "^2.3.7" + triple-beam "^1.2.0" + +winston@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.3.3.tgz#ae6172042cafb29786afa3d09c8ff833ab7c9170" + integrity sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw== + dependencies: + "@dabh/diagnostics" "^2.0.2" + async "^3.1.0" + is-stream "^2.0.0" + logform "^2.2.0" + one-time "^1.0.0" + readable-stream "^3.4.0" + stack-trace "0.0.x" + triple-beam "^1.3.0" + winston-transport "^4.4.0" + word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"